龙空技术网

读《Java核心技术》---泛型数组列表(数组列表ArrayList)

David8579 201

前言:

现时看官们对“java泛型与数组”大致比较关注,你们都想要分析一些“java泛型与数组”的相关知识。那么小编在网上网罗了一些关于“java泛型与数组””的相关资讯,希望朋友们能喜欢,咱们一起来学习一下吧!

在 Java 中,允许在运行时确定数组的大小

int actualSize = ...Employee[] staff = new Employee[actualSize];

这段代码并没有完全解决运行时动态更改数组的问题。一旦确定了数组的大小, 改变它就不太容易了。

解决这个问题最简单的方法是使用 Java 中另外一个被称为 ArrayList 的类

// ArrayList 是一个采用类型参数( type parameter ) 的泛型类( generic class)ArrayList<Employee> staff = new ArrayList<Employee>();ArrayList<Employee> staff = new ArrayList<>();staff.add(new Employee("Harry Hacker"));staff.add(new Employee("Tony Tester"));

数组列表管理着对象引用的一个内部数组。如果调用 add 且内部数组已经满了,数组列表就将自动地创建 一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中。 如果已经清楚或能够估计出数组可能存储的元素数量, 就可以在填充数组之前调用 ensureCapacity方法:

staff.ensureCapacity(100);

// 可以把初始容量传递给 ArrayList 构造器//完成初始化构造之后,数组列表根本就不含有任何元素 和数组的区别ArrayList<Employee> staff = new ArrayList<>(100);staff.size();//返回数组实际元素数目

访问数组列表元素

数组列表自动扩展容量的便利增加了访问元素语法的复杂程度,使用 get 和 set 方法实现访问或改变数组元素的操作,而不使用人们喜爱的 [ ]语法格式

staff.set(i,harry); ==> a[i] = harrr;staff.get(i); ==> a[i];

只有 i 小于或等于数组列表的大小时, 才能够调用 list.set(i, x)就是说用set只能是list内有元素,如果没有元素会出错。set只能替换数组中已经存在的元素内容。

小技巧:利用Arraylist来创建数组列表,toArray()方法来装换成数组,就可以灵活扩展数组,又可以方便访问数组元素:

ArrayList<X> list = new ArrayList<>();while(){	x = ..;	list.add(x);}X[] arr = new X[list.size()];list.toArray(arr);

除了在数组列表的尾部追加元素之外,还可以在数组列表的中间插入元素,使用带索引参数的 add 方法。

int n = staff.size() /2;staff.add(n,e);

使用“ foreach” 循环遍历数组列表

for(Employee e : staff){	do something with e;}// ArrayListTest.javapublic class ArrayListTest{	public static void main(String[] args){		ArrayList<Employee> staff = new ArrayList<>();		staff.add(new Employee("Carl Cracker",75000,1987,12,15));		staff.add(new Employee("Harry Hacker",50000,1989,10,1));		staff.add(new Employee("tony Tester",55000,1990,3,15));		for(Employee e: staff){			e.raiseSalary(5);		}		for(Employee e: staff){			System.out.println("name=" + e.getName()+ ",salary="+e.getSalary()+",hireDay="+e.getHireDay());		}	}}

类型化与原始数组列表的兼容性(比如:ArrayList<String>与ArrayList的兼容性)

public class EmployeeDB{public void update(ArrayList list) { . . . }public ArrayList find(String query) { . . . }}

可以将一个类型化的数组列表传递给 update 方法, 而并不需要进行任何类型转换。

ArrayList<Employee〉staff = . . .;employeeDB.update(staff);

也可以将 staff 对象传递给 update 方法。

相反地,将一个原始 ArrayList 赋给一个类型化 ArrayList 会得到一个警告。

ArrayList result = employeeDB.find(query); // yields warning

对象包装器与自动装箱

所有的基本类型都有一个与之对应的类。 例如,Integer 类对应基本类型 int。通常, 这些类称为包装器 ( wrapper )

对象包装器类是不可变的,即一旦构造了包装器,就不允许更改包装在其中的值。同时, 对象包装器类还是 final , 因此不能定义它们的子类。

假设想定义一个整型数组列表。而尖括号中的类型参数不允许是基本类型,也就是说, 不允许写成 ArrayList<int>。这里就用到了 Integer 对象包装器类。我们可以声明一个 Integer 对象的数组列表。

ArrayList<Integer> list = new ArrayList<>();

//自动装箱list.add(3) ---> list.add(Integer.valueOf(3))///自动拆箱int n = list.get(i); --->int n = list.get(i).intValue();

可以将自增操作符应用于一个包装器 引用:

 Integer n = 3; n++; 

编译器将自动地插人一条对象拆箱的指令, 然后进行自增计算, 最后再将结果装箱。

下面的比较通常不会成立:

 Integer a = 1000; Integer b = 1000; if (a == b) . . .

然而,Java 实现却有可能让它成立。如果将经常出现的值包装到同一个对象中, 这种比较就有可能成立。这种不确定的结果并不是我们所希望的。解决这个问题的办法是在 两个包装器对象比较时调用 equals 方法。

自动装箱规范要求 boolean、byte、char 127, 介于128 ~ 127 之间的 short 和int 被包装到固定的对象中。例如,如果在前面的例子中将 a 和 b 初始化为 100,对它们进行比较的结果一定成立。

参数数量可变的方法

Java现在的版本 提供了可以用可变的参数数量调用的方法。

public static double max(double... values){ //注意这个...	double largest = Double.NEGTIVE_INFINITY;	for(double v : values){		if(v>largest){			largest = v;		}	}	return largest;}double m = max(3.1,505,-5);

事实上这个可变参数实际上就是一个数组类型,只不过这种方式,编译器会自动识别并且帮你添加构造数组的代码,如果有需要还可以自动装箱,比如把基本类型装箱为引用类型。

枚举类

public enum Size{SMALL,MEDIUM,LARGE,EXTRA_LARGE};

比较时直接用==不要用equals

在枚举类中添加构造器、方法、域。构造器只是在构造枚举常量的时候被调用

public enum Size{	SMALL("S"),MEDIUM("M"),LARGE("L"),EXTRA_LARGE("XL");	private String abbreviation;	private Size(String abbreviation){		this.abbreviation = abbreviation;	}	public String getAbbreviation(){		return abbreviation;	}}

所有的枚举类型都是 Enum 类的子类。它们继承了这个类的许多方法。其中最有用的一个是 toString, 这个方法能够返回枚举常量名:

Size.SMALL.toString(); --> "SMALL"Size s = Enum.valueOf(Size.class,"SMALL");

静态的values方法,它将返回一个包含全部枚举值的数组例如,如下调用

Size[] values = Size.values();

ordinal方法返回enum声明中枚举常量的位置,位置从0开始计数。例如:

Size.MEDIUM. ordinal() //返回 1。

标签: #java泛型与数组