泛型数组列表ArrayList

来源:互联网 发布:mac被灭雷欧为什么不救 编辑:程序博客网 时间:2024/06/06 08:48

【0】README

0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理清 java 中的 数组列表 ArrayList;


【2】数组列表 ArrayList

2.1)ArrayList: ArrayList 具有自动调节数组容量的功能, 而不需要为此编写任何代码;
2.2)ArrayList 是一个采用类型参数的泛型类:

ArrayList<Employee> staff =new ArrayList<Employee>() = new ArrayList<>() (Employee可以省略);

Annotation)实现动态数组, ArrayList 比 Vector 更加有效;
2.3)数组列表管理着 对象引用的一个内部数组:最终,数组的全部空间有可能被用尽, 这就显现出数组列表的操作魅力:如果 调用add 且 内部数组已经满了,数组列表就将自动地创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中;
2.4)ensureCapacity方法——如果已经清楚或能够估计出数组可能存储的元素数量, 就可以在填充数组之前调用 ensureCapacity方法: staff.ensureCapacity(100); 这个方法将分配一个包含100个对象的内部数组, 然后调用100 次add, 而不用重新分配空间了;还可以把初始容量传给 ArrayList 构造器: ArrayList staff= new ArrayList<>(100);
Alert) 数组列表的容量和数组大小是有区别的:如果为数组分配100个元素, 数组就有100个空位置可以使用; 而容量为100的数组列表只是拥有保存100个元素的潜力(实际上, 重新分配空间的话, 将会超过100);
2.5)size方法:它返回数组列表的实际元素数目, 等价于数组的 length 方法;
2.6)trimToSize方法:一旦能够确认数组列表的大小不在发生变化,就可调用 trimToSize 方法, 这个方法将存储区域的大小调整为当前元素数量所需要的存储空间数组。垃圾回收器将回收多余的存储空间;
Attention) 一旦整理了数组列表的大小,添加新元素就需要花时间再次移动存储块, 所以应该在确认不会添加任何元素时, 再调用 trimToSize 方法;


【3】访问数组列表元素

3.1)扩展数组的一个技巧:既可以灵活地扩展数组, 又可以方便地访问数组元素

  • 1) 先创建一个数组, 并添加所有元素:ArrayList list = new ArrayList<>();
  • 2) 使用 toArray 方法将数组元素拷贝到一个数组中:

    X[] a = new X[list.size()];list.toArray(a);

3.2)在数组中间插入元素 + 删除元素

int n = staff.size/2;staff.add(n, e);//位于n 之后的所有元素都要向后移动一个位置, 数组大小减1;Employee e = staff.remove(n);//位于n 之后的所有元素都要向前移动一个位置, 数组大小加1;

3.3)对数组进行插入和删除的效率比较低
如果数组存储的元素比较多的话, 又经常需要在中间位置插入、删除元素, 就应该考虑使用链表了
Attention)将 Employee[] 数组替换成 ArrayList , 请注意一下变化:

  • A1)不必指出数组的大小;
  • A2)使用 add 将任意多的元素添加到数组中;
  • A3)使用 size() 替代 length 计算元素数目;
  • A4)使用 a.get(i) 替代 a[i] 访问元素;

【4】类型化与原始数组列表的兼容性

4.1)假设有下面这些遗留下来的类:

public class EmployeeDB{    public void update(ArrayList list) {...}    public ArrayList find(String query) {...}}ArrayList<Employee> staff = ...;employeeDB.update(staff);

Warning)

  • W1)这样调用不太安全,因为添加到 数组列表中的元素可能不是 Employee 类型;
  • W2)相反, 将一个原始ArrayList 赋给一个类型化ArrayList ,会得到一个警告;
    ArrayList result = employeeDB.find(query);
  • W3)使用类型转换,还不能避免出现警告:

    ArrayList<Employee> result = ( ArrayList<Employee> )employeeDB.find(query);而且,还会得到 另外一个警告消息, 被告之 类型转换有误;

4.2)鉴于兼容性的考虑: 编译器在对类型转换进行检查之后, 如果没有发现违反规则的现象, 就将所有的类型化数组列表转换成原始 ArrayList对象。在程序运行时, 所有的数组列表都一样, 即没有虚拟机中的类型参数;因此, 类型转换(ArrayList) 和 (ArrayList) 将进行相同的运行时检查;

  • 1)在这种情形下,不必做什么:只要研究一下编译器的警告性提示,并确保这些警告不会造成太严重的后果就行了;
  • 2)一旦确保不会造成严重的后果: 就可以使用 @SuppressWarnings(“unchecked”) 标注来标记这个变量能够接受类型转换, 如下所示:

    @SuppressWarnings("unchecked")ArrayList<Employee> result = (ArrayList<Employee>) employeeDB.find(query);
0 0