集合框架介紹
說明:對於以上的框架圖有如下幾點說明
1.所有集合類都位於java.util包下。Java的集合類主要由兩個接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,這兩個接口又包含了一些子接口或實現類。
2. 集合接口:6個接口(短虛線表示),表示不同集合類型,是集合框架的基礎。
3. 抽象類:5個抽象類(長虛線表示),對集合接口的部分實現。可擴展為自定義集合類。
4. 實現類:8個實現類(實線表示),對接口的具體實現。
5. Collection 接口是一組允許重復的對象。
6. Set 接口繼承 Collection,集合元素不重復。
7. List 接口繼承 Collection,允許重復,維護元素插入順序。
8. Map接口是鍵-值對象,與Collection接口沒有什么關系。
9.Set、List和Map可以看做集合的三大類:
List集合是有序集合,集合中的元素可以重復,訪問集合中的元素可以根據元素的索引來訪問。
Set集合是無序集合,集合中的元素不可以重復,訪問集合中的元素只能根據元素本身來訪問(也是集合里元素不允許重復的原因)。
Map集合中保存Key-value對形式的元素,訪問時只能根據每項元素的key來訪問其value。
List集合介紹:
List集合代表一個有序集合,集合中每個元素都有其對應的順序索引。List集合允許使用重復元素,可以通過索引來訪問指定位置的集合元素。
List接口繼承於Collection接口,它可以定義一個允許重復的有序集合。因為List中的元素是有序的,所以我們可以通過使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。
List接口為Collection直接接口。List所代表的是有序的Collection,即它用某種特定的插入順序來維護元素順序。用戶可以對列表中每個元素的插入位置進行精確地控制,同時可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。實現List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。
ArrayList底層實現原理
- Arraylist底層基於數組實現
-
private Object[] elementData;
Arraylist底層默認數組初始化大小為10個object數組
-
public ExtArraylist() throws Exception {
this(10);
}
public ExtArraylist( int initialCapacity) throws Exception {
if (initialCapacity < 0) {
throw new IllegalArgumentException("初始容量不能小於0 " + initialCapacity);
}
elementData = new Object[initialCapacity];
}
添加元素后大於當前數組的長度,則進行擴容,將數組的長度增加原來數組的一半。
-
// 增大數組空間
private void grow ( int minCapacity){
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 在原來容量的基礎上加上
// oldCapacity/2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; // 最少保證容量和minCapacity一樣
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity); // 最多不能超過最大容量
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
Vector底層實現原理
Vector是線程安全的,但是性能比ArrayList要低。
ArrayList,Vector主要區別為以下幾點:
(1):Vector是線程安全的,源碼中有很多的synchronized可以看出,而ArrayList不是。導致Vector效率無法和ArrayList相比;
(2):ArrayList和Vector都采用線性連續存儲空間,當存儲空間不足的時候,ArrayList默認增加為原來的50%,Vector默認增加為原來的一倍;
(3):Vector可以設置capacityIncrement,而ArrayList不可以,從字面理解就是capacity容量,Increment增加,容量增長的參數。
private void grow ( int minCapacity){
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //擴充的空間增加原來的50%(即是原來的1.5倍)
if (newCapacity - minCapacity < 0) //如果容器擴容之后還是不夠,那么干脆直接將minCapacity設為容器的大小
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) //如果擴充的容器太大了的話,那么就執行hugeCapacity
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
LinkeList原理
LinkedList 和 ArrayList 一樣,都實現了 List 接口,但其內部的數據結構有本質的不同。LinkedList 是基於鏈表實現的(通過名字也能區分開來),所以它的插入和刪除操作比 ArrayList 更加高效。但也是由於其為基於鏈表的,所以隨機訪問的效率要比 ArrayList 差。