List集合代表着这个有序的、可重复的集合,集合当中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List集合默认按照元素的添加顺序设置索引。
List作为Collection的子接口,可以使用Collection里面的所有方法。而且由于List是一个有序集合所以添加了一些根据索引操作的方法。
所有的List实现类都可以调用这些方法来操作集合元素。与Set集合相比较,List添加了根据索引来插入、替换和删除集合元素的方法。除此之外,Java8
还为List接口添加了如下两个默认方法。
import java.util.ArrayList;
import java.util.TreeSet;
public class App {
public static void main(String[] args) throws Exception {
ArrayList javas = new ArrayList();
javas.add("开始学习");
javas.add("怀疑人生");
javas.add("萌生退意");
System.out.println(javas);
javas.add(1,new String("直接放弃"));
for (int i= 0;i<javas.size();i++){
System.out.println(javas.get(i));
}
javas.remove(2);
System.out.println(javas);
System.out.println(javas.indexOf("直接放弃"));
javas.set(1, "怀疑人生");
System.out.println(javas);
System.out.println(javas.subList(1, 2));
}
}
上述程序输出结果如下:
[开始学习, 怀疑人生, 萌生退意]
开始学习
直接放弃
怀疑人生
萌生退意
[开始学习, 直接放弃, 萌生退意]
1
[开始学习, 怀疑人生, 萌生退意]
[怀疑人生]
从上面的程序可以看出list的一些基本用法,同时可以看出list判断两个对象的标准:只要通过equlas方法就返回true就认为它们是相等。
与set只提供一个iterator()方法不同,List还额外提供了一个listIteration()方法,该方法返回一个ListIterator对象,ListIterator接口继承了Iteration接口,提供了专门操作List的方法。ListIterator接口在Iterator接口基础之上增加了如下的方法。
拿ListIterator与普通的Iterator进行对比,不难发现ListIterator增加了向前迭代的功能(Iterator只能向后迭代),而且ListIterator和可以通过add()方法向List集合中添加元素。
ArrayList和Vector作为List类的两个典型实现,完全支持前面介绍的List接口的全部功能。
ArrayList和Vector类都是基于数组实现的List类,所以ArrayList和Vector类封装了一个动态的、允许再分配的Object[]数组。ArrayList或者Vector对象使用initialCapacity参数来设置该数组的长度,当向ArrayList或者Vector中添加元素超过该数组的长度的时候,他的initialCapacity会自动增加。
对于通常的编程场景,程序员无需关心ArrayList和Vector的initialCapacity。但如果向ArrayList或者Vector集合中添加大量元素的时候,可使用ensureCapacity(int minCapacity)方法一次性地增加initialCapacity。这可以减少重分配的次数,从而提高性能。
如果开始知道ArrayList或者Vector集合需要保存多少个元素,则可以在创建它们时就指定initial大小,如果创建空的ArrayList或者Vector集合时不指定initialCapacity参数,则Object[]数组的长度默认为10.
除此之外,ArrayList和Vector还提供了如下两个方法来重新分配Object[]数组。
ArrayList或Vector的显著区别是:ArrayList是线程不安全的,而Vector是线程安全的。所以Vector的性能要比ArrayList要低,但是实际上,即使是在线程当中,也不建议使用Vector。可以通过Collections工具类,他可以将一个ArrayList变成线程安全。
Vector提供了一个Stack子类,其基本上模仿了栈这种数据结构。但是Stack与Vector一样都是一个非常古老的子类,它们都是线程安全,性能较差的。因此应该尽量少用Stack类,如果必须使用Stack类的功能,可以考虑使用ArrayDeque代替。
在学习数组的时候,介绍了一个工具类:Arrays,该工具类里了asList(Object… a)方法,该方法可以把一个数组或指定个数的对象转换为一个List集合,这个List集合既不是ArrayList实现类的实例,也不是Vector实现类的实例,也不是Vector实现类的实例,而是Arrays的内部类ArrayList的实例。
Arrays.ArrayList是一个固定长度的List集合,程序只能遍历访问该集合里的元素,不可增加、删除该集合里的元素。如下程序所示。
import java.util.Arrays;
import java.util.List;
public class App {
public static void main(String[] args) throws Exception {
List fixedList = Arrays.asList("开始学习","学习结束");
System.out.println(fixedList.getClass());
fixedList.forEach(System.out::println);
// fixedList.add("放弃学习");
// fixedList.remove("开始学习");
}
}
输出结果如下:
class java.util.Arrays$ArrayList
开始学习
学习结束
任何试图增加或者删除的操作都会引起异常。注释掉代码在运行的时候回引发异常。