Java集合相關面試題整理
1、為什麼要使用集合?
針對於陣列的缺點出現的:陣列的長度固定的,且只能存放一種型別的資料;
2、集合的特點?
(1)長度可擴充套件,可以存放多種型別的資料;
(2)只能存放引用型別的資料,哪怕存放基本型別進去,也會先將其轉換為包裝型別才儲存進去;
(3)集合存放的只是物件的引用,物件本身還是儲存在堆中的;
(4)有倆個基本的介面,iterator介面(collection是list與set的父介面)與map;
ps:繼承順序list、set ----> collection ----> iterable(其中分裝了iterator介面)
3、List集合相關問題:
(1)List介面的典型實現:
1>、ArratList:底層是陣列,隨機獲取元素快,刪除、新增慢,執行緒不安全;
2>、vector:底層為陣列,隨機獲取元素快,刪除,新增慢,執行緒安全;
3>、LinkedList:底層為連結串列結構,隨機獲取元素慢,新增、刪除元素較快,執行緒不安全的;
(2)ArrayList與LinkedList的區別?(此處只講隨機獲取元素以及新增刪除方面的異同)
ArrayList採用的是陣列的方式實現List介面的,陣列是採用一段連續的儲存單元來儲存資料,它的優點是若通過索引的方式快速獲定位物件的位置,但是若是新增/刪除資料速度會比較慢,因為需要移動所有元素的儲存的位置;
LinkedList採用的是連結串列的方式實現List介面的,對於線性連結串列來說,新增或者刪除資料只需要處理節點間的引用就行(線性連結串列講解:https://mp.csdn.net/mdeditor/83628312#),但是對於隨機得到元素來說速度很慢,因為採用的是連結串列,故先要遍歷連結串列;
(3)ArrayList與Vector的區別?
1>、ArrayList是執行緒非安全的,Vector是執行緒安全的;
2>、ArrayList的中的元素如果超過其容量的話,其容量會擴容50%+1,但是Vector卻會翻倍;
(4)陣列與連結串列異同?
相同點: 陣列是線性的,連結串列也是線性的;陣列的訪問是通過索引來訪問的,連結串列型資料的訪問是通過移動指標,且只能從頭到尾;
不同點:陣列元素在記憶體中是連續的,在棧區,而連結串列元素在記憶體中是不連續的,在堆區;
4、Set集合的相關問題:
(1)Set介面的典型實現
1>、hashSet:底層採用hash演算法,不保證元素的新增順序,查詢效率高(原因見:);
2>、LinkedHashSet:hashSet的子類,在hashSet的基礎上實現了連結串列結構,及保證了元素的新增順序,整體效能低於hashSet(隨機訪問元素效率慢);
3>、TreeSet:不能儲存null,底層實現了紅黑樹演算法,有序,擅長於範圍查詢;
(2)hashSet與hashMap的關係?
1>、hashSet相當於(key,null)的hashMap;
(3)hashSet、LinkedHashSet的區別與TreeSet的區別?
hashSet與LinkedHashSet的區別僅在後者的底層實現了線性連結串列(按照插入的順序排序);
hashSet與TreeSet的區別:
1>、hashSet的key可以為null,但是TreeSet不行;
2>、hashSet不能保證插入的元素的順序,treeSet是有序的(自己的演算法排序);
3>、hash底層實現的是hash表演算法,而TreeSet實現的是紅黑樹演算法;
4>、hashSet是通過equals與hashCode方法判斷元素是否重複,TreeSet是通過comparato的返回值來判斷元素是否重複以及排序的規則的;
5>、TreeSet儲存自定義型別的物件,自定義的類必須實現comparato方法,否則無法判斷元素的“大小”(排序規則);
6>、comparato的返回值為0,則不儲存元素,返回值為1,則認為儲存值與比較值相比較大,若返回值為-1則認為,儲存值與比較值相比較小;
7>、TreeSet的排序規則分為倆種,自然排序與定製排序,自然排序就是按照從小到大的順序排序,定製排序則是按照自己的規則排序;
5、Map集合的相關問題:
(1)Map集合的典型實現
1>、HashMap:底層採用hash表演算法,key的順序與hashSet一致,不會保證新增的順序;
2>、TreeMap:底層紅黑樹演算法,排序規則按照自然排序或者定製順訊;
3>、LinkedHashMap:採用連結串列演算法和雜湊演算法,保證元素的新增順序;
4>、HashTable:採用雜湊表演算法,基本功能與hashMap類似,但是會保證插入的順序,且為執行緒同步的,key鍵不能為null,且效率低下(一個執行緒對其做put處理時,其他執行緒不僅不嫩使用put且不能使用get,造成執行緒的阻塞)jdk5之後提供了ConcurrentHashMap,是HashTable的擴充套件版本;
5>、Properties:HashTable的子類,用來載入properties檔案的;
(2)HashMap與HashTable的區別?
1>、倆者幾乎相同,但是會保證插入的順序(且不能保證隨著時間的推移,元素順序不變),且為執行緒同步,jdk5之後出了ConcurrentHashMap,是HashTable的擴充套件;
2>、HashMap使用的迭代器是Iterator是fail-fast(但是其remove方法是不會丟擲fail-fast,且不是必然發生的),而HashTable使用的enumerator迭代器不是fail-fast的;
3>、HashMap在單執行緒的效能要超過HashTable;
(3)HashMap的實現原理?
1>、map集合:
嚴格意義上來說map並不是集合,而是倆個集合之間的對映關係;
並未實現collection介面也未實現Iterable介面,因此不能採用forEach遍歷;
是Entry(key,value),map可以看成是由多個Entry組成的;
2>、HashMap的實現原理:
是基於雜湊表演算法+陣列實現的;
HashMap在儲存物件時是將key-value當做一個整體進行處理的,這個整體就是一個Node物件,儲存物件時,先呼叫key的hash演算法來決定其在陣列中的位置,在根據equals演算法決定其在該陣列連結串列(bucket)上的位置;取物件時,先得到key的hashCode值,在根據equals方法從該位置上的連結串列中取出該Node;
使用了fail-fast機制;
3>、Map與set的關係?
hashSet、hashMap採用的底層演算法都是hash表演算法,treeSet與treeMap採用的都是紅黑樹演算法;
set集合就是由map集合的key組成的;
(4)ConcurrentHashMap
同步機制:使用分段鎖技術------結構與HashMap類似,採用的是陣列+連結串列的方式,分段鎖是將集合分為一段一段的segment然後給每一段segment分配一個鎖,當一個縣城訪問一個segment時,其他的分段也能被其他執行緒訪問,即可以實現並行插入;
組成結構:一個ConcurrentHashMap是一個segment陣列,一個segment是一個hashEntry陣列,而每個hashEntry都是連結串列結構的元素,用來封裝雜湊對映表中的鍵值對;
應用場景:多執行緒的寫
get不加鎖,定位到segment之後找到頭節點進行去取操作,value是通過volatile修飾的;
put加鎖,新增到hash連結串列的頭部;
remove加鎖,由於next是final型別的,所以必須把刪除之前的節點都複製一遍;
ps:ConcurrentHashMap只能保證每一個呼叫是原子性的,但是不能保證多次的呼叫也是原子性的(這句話不太懂,如果有人知道的話請指導一下)