List(序列),序列中的元素是有序的,且允许重复。
首先,List是接口不能实例化,只能实例化List的实现类。
在List集合中,我们常用到ArrayList和LinkedList,Vector这三种List的实现类型。
1.ArrayList
ArrayList: 有顺序,可重复,可以添加 null元素。ArrayList底层通过数组实现,随着元素的增加而动态扩容。
例如:
public static void main(String[] args) {
List list = new ArrayList();
list.add("grape");
list.add("banana");
list.add("apple");
list.add("orange");
list.add(null);
list.add("watermelon");
list.add("apple");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
运行结果
grape
banana
apple
orange
null
watermelon
apple
由于List是由顺序的,所以每个元素都有对应的索引(下标),因此可以使用for循环遍历List里的元素。 也可以使用foreach迭代器原理遍历,如下:
public static void main(String[] args) {
List list = new ArrayList();
list.add("grape");
list.add("banana");
list.add("apple");
list.add("orange");
list.add(null);
list.add("watermelon");
list.add("apple");
for(Object obj : list){
System.out.println(obj);
}
}
运行结果
grape
banana
apple
orange
null
watermelon
apple
2.LinkedList
ArrayList: 有顺序,可重复,可以添加 null元素。LinkedList底层通过链表来实现,随着元素的增加不断向链表的后端增加节点。
例如:
public static void main(String[] args) {
List list = new LinkedList();
list.add("grape");
list.add("banana");
list.add("apple");
list.add("orange");
list.add(null);
list.add("watermelon");
list.add("apple");
for(Object obj : list){
System.out.println(obj);
}
((LinkedList) list).addFirst("pear");
((LinkedList) list).addLast("strawberry");
System.out.println("---------添加头尾节点后----------");
for(Object obj : list){
System.out.println(obj);
}
}
运行结果:
grape
banana
apple
orange
null
watermelon
apple
---------添加头尾节点后----------
pear
grape
banana
apple
orange
null
watermelon
apple
strawberry
通过以上代码,我们发现LinkedList有类似addFirst和addLast这样能体现链表特征的方法,也间接证明了LinkedList底层是通过链表实现的。
比较ArrayList与LinkedList的区别,恰恰就是比较顺序存储结构与离散存储结构的优缺点,总结如下: 1).ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2).对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 3).对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
3.Vector
Vector用法与ArrayList完全相同,两者底层的数据存储都使用的Object数组实现,因为是数组实现,所以具有查找快,插入删除慢。
Vector与ArrayList最大的不同是,vector是线程安全的,在vector的大多数方法都使用synchronized关键字修饰,ArrayList是线程不安全的(可以通过Collections.synchronizedList()实现线程安全)。
4.并发包下的List
虽然Vector是线程安全的,但是Vector是从JDK1.0中给出的类,过于陈旧,所以效率低。Vector分配内存的时候需要连续的存储空间,如果数据太多,容易分配内存失败;推荐使用并发包下的CopyOnWriteArrayList替换Vector.
CopyOnWriteArrayList list = new CopyOnWriteArrayList();
//有顺序,可重复,可以添加空元素。
list.add("grape");
list.add("banana");
list.add("apple");
list.add("orange");
list.add(null);
list.add("watermelon");
list.add("apple");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
小结:
1.List是序列,特点是有顺序,可重复,可以添加null元素。List是接口不能实例化。
2.常用的List实现类是ArrayList/LinkedList/Vector.
3.ArrayList底层是对象数组,顺序存储结构。
4.LinkedList底层是链表,离散存储结构。
5.Vector与ArrayList用法一样,Vector是线程安全的,而ArrayList是线程不安全的。