這一節主要介紹List介面的幾個實現類的區別: 1.線程安全 Vector是線程安全的,而ArrayList和LinkedList是非線程安全的。從源碼中我們可知,Vector類中的方法大部分都是同步的,即被synchronized關鍵字修飾;而那些沒有被synchronized關鍵字修飾的方法都是 ...
這一節主要介紹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的排序也是同樣的操作,此處不再贅述。