1. 程式人生 > >java集合類源碼分析之List(二)

java集合類源碼分析之List(二)

頻繁 null 並且 reel closed tco 默認 java集合 進行

這一節主要介紹List接口的幾個實現類的區別:

1.線程安全

Vector是線程安全的,而ArrayList和LinkedList是非線程安全的。從源碼中我們可知,Vector類中的方法大部分都是同步的,即被synchronized關鍵字修飾;而那些沒有被synchronized關鍵字修飾的方法都是通過調用其他同步方法或者采用同步代碼塊來達到同步的。

技術分享
 1     public synchronized void addElement(E obj) {
 2         modCount++;
 3         ensureCapacityHelper(elementCount + 1);
4 elementData[elementCount++] = obj; 5 } 6 7 public synchronized boolean removeElement(Object obj) { 8 modCount++; 9 int i = indexOf(obj); 10 if (i >= 0) { 11 removeElementAt(i); 12 return true; 13 } 14 return false
; 15 } 16 17 public synchronized E get(int index) { 18 if (index >= elementCount) 19 throw new ArrayIndexOutOfBoundsException(index); 20 21 return elementData(index); 22 } 23 24 public synchronized void insertElementAt(E obj, int index) { 25 modCount++;
26 if (index > elementCount) { 27 throw new ArrayIndexOutOfBoundsException(index 28 + " > " + elementCount); 29 } 30 ensureCapacityHelper(elementCount + 1); 31 System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); 32 elementData[index] = obj; 33 elementCount++; 34 }
View Code 技術分享
 1     public boolean contains(Object o) {
 2         return indexOf(o, 0) >= 0;
 3     }
 4 
 5     public synchronized int indexOf(Object o, int index) {
 6         if (o == null) {
 7             for (int i = index ; i < elementCount ; i++)
 8                 if (elementData[i]==null)
 9                     return i;
10         } else {
11             for (int i = index ; i < elementCount ; i++)
12                 if (o.equals(elementData[i]))
13                     return i;
14         }
15         return -1;
16     }
17 
18     public Enumeration<E> elements() {
19         return new Enumeration<E>() {
20             int count = 0;
21 
22             public boolean hasMoreElements() {
23                 return count < elementCount;
24             }
25 
26             public E nextElement() {
27                 synchronized (Vector.this) {
28                     if (count < elementCount) {
29                         return elementData(count++);
30                     }
31                 }
32                 throw new NoSuchElementException("Vector Enumeration");
33             }
34         };
35     }
View Code

2.適用條件

ArrayList:適用於隨機訪問比較頻繁(自帶索引),而插入和刪除操作較少的情況下;

LinkedList:適用於插入和刪除比較頻繁(修改前後節點),而隨機訪問較少的情況下;

Vector:適用於要求線程安全(方法同步),執行效率不高,數據量大的情況下。

3.內存消耗

在內存消耗方面,LinkedList < ArrayList < Vector。

LinkedList由於采用鏈表的形式實現,所以不需要指定容量大小,因此內存消耗較少;而ArrayList和Vector都是采用數組的形式實現,需要指定初始容量的大小(默認都是10),並且當容量不夠時都需要進行擴容,在擴容方面:

  • ArrayList每次只增加當前數組長度的一半,即newCapacity = oldCapacity + (oldCapacity >> 1),源碼中擴容的方法如下:
技術分享
 1     private void grow(int minCapacity) {
 2         // overflow-conscious code
 3         int oldCapacity = elementData.length;
 4         int newCapacity = oldCapacity + (oldCapacity >> 1);
 5         if (newCapacity - minCapacity < 0)
 6             newCapacity = minCapacity;
 7         if (newCapacity - MAX_ARRAY_SIZE > 0)
 8             newCapacity = hugeCapacity(minCapacity);
 9         // minCapacity is usually close to size, so this is a win:
10         elementData = Arrays.copyOf(elementData, newCapacity);
11     }
View Code
  • Vector每次增加當前數組長度的一倍,即newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity),capacityIncrement是人為指定的擴容大小,默認為0,源碼中擴容的方法如下:
技術分享
 1     private void grow(int minCapacity) {
 2         // overflow-conscious code
 3         int oldCapacity = elementData.length;
 4         int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
 5                                          capacityIncrement : oldCapacity);
 6         if (newCapacity - minCapacity < 0)
 7             newCapacity = minCapacity;
 8         if (newCapacity - MAX_ARRAY_SIZE > 0)
 9             newCapacity = hugeCapacity(minCapacity);
10         elementData = Arrays.copyOf(elementData, newCapacity);
11     }
View Code

綜上所述,Vector對內存的消耗比較高,其次是ArrayList。

4.集合排序

有了數據的存儲方法(集合),當然要考慮到數據在集合中的順序問題,下面對集合排序做一個簡單的總結:

  • 集合中的排序通常調用Collections類中的靜態方法來實現,常用的方法有:sort、reverse、shuffle、min、max等。
技術分享
 1         LinkedList<Integer> linkedList = new LinkedList<Integer>();
 2         linkedList.add(100);
 3         linkedList.add(120);
 4         linkedList.add(110);
 5         Collections.sort(linkedList);//升序排列
 6         System.out.println(linkedList);
 7         
 8         Collections.sort(linkedList, new Comparator<Integer>() {
 9 
10             @Override
11             public int compare(Integer o1, Integer o2) {
12                 // TODO Auto-generated method stub
13 //                return 0;
14                 return o2.compareTo(o1);    //降序排列
15             }
16         });
17         System.out.println(linkedList);
18         
19         Collections.shuffle(linkedList);//隨機亂序
20         System.out.println(linkedList);
21         
22         Collections.reverse(linkedList);//逆序
23         System.out.println(linkedList);
24         
25         System.out.println(Collections.min(linkedList));//最小值
26         System.out.println(Collections.max(linkedList));//最大值
View Code

這裏只給出了LinkedList的排序代碼,而對於ArrayList和Vector的排序也是同樣的操作,此處不再贅述。

java集合類源碼分析之List(二)