Java
大约 4 分钟
Java
目录
容器类
泛型数组列表
Java普通数组
C需要一开始就确定数组的大小
java 运行时确定数组大小
// 在Java中,它允许在运行时确定数组的大小
// 缺点:一旦确定了数组的大小,改变它就不太容易了
int actualSize = ...;
Employee[] staff = new Employee[actualSize];
ArrayList
API: java.util.ArrayList<E>1.2
API: java.util.ArrayList<T>1.2
ArrayList类在添加或删除元素时,具有自动调节数组容量的功能
ArrayList是一个采用 类型参数(type parameter) 的 泛型类(generic class)
创建
ArrayList<Employee> staff = new ArrayList<Employee>(); // 为了指定数组列表保存的元素对象类型,需要用一对尖括号将类名括起来加在后面 ArrayList<Employee> staff = new ArrayList<>(); // Java SE 7中,可以省去右边的类型参数 // 这被称为“菱形”语法,<>就像是一个菱形。可结合new操作符使用菱形语法
性能优化
估算元素数量
// 估算元素数量 // 如果已经清楚或能够估计出数组可能存储的元素数量,就可以在填充数组之前调用ensureCapacity方法 staff.ensureCapacity(100); // 还可以把初始容量传递给ArrayList构造器 ArrayList<Employee> staff = new ArrayList<>(100); // 补充,下面两种写法不同 new ArrayList<>(100); // capacity is 100 new Employee[100]; // size is 100 staff.size(); // size方法将返回数组列表中包含的实际元素数目,等价于数组a的a.length
多余空间的垃圾回收
// 垃圾回收 // 一旦能够确认数组列表的大小不再发生变化,就可以调用trimToSize方法。 // 这个方法将存储区域的大小调整为当前元素数量所需要的存储空间数目。垃圾回收器将回收多余的存储空间。
add方法/remove方法
// 自动调节容量: // 如果调用add且内部数组已经满了,数组列表就将自动地创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中 staff.add(new Employee("Harry Hacker", ...)); staff.add(new Employee("Tony Tester", ...)); // 除了在数组列表的尾部追加元素之外,还可以在数组列表的中间插入元素,使用带索引参数的add方法(位于n之后的所有元素都要向后移动一个位置) // remove同理 staff.add(n, e); Employee e = staff.remove(n);
set方法/get方法
Employee e = staff.get(i) // add方法为数组添加新元素,而不要使用set方法,它只能替换数组中已经存在的元素内容 staff.set(i, harry);
旧版补充
- Java SE 5.0以前的版本
- 没有提供泛型类 而是有一个ArrayList类,其中保存类型为Object的元素,它是“自适应大小”的集合。 如果一定要使用老版本的Java,则需要将所有的后缀<...>删掉 在Java SE 5.0以后的版本中,没有后缀<...>仍然可以使用ArrayList,它将被认为是一个删去了类型参数的“原始”类型
- Java老版本中
- 程序员使用Vector类实现动态数组 不过,ArrayList类更好
与C++不同
普通数组的区别
C
// C需要一开始就确定数组的大小 int[] list_i = int[100]
Java
// 在Java中,它允许在运行时确定数组的大小 // 缺点:一旦确定了数组的大小,改变它就不太容易了 int actualSize = ...; Employee[] staff = new Employee[actualSize];
泛型变成数组 - 创建
Java
ArrayList:泛型变长数组
ArrayList<Employee> staff = new ArrayList<Employee>(); ArrayList<Employee> staff = new ArrayList<>(); // Java SE 7,“菱形”语法
C++
Array:泛型定长数组
#include <array> std::array <typeName, N_ELEM> arr;
Vector等:泛型变长数组
#include <vector> std::vector<doubel> vd(n);
泛型变长数组 - 拷贝
- C++
- 向量拷贝是值拷贝。如果a和b是两个向量,赋值操作 a=b 将会构造一个与b长度相同的新向量a,并将所有的元素由b拷贝到a
- Java
- a=b 这条赋值语句的操作结果是让a和b引用同一个数组列表
泛型变长数组 - 访问
ArrayList类似于C++的vector模板。ArrayList与vector都是泛型类型。 但是C++的vector模板为了便于访问元素重载了[]运算符。 由于Java没有运算符重载,所以必须调用显式的方法,使用get和set方法实现访问或改变数组元素的操作,而不使用人们喜爱的[]语法格式
Java
staff.set(i, harry); Employee e = staff.get(i)
C++
a[i] = harry; Employee e = a[i];
类型化与原始数组列表的兼容性
@TODO: 没懂,查书