List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。List接口一共有3个实现类,分别是ArrayList、Vector和LinkedList。3个实现类的区别如下:
- ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组元素复制到新的存储空间中。当在ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动,代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
- Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
- LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,它还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
List:
|–Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
|–ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
|–LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
关于ArrayList和Vector区别如下:
- ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
- Vector提供indexOf(obj, start)接口,ArrayList没有。
- Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
Vector
Vector是可实现自动增长的对象数组。
java.util.vector提供了向量类(vector)以实现类似动态数组的功能。在Java语言中没有指针的概念,但如果正确灵活地使用指针又确实可以大大提高程序的质量。比如在c/c++中所谓的“动态数组”一般都由指针来实现。为了弥补这个缺点,Java提供了丰富的类库来方便编程者使用,vector类便是其中之一。事实上,灵活使用数组也可以完成向量类的功能,但向量类中提供大量的方法大大方便了用户的使用。
创建了一个向量类的对象后,可以往其中随意插入不同类的对象,即不需顾及类型也不需预先选定向量的容量,并可以方便地进行查找。对于预先不知或者不愿预先定义数组大小,并且需要频繁地进行查找,插入,删除工作的情况,可以考虑使用向量类。
Vector类提供了三种构造方法:
public vector()
public vector(int initialCapacity,int capacityIncrement)
public vector(int initialCapacity)
- 使用第一种方法系统会自动对向量进行管理。若使用后两种方法,系统将根据参数initialCapacity设定向量对象的容量(即向量对象可存储数据的大小),当真正存放的数据个数超过容量时,系统会扩充向量对象存储容量。
- 参数capacityIncrement给定了每次扩充的扩充值。当capacityincrement为0时,每次扩充一倍。利用这个功能可以优化存储。在Vector类中提供了各种方法方便用户的使用:
插入功能:
(1)public final synchronized void addElement(Object obj)
将obj插入向量的尾部。obj可以是任何类型的对象。对同一个向量对象,亦可以在其中插入不同类的对象,但插入的应是对象而不是数值,所以插入数值时要注意将数组转换成相应的对象。
例如:要插入整数1时,不要直接调用v1.addElement(1),正确的方法为:
Vector v1 = new Vector();
Integer integer1 = new Integer(1);
v1.addElement(integer1);
(2)public final synchronized void setElementAt(Object obj,int index)
将index处的对象设置成obj,原来的对象将被覆盖。
(3)public final synchronized void insertElementAt(Object obj,int index)
在index指定的位置插入obj,原来对象以及此后的对象依次往后顺延。
删除功能:
(1)public final synchronized void removeElement(Object obj)
从向量中删除obj,若有多个存在,则从向量头开始试,删除找到的第一个与obj相同的向量成员。
(2)public final synchronized void removeAllElement()
删除向量所有的对象
(3)public fianl synchronized void removeElementAt(int index)
删除index所指的地方的对象
查询搜索功能:
(1)public final int indexOf(Object obj)
从向量头开始搜索obj,返回所遇到的第一个obj对应的下标,若不存在此obj,返回-1
(2)public final synchronized int indexOf(Object obj,int index)
从index所表示的下标处开始搜索obj
(3)public final int lastindexOf(Object obj)
从向量尾部开始逆向搜索obj
(4)public final synchornized int lastIndex(Object obj,int index)
从index所表示的下标处由尾至头逆向搜索obj
(5)public final synchornized firstElement()
获取向量对象中的首个obj
(6)public final synchornized Object lastElement()
获取向量对象的最后一个obj
其他功能:
(1)public final int size()
此方法用于获取向量元素的个数。它们返回值是向量中实际存在的元素个数,而非向量容量。可以调用方法capacity()来获取容量值。
(2) public final synchronized void setsize(int newsize)
此方法用来定义向量的大小,若向量对象现有成员个数已经超过了newsize的值,则超过部分的多余元素会丢失。
(3)public final synchronized Enumeration elements()
此方法将向量对象对应到一个枚举类型。
Enumeration是java.util中的一个接口, 在Enumeration中封装了有关枚举数据集合的方法。 在Enumeration提供了方法hasMoreElement()来判断集合中是否还有其他元素,以及方法nextElement()来获取下一个元素。利用这两个方法,可以依次获得集合中的元素。
示例:
// Enumeration枚举接口的功能和Iterator迭代器接口的功能是重复的,Iterator接口添加了一个可选的移除方法,并使用较短的方法名
// java1.2开始,使用Iterator替代Enumeration
Vector v = new Vector();
v.addElement("abc1");
v.addElement("abc2");
Enumeration en = v.elements();
while(en.hasMoreElements()){
System.out.println("nextelment:"+en.nextElement());
}
Iterator it = v.iterator();
while(it.hasNext()){
System.out.println("next:"+it.next());
}
ArrayList
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("P1",21));
al.add(new Person("P1",22));
al.add(new Person("P2",23));
al.add(new Person("P3",24));
System.out.println(al); // [P1:21, P1:22,P2:23, P3:24]
Iterator it = al.iterator();
while(it.hasNext()){
Person p = (Person) it.next();
System.out.println(p.getName()+":"+p.getAge());
}
LinkedList
LinkedList link = new LinkedList();
link.getFirst(); // 获取第一个但不删除。当链表为空的时候会抛出抛出NoSuchElementException
link.getLast(); // 获取最后一个元素,当链表为空的时候会抛出抛出NoSuchElementException
link.peekFirst(); // 获取第一个元素,当链表为为空的时候不会报异常,返回null
link.peekLast(); // 获取最后一个元素
link.removeFirst(); // 获取第一个元素但是会删除。当链表为空的时候会抛出NoSuchElementException
link.removeLast(); // 获取最后一个元素但是会删除。当链表为空的时候会抛出NoSuchElementException
link.pollFirst(); // 获取第一个元素并从集合中移除(1.6出来的新方法,当链表为为空的时候不会报异常)
link.pollLast(); // 获取最后一个元素并从集合中移除
Iterator it = link.iterator();
while(it.hasNext()){
System.out.println(it.next());
}