@Author:cjcj cj.yangjun@gmail.com <c-j.iteye.com>
题记:
当我还是个年幼无知的孩童时,就被网络给害了.......
网络曾经一度传言,遍历List对象Iterator比普通的for循环效率要高,于是乎,今天兴致勃勃的把工程里遍历都改成了Iterator,可在一念之间,做了一个简单的测试才恍然大悟.....另外在测试中竟然发现LinkedList出现OutOfMemoryErr错误...就更让我迷惑了...
List接口:
现在工程中常用的List来存储数据项,其中最常用的应该是ArrayList和LinkedList,抱着知其所以然的态度来窥视下这两个List容器...(文章会慢慢完善)
继承关系:
ArrayList的继承关系是:
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
可以看到
implements List---关联了List接口
Cloneable--是为了clone方法使用
Serializable--基本上为了让对象序列话用于异地JVM调用
LinkedList的继承关系是:
public class LinkedList extends AbstractSequentialList
implements List, Cloneable, java.io.Serializable
implements List---关联了List接口
存储形式:
ArrayList是用一个动态Object[]数组存储数据..
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object elementData[];
初始化赋值操作为:
this.elementData = new Object[initialCapacity];
在JDK1.6 中,这个数组初始化是的大小是10,也就是 new Object[10];
add()赋值操作为:
当新增数据时,ArrayList会尝试按照 (当前大小*3)/2 + 1 的递增方式增加存储块..如一下代码:
public void ensureCapacity(int minCapacity) {
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}
LinkedList是用一个私有类private static class Entry 来存储数据
private transient Entry header = new Entry(null, null, null);
初始化时,她的大小为:0
add()赋值操作为:
private Entry addBefore(Object o, Entry e) {
Entry newEntry = new Entry(o, e, e.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
return newEntry;
}
类似一个双向链表一样增加数据;所以他存储的每个单位的开销要比ArrayList要大
测试代码:
List list=new LinkedList();
for(int i=0 ;i<3000000;++i){
list.add("tesing--cjcj");
}
long now=System.currentTimeMillis();
Iterator iter=list.iterator();
while(iter.hasNext()){
Object obj=iter.next();
}
System.out.println(System.currentTimeMillis()-now);
now = System.currentTimeMillis();
for(int i =0;i<list.size();++i){
Object obj=list.get(i);
}
System.out.println(System.currentTimeMillis()-now);
测试结果:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
而用ArrayList则不会出现内存溢出.
大致结论:
ArrayList用的数据结构用for是最快的,存储的容量也比LinkedList要大..适合从后面增加或删除数据和随机查询
LinkedList则用Iterator比for要快...适合随机增加数据
1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。
2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。
3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。
4.HashTable使用Enumeration,HashMap使用Iterator。