1. Vector
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:
- Vector 是同步访问的。
- Vector 包含了许多传统的方法,这些方法不属于集合框架。
Vector 主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。
构造方法
第一种构造方法创建一个默认的向量,默认大小为 10:
Vector()
第二种构造方法创建指定大小的向量。
Vector(int size)
第三种构造方法创建指定大小的向量,并且增量用 incr 指定。增量表示向量每次增加的元素数目。
Vector(int size,int incr)
第四种构造方法创建一个包含集合 c 元素的向量:
Vector(Collection c)
2.比较
Vector、ArrayList、LinkedList这三者都实现了List 接口.
List是有序、可重复的容器
有序:List中每个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素
可重复:List允许加入重复的元素、List通常允许满足e1.equals(e2)的元素重复加入容器
| ArrayList | Vector | LinkedList | |
|---|---|---|---|
| 线程安全 | 否 | 是 | 否 |
| 底层实现 | 数组 | 数组 | 链表 |
| 性能 | 查询快,增删慢 | 最慢 | 增删快,查询慢 |
| 扩容 | 1.5倍 | 2倍 | 无 |
| 默认大小 | 10 | 10 | 空链表 |
| 值是否可以为null | 可以 | 可以 | 可以 |
| 泛型 | 支持 | 支持 | 支持 |
线程安全
Vector相关的方法都添加了同步检查,因此线程安全、效率低,
public synchronized boolean add(E e)
public synchronized E remove(int index)
........
默认大小
ArrayList
private static final int DEFAULT_CAPACITY = 10;
发生在无参构造的第一次添加元素
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
Vector
无参构造
public Vector() {
this(10);
}
this直接调用指定大小的构造方法,传入10
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
LinkedList
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
Hashtable,ConcurrentHashMap键和值都设计成不能为null
因为Hashtable,ConcurrentHashMap它们是用于多线程的,并发的,如果map.get(key)得到了null ,不能判断到底是映射的value是nll,还是因为没有找到对应的key而为空,而用于单线程状态的Hashmap却可以用containsKey ( key )去判断到底是否包含了这个null。而为什么Hashtable不能用containsKey()方法呢?因为要考虑到原子性问题:一个线程先get(key)再containsKey(key),这两个方法的中间时刻,其他线程怎么操作这个key都会可能发生,例如删掉这个key。就不能保证操作的原子性了。
泛型
ArrayList
public class ArrayList<E>
Vector
public class Vector<E>
LinkedList
public class LinkedList<E>
3.总结
ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢,现在基本已弃用。