在List集合中,有三个重要的常用子类:Vector,ArrayList,LinkedList。
1. Vector:内部是数组数据结构,线程安全。增删,查询都很慢。
2. ArrayList:内部是数组数据结构,线程不安全,替代Vector,查询速度快,增删速度慢。如果需要使用多线程,我们可以给ArrayList加锁,或者使用其他的方法,Vector已经不再使用了。
3. LinkedList:内部是链表数据结构,线程不安全,增删速度快,查询速度慢。
* 如果要猜集合是否线程安全,只要不是Vector,都猜线程不安全,概率大

Vector
Vector在JDK1.0版本就已经出现了,在1.2版本后出现了Collection集合,开始有集合框架,Vector改进为可以实现List接口,纳入集合框架。构造函数Vector()构造一个空向量,内部数组默认初始化大小为10。Vector中的方法都是从Collection和List继承来的。但Vector有一些特有的方法
void addElement(E obj)
E firstElement()
E lastElement()
boolean removeElement(Object obj)
void setElementAt(E obj, int index)等…这些方法和对应不带Element的方法功能相同。

Vector特有的取出方法:enumeration elements():返回此向量的组件的枚举
Enumeration是一个接口,与Iterator类似。它有两个方法:
boolean hasMoreElements():是否还包含元素
E nextElement():返回此枚举的下一个元素
接口Enumeration的功能与Iterator接口功能是重复的。此外,Iterator 接口添加了一个可选的移除操作(void remove()),并使用较短的方法名。新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。

Vector v = new Vector();

v.addElement("abc1");
v.addElement("abc2");
v.addElement("abc3");
v.addElement("abc4");

Enumeration en = v.elements();
while(en.hasMoreElements()){
    System.out.println(en.nextElement());
}

输出结果:
abc1
abc2
abc3
abc4

LinkedList

LinkedList是链接列表数据存储格式的,简称链表格式。链表内存示意图如下:

List取子集 java java list子类_LinkedList


链表中每个元素都有自己的地址,第一个元素记住第二个元素的地址,第二个元素记住第三个元素的地址,以此类推…如果想要查询其中的某一个元素,要从第一个元素挨个做判断,因为这些元素不是连续的,所以很慢。如果要增加一个元素,让这个元素把地址给前一个元素,再记住后一个元素的位置即可;如果要删除一个元素,只要它前一个元素记住它后一个元素的地址即可,所以增删的速度很快。

LinkedList也有角标,因为它是List集合的子类,List接口最大的特点就是可以操作角标。

一般方法:

void addFirst(E e):将指定元素插入此列表的开头
void addLast(E e):将指定元素添加到此列表的结尾
Object getFirst():返回此列表的第一个元素
Object getLast():返回此列表的最后一个元素
Object removeFirst():移除并返回此列表的第一个元素,remove会改变集合的长度,所以第二个元素就变成了第一个元素

LinkedList link = new LinkedList();

link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
link.addFirst("abc4");

Iterator it = link.iterator();
while(it.hasNext()){
    System.out.println(it.next());
}
System.out.println("-----------------------");
System.out.println(link.getFirst());
System.out.println(link.getFirst());//getFirst获取第一个元素但是不会删除
System.out.println("-----------------------");

System.out.println(link.removeFirst());
System.out.println(link.removeFirst());//remove改变集合长度,第二个元素变成第一个
System.out.println("-----------------------");
link.addFirst("abc3");
link.addFirst("abc4");
while (!link.isEmpty()) {
    System.out.println(link.removeFirst());//可以用这种方法来取集合中的元素,不过取完集合就变成空的了
}

输出结果:
abc4
abc3
abc2
abc1


abc4
abc4


abc4
abc3


abc4
abc3
abc2
abc1

在JDK1.6版本后新增了一些方法
addFirst();
addLast():
jdk1.6
offerFirst();
offetLast();

getFirst();.//获取但不移除,如果链表为空,抛出NoSuchElementException.
getLast();
jdk1.6
peekFirst();//获取但不移除,如果链表为空,返回null.
peekLast():

removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException.
removeLast();
jdk1.6
pollFirst();//获取并移除,如果链表为空,返回null.
pollLast();

ArrayList

ArrayList是大小可变的数组,ArrayList()构造函数默认初始化一个容量为10的空列表

ArrayList内存示意图如下:

List取子集 java java list子类_java_02


ArrayList中每一个元素都有自己的地址值,数组中存储着这些元素的地址值,因为数组是一片连续的空间,所以在查询某一元素的时候速度很快。但是如果删除1角标的元素,因为remove会改变集合的长度,删除后如下

List取子集 java java list子类_java_03


角标1后所以的元素位置都需要做改变,所以ArrayList增删元素的速度相对较慢。

ArrayList al = new ArrayList();

al.add(new Person("lisi1",21));
al.add(new Person("lisi2",22));
al.add(new Person("lisi3",23));
al.add(new Person("lisi4",24));
al.add(5);//JDK1.5版本以后自动装箱
al.add(new Integer(10));//JDK1.4版本前

Iterator it = al.iterator();
while(it.hasNext()){
    System.out.println(it.next());
}

输出结果:
lisi1:21
lisi2:22
lisi3:23
lisi4:24
5
10