- List接口
List判断两个对象相等的标准是只要通过equals方法比较返回true就行。所以在下面代码,虽然list中没有AA对象,但在程序试图删除一个AA对象时,List会调用该AA对象的equals方法依次与集合元素进行比较,如果比较出某个元素返回true, List就会认为该元素就是AA对象,于是将该元素删除。所以可以看到每次从list中删除AA对象,总是删除list集合中的第一个元素。
import java.util.ArrayList; import java.util.List; class AA { public boolean equals(Object o) { return true; } } public class ListDemo { public static void main(String[] args) { // TODO Auto-generated method stub List list = new ArrayList(); list.add(new String("Java")); list.add(new String("C++")); list.add(new String("C#")); System.out.println(list); list.remove(new AA()); System.out.println(list); list.remove(new AA()); System.out.println(list); } }
输出结果:
[Java, C++, C#]
[C++, C#]
[C#]
- ListIterator接口
List不仅有iterator()方法返回一个Iterator对象,它还额外提供了一个ListIterator()方法返回一个ListIterator对象,ListIterator对象增加了向前迭代的功能,还有add方法可以向List中添加元素。eg.
import java.util.ArrayList; import java.util.List; import java.util.ListIterator; public class ListIteratorDemo { public static void main(String[] args) { // TODO Auto-generated method stub String[] strArray = {"Java", "C++", "C#"}; List strList = new ArrayList(); for (int i = 0; i < strArray.length; i++ ) { strList.add(strArray[i]); } ListIterator lit = strList.listIterator(); while(lit.hasNext()) { System.out.println(lit.next()); lit.add("----------"); } System.out.println("==================="); while(lit.hasPrevious()) { System.out.println(lit.previous()); } } }
输出结果:
Java
C++
C#
===================
----------
C#
----------
C++
----------
Java
- ArrayList,LinkedList和Vector
ArrayList和Vector都是基于数组实现的List类,使用initialCapacity参数来设置数组长度,如果添加元素超出了数组长度时,initialCapacity会自动增加。
ArrayList是线程不安全的,Vector是线程安全的,所以Vector的性能要低,不过即使要保证List集合线程安全,也不推荐使用Vector。
ArrayList和LinkedList的性能差异可以忽略,只需要知道LinkedList不仅提供了List的功能,还提供了双端队列和栈的功能。
- Arrays.asList
Arrays.asList(Object... a)把一个数组转换成一个List集合,但这个集合既不是ArrayList的实现类,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例。Arrays.ArrayList是一个固定长度的list,程序只能遍历访问该集合中的元素,不可增加/删除该集合里的元素。
- 使用List的建议
如果需要遍历List集合元素,对于ArrayList/Vector集合,应该使用随机访问方法get来遍历,如果遍历LinkedList,则应该采用iterator来遍历
如果需要经常执行插入删除操作来改变List的大小,应该使用LinkedList,而不是ArrayList。使用ArrayList/Vector集合需要经常重新分配内部数组的大小,其时间开销通常是LinkedList的几十倍。
如果有多个线程需要同时访问List集合中的元素,可以考虑使用Collections将集合包装成线程安全的集合。