<CoreJava> 5.3 泛型数组列表

1、为了解决运行时动态更改数组的问题,使用ArrayList类;它与数组很相似,但在增加或删除元素时具有自动调节数组容量的功能。

2、ArrayList是采用类型参数的泛型类。用法:ArrayList<Class Name>
ArrayList<Employee> staff = new ArrayList<Employee>();

3、使用add方法添加元素:
staff.add(new Employee("Harry", ...));
staff.add(new Employee("Tome", ....));
如果调用add且内部数组已满时,数组列表就会自动创建一个更大容量的数组,并将小数组中的对象全部拷贝到大数组中。

4、预先分配容量大小:如果可以准确的预计数组可能存储的元素数量,可以在填充数组前调用ensureCapacity方法:
staff.ensureCapacity(100);    //分配一个包含100个对象的内部数组。
这里如过调用100add,是不会重新分配空间的。

5、把初始容量传递给构造器:
ArrayList<Employee> staff = new ArrayList<Employee>(100);
警告:
分配数组列表:new ArrayList<Employee>(100);与新数组分配空间:new Employee[100];不同。
数组列表的容量与数组的大小不同:数组分配100个存储空间就表明这个数组有100个空位置可用(即用或不用那100个空间都会摆在那,不多不少);而容量为100的数组列表仅表明它拥有保存100个元素的潜力(所谓潜力就是可能超越100,可能不足100.这要实际运行中动态决定是否会重新分配容量),但是可以确定的是数组列表在完成初始化构造时不含任何元素。

6、size方法将返回数组列表实际元素个数:staff.size();返回staff数组列表的当前元素个数,等价于a.length;
当确定数组列表不再增删元素时可以使用trimToSize方法。这个方法将存储空间调整为当前元素所用空间,多于的交给垃圾回收器回收。注意:一定是确定数组列表大小不变后才使用该方法,因为使用该方法后再添加新元素就要花时间再次移动存储块,时间开销较大。

5.3.1 访问数组列表元素
1、ArrayList类不是Java的一部分。而是由某些人编写且被放到标准库中的一个实用类。

2、使用get和set方法访问和改变数组元素,不能采用数组的[]语法格式。
例如:改变第i个元素:staff.set(i, harry);
等价于a[i] = harry;
警告:使用add方法添加新的元素,set方法只能改变已有元素的内容。

使用get访问数组列表的元素:Employee e = staff.get(i);
等价于:Employee e = a[i];

3、介绍个技巧,即可灵活的扩展数组,又可以方便的访问数组元素。
1)创建一个数组列表,并添加所有元素:
ArrayList<X> list = ArrayList<X>();
while (...) {
    x = ...;
    list.add(x);
}

2)使用toArray方法将数组列表元素拷贝到一个数组中:
x[] a = new x[list.size()];
list.toArray(a);

3)除了在尾部追加元素之外,使用带索引参数的add方法插入新元素:
int n = staff.size() / 2;
staff.add(n, e);
插入新元素后位于n后的所有元素自动向后移动,若超出容量将会重新分配存储空间。

4)删除元素:Emplouyee e = staff.remove(n);

5)使用“for each”循环对数组列表遍历:
for (Employee e : staff)
    //do something with e;

4、源代码:例5-4,将Employee[]数组替换成ArrayList<Employee>。
注意变化:
不必指出数组的大小;
使用add想数组列表添加任意多的元素;
使用size代替length计算元素个数;
使用get[i]代替a[i]访问元素。

ArrayListTest.java:
  1. package com.vicent.corejava.arraylisttest;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. public class ArrayListTest {  
  6.     public static void main(String[] args) {  
  7.         ArrayList<Employee> staff = new ArrayList<Employee>();  
  8.           
  9.         staff.add(new Employee("Carl"750019871215));  
  10.         staff.add(new Employee("Harry"50001989101));  
  11.         staff.add(new Employee("Tony"40001990315));  
  12.           
  13.         for (Employee e : staff)  
  14.             e.raiseSalary(5);  
  15.           
  16.         for (Employee e : staff)  
  17.             System.out.println("name: " + e.getName()  
  18.                     + ", salary: " + e.getSalary()  
  19.                     + ", hireDay: " + e.getHireDay());  
  20.               
  21.     }  
  22.   
  23. }  

Employee.java:
  1. package com.vicent.corejava.arraylisttest;  
  2.   
  3. import java.util.Date;  
  4. import java.util.GregorianCalendar;  
  5.   
  6. public class Employee {  
  7.   
  8.     private String name;  
  9.     private double salary;  
  10.     private Date hireDay;  
  11.     private double raise;  
  12.   
  13.     public Employee(String aName, double aSalary, int year, int month, int day) {  
  14.         name = aName;  
  15.         salary = aSalary;  
  16.         GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);  
  17.         hireDay = calendar.getTime();  
  18.     }  
  19.       
  20.     public String getName() {  
  21.         return name;  
  22.     }  
  23.       
  24.     public double getSalary() {  
  25.         return salary;  
  26.     }  
  27.       
  28.     public Date getHireDay() {  
  29.         return hireDay;  
  30.     }  
  31.       
  32.     public void raiseSalary(double byPercent) {  
  33.         raise = salary * byPercent / 100;  
  34.         salary += raise;  
  35.     }  
  36.   
  37. }  

运行结果:
name: Carl, salary: 7875.0, hireDay: Tue Dec 15 00:00:00 CST 1987
name: Harry, salary: 5250.0, hireDay: Sun Oct 01 00:00:00 CST 1989
name: Tony, salary: 4200.0, hireDay: Thu Mar 15 00:00:00 CST 1990
posted @ 2013-02-28 18:55  vincent_hv  阅读(210)  评论(0编辑  收藏  举报