Java集合之List接口


List接口繼承了Collection接口,其主要實現類如下所示:

├List(在Collection接口的基礎上新增加了一些方法)
│├LinkedList  (底層是鏈表實現)
│├ArrayList (底層爲對象數組,容量默認爲10,擴容1.5,即每次增長原來的0.5倍)
│ └Vector(底層爲對象數組,容量默認爲10,可按規定值擴容,默認爲每次增長爲原來的1倍)
│ └Stack


一、List接口常用實現類介紹

1、LinkedList類底層是由雙鏈表實現的,雙鏈表有一個虛擬節點header,節點值爲null,前驅引用指向尾節點,後繼引用指向頭節點。通過虛擬節點header可很方便的找到尾節點,而不用去遍歷整個鏈表。該類具有鏈表的所有特性,插入、刪除操作很方便,訪問節點需要遍歷鏈表(雖然刪除節點也需要遍歷,但不需要移動元素)較慢。

    適用場景:數據的大小未知,數據動態插入與刪除。

虛擬節點及其數據結構如下:

 private transient Entry<E> header = new Entry<E>(null, null, null);//虛擬節點

 private static class Entry<E> {
E element;
Entry<E> next;
Entry<E> previous;


Entry(E element, Entry<E> next, Entry<E> previous) {
   this.element = element;
   this.next = next;
   this.previous = previous;
}
    }

2、ArrayList類底層是由可變的對象數組實現的,對象數組默認大小爲10,在容量不夠時擴容爲原來的1.5倍,即每次擴容大小增長0.5倍。ArrayList具有數組的所有性質,易於隨機訪問,一般情況下插入和刪除需要移動元素(需要一定元素,擴容需要富足元素,代價較大)。

   適用場景:數據大小已知,高效訪問,一般不需隨機插入和刪除。

 private transient Object[] elementData;//對象數組

//可以指定數組大小

 public ArrayList(int initialCapacity) {
super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
this.elementData = new Object[initialCapacity];
    }


    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
this(10);
    }

//容量不夠時做擴容處理,爲原來大小的1.5倍,且需要將原來的元素複製到新的數組中,該過程較耗時。

 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;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
}
    }

3、Vector底層實現也是可變數組,其基本功能跟ArrayList類似,不同的是Vector是線程安全的,對象數組的操作全部加鎖;另外其擴容大小爲原來的2倍。由於加鎖實現線程同步,訪問效率比ArrayList慢。

   適用場景:數據大小已知,高效隨機訪問,且需要保證線程安全。

4、Stack繼承自Vector,在Vector的基礎上實現了元素先入後出的操作,線程安全。

    適用場景:數據大小已知,具有先入後出的特性。


二、其他知識點

1、結合排序

Java API針對集合類型排序提供了兩種支持:
java.util.Collections.sort(java.util.List) 
java.util.Collections.sort(java.util.List, java.util.Comparator) 
第一個方法要求所排序的元素類必須實現java.lang.Comparable接口,該方法具有侵入性。
第二個方法要求實現一個java.util.Comparator接口。


2、集合遍歷

 a、for each遍歷

List<Integer> list = new ArrayList<Integer>();
for (Integer j : list) {
// use j
}

b、迭代器遍歷

List<Integer> list = new ArrayList<Integer>();
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext();) {
iterator.next();
}

c、下標遍歷

List<Integer> list = new ArrayList<Integer>();
for (int j = 0; j < list.size(); j++) {
list.get(j);
}

一般情況下建議使用for each遍歷,勿須關注下標。迭代器遍歷linkedList時,get方法會從頭遍歷至index下標,效率較低。


3、線程安全類

Collections.synchronizedList(List<? extends E> list)類是List的線程安全的代理類,在操作list時會加鎖,線程安全。

Collections.UnmodifiableList(List<? extends E> list)類是List的線程安全類,只能讀,不能寫。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章