再快不能快基礎,再爛不能爛語言! 面試
List,Set都是繼承自Collection接口,List特色:有序可重複,Set特色:無序不可重複,重複元素會覆蓋掉算法
Set:檢索元素效率低下,刪除和插入效率高,插入和刪除不會引發元素位置改變。<實現類有HashSet,TreeSet>編程
List:和數組相似,List能夠動態增加,查找元素效率高,插入刪除元素效率低,由於會引發其餘元素位置改變。<實現類有ArrayList,LinkedList,Vector>數組
List是對象集合,容許對象重複。安全
Map是鍵值對的集合,不容許key重複。bash
Arraylist:數據結構
優勢:ArrayList是實現了基於動態數組的數據結構,由於地址連續,一旦數據存儲好了,查詢操做效率會比較高(在內存裏是連着放的)。多線程
缺點:由於地址連續, ArrayList要移動數據,因此插入和刪除操做效率比較低。併發
LinkedList:異步
優勢:LinkedList基於鏈表的數據結構,地址是任意的,因此在開闢內存空間的時候不須要等一個連續的地址,對於新增和刪除操做add和remove,LinedList比較佔優點。LinkedList 適用於要頭尾操做或插入指定位置的場景
缺點:由於LinkedList要移動指針,因此查詢操做性能比較低。
適用場景分析:
當須要對數據進行對此訪問的狀況下選用ArrayList,當須要對數據進行屢次增長刪除修改時採用LinkedList。
public ArrayList(int initialCapacity)//構造一個具備指定初始容量的空列表。
public ArrayList()//構造一個初始容量爲10的空列表。
public ArrayList(Collection<? extends E> c)//構造一個包含指定 collection 的元素的列表
複製代碼
public Vector()//使用指定的初始容量和等於零的容量增量構造一個空向量。
public Vector(int initialCapacity)//構造一個空向量,使其內部數據數組的大小,其標準容量增量爲零。
public Vector(Collection<? extends E> c)//構造一個包含指定 collection 中的元素的向量
public Vector(int initialCapacity,int capacityIncrement)//使用指定的初始容量和容量增量構造一個空的向量
複製代碼
ArrayList和Vector都是用數組實現的,主要有這麼三個區別:
Vector是多線程安全的,線程安全就是說多線程訪問同一代碼,不會產生不肯定的結果。而ArrayList不是,這個能夠從源碼中看出,Vector類中的方法不少有synchronized進行修飾,這樣就致使了Vector在效率上沒法與ArrayList相比;
兩個都是採用的線性連續空間存儲元素,可是當空間不足的時候,兩個類的增長方式是不一樣。
Vector能夠設置增加因子,而ArrayList不能夠。
Vector是一種老的動態數組,是線程同步的,效率很低,通常不同意使用。
適用場景分析:
Vector是線程同步的,因此它也是線程安全的,而ArrayList是線程異步的,是不安全的。若是不考慮到線程的安全因素,通常用ArrayList效率比較高。
若是集合中的元素的數目大於目前集合數組的長度時,在集合中使用數據量比較大的數據,用Vector有必定的優點。
hashMap去掉了HashTable 的contains方法,可是加上了containsValue()和containsKey()方法。
hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
hashMap容許空鍵值,而hashTable不容許。
注意:
set是線性結構,set中的值不能重複,hashset是set的hash實現,hashset中值不能重複是用hashmap的key來實現的。
map是鍵值對映射,能夠空鍵空值。HashMap是Map接口的hash實現,key的惟一性是經過key值hash值的惟一來肯定,value值是則是鏈表結構。
他們的共同點都是hash算法實現的惟一性,他們都不能持有基本類型,只能持有對象
ConcurrentHashMap是線程安全的HashMap的實現。
HashTable裏使用的是synchronized關鍵字,這實際上是對對象加鎖,鎖住的都是對象總體,當Hashtable的大小增長到必定的時候,性能會急劇降低,由於迭代時須要被鎖定很長的時間。
ConcurrentHashMap算是對上述問題的優化,其構造函數以下,默認傳入的是16,0.75,16。
public ConcurrentHashMap(int paramInt1, float paramFloat, int paramInt2) {
//…
int i = 0;
int j = 1;
while (j < paramInt2) {
++i;
j <<= 1;
}
this.segmentShift = (32 - i);
this.segmentMask = (j - 1);
this.segments = Segment.newArray(j);
//…
int k = paramInt1 / j;
if (k * j < paramInt1)
++k;
int l = 1;
while (l < k)
l <<= 1;
for (int i1 = 0; i1 < this.segments.length; ++i1)
this.segments[i1] = new Segment(l, paramFloat);
}
public V put(K paramK, V paramV) {
if (paramV == null)
throw new NullPointerException();
int i = hash(paramK.hashCode()); //這裏的hash函數和HashMap中的不同
return this.segments[(i >>> this.segmentShift & this.segmentMask)].put(paramK, i, paramV, false);
}
複製代碼
ConcurrentHashMap引入了分割(Segment),上面代碼中的最後一行其實就能夠理解爲把一個大的Map拆分紅N個小的HashTable,在put方法中,會根據hash(paramK.hashCode())來決定具體存放進哪一個Segment,若是查看Segment的put操做,咱們會發現內部使用的同步機制是基於lock操做的,這樣就能夠對Map的一部分(Segment)進行上鎖,這樣影響的只是將要放入同一個Segment的元素的put操做,保證同步的時候,鎖住的不是整個Map(HashTable就是這麼作的),相對於HashTable提升了多線程環境下的性能,所以HashTable已經被淘汰了。
【推薦篇】- 書籍內容整理筆記 | 連接地址 |
---|---|
【推薦】【Java編程思想】【筆記】 | juejin.im/post/5dbb7a… |
【推薦】【Java核心技術 卷Ⅰ】【筆記】 | juejin.im/post/5dbb7b… |
如有錯誤或者理解不當的地方,歡迎留言指正,但願咱們能夠一塊兒進步,一塊兒加油!😜😜