每日一面系列之Java集合基礎

1.講一下List、Set、Map三者的區別

  • List存儲的元素是有序,可以重複的。
  • Set存儲的元素是無序,不可重複的。
  • Map是以key-value鍵值對的方式存儲元素,key是無序不可重複的,value是無序可以重複的,每個key最多隻對應一個value。

2.ArrayList和LinkedList有什麼區別?

  1. 是否保證線程安全:ArrayList和LinkedList都是線程不安全的。
  2. 底層數據結構:ArrayList底層是Object數組,LinkedList底層是雙向鏈表。
  3. 插入和刪除元素操作的時間複雜度是否受元素位置的影響:ArrayList底層是採用數組方式存儲元素的,所以插入和刪除元素的時間複雜度是受元素位置所影響的,因爲每插入火刪除一個元素,其他元素的位置都會隨之移動。LinkedList底層採用的是雙向鏈表,所以插入和刪除元素的時間複雜度是不受元素位置影響的。
  4. 是否支持快速隨機訪問:ArrayList支持快速隨機訪問,可以根據元素下標快速查到對應元素。LinkedList是不支持快速隨機訪問的,需要對鏈表進行遍歷。
  5. 內存空間的佔用: ArrayList的空 間浪費主要體現在在list列表的結尾會預留⼀定的容量空
    間,⽽LinkedList的空間花費則體現在它的每⼀個元素都需要消耗⽐ArrayList更多的空間(因
    爲要存放直接後繼和直接前驅以及數據)。

3. ArrayList 與 Vector 區別呢?

ArrayList 和 Vector都實現了List接口

  1. 線程安全方面:ArrayList是線程不安全的,也是線程不同步的。Vector是線程安全的,也是線程同步的。
  2. 擴容機制方面:Vector 增長原來的一倍,ArrayList 增加原來的 0.5 倍。

4.HashMap和HashTable有什麼區別?

  1. 線程是否安全:HashMap是線程不安全的.HashTable是線程安全的,HashTable內部方法基本都使用了synchronized進行加鎖。
  2. 效率:因爲線程安全的問題,HashMap的效率要高於HashTable。
  3. key和value能否爲null:HashMap最多隻允許一個key爲null,允許一個或者多個key對應的value爲null。HashTable不允許key和value爲null。
  4. 底層數據結構:HashTable底層是使用數組加鏈表的形式實現的。HashMap在1.8之前也是使用數組加鏈表的形式實現的,在1.8之後爲了解決哈希衝突採用數組加鏈表或者數組加紅黑樹的形式實現。
  5. 初始容量的大小和擴容容量的大小:如果不指定初始化容量,HashMap默認是16,每次擴容爲原來的2倍。HashTable默認是11,每次擴容爲原來的2n+1倍。如果指定了初始化容量,HashTable會直接使用指定的容量大小,HashMap會將其擴充爲2的冪次方大小,也就是說HashMap總是使用2的冪次方作爲哈希表的大小。

5.HashMap和HashSet有什麼關係與區別?

HashSet底層就是基於HashMap實現的。

  1. HashMap實現了Map接口,HashSet實現了Set接口。
  2. HashMap存儲的是鍵值對,HashSet存儲的是對象。
  3. HashMap通過put()方法添加元素,HashSet通過add()方法添加元素。
  4. HashMap使用key計算hashcode,HashSet使用成員對象來計算hashcode,兩個對象的hashcode可能會相等,所以使用equals()方法來判斷兩個對象是否相等。

6.HashSet是如何檢查重複的?

將對象加入HashSet的時候,HashSet首先會計算該對象的hashcode值來判斷對象加入的位置,同時還會與集合中其他對象的hashcode進行比較,如果沒有與之相等的hashcode,表示新增對象沒有重複。如果有相等的hashcode,則會調用equals()方法來檢查相等hashcode的對象是否真的相等,如果真的相等,表示新增對象重複,則不會新增成功。

7.什麼是快速失敗(fail-fast)?

快速失敗(fail-fast) 是 Java 集合的⼀種錯誤檢測機制。
在使⽤迭代器對集合進⾏遍歷的時候,我們在多線程下操作⾮安全失敗(fail-safe)的集合類可能就會觸發 fail-fast 機制,導致拋ConcurrentModificationException 異常。 另外,在單線程下,如果在遍歷過程中對集合對象的內容進⾏了修改的話也會觸發 fail-fast 機制。

追問:爲什麼在遍歷過程中對集合對象的內容進行修改就會觸發fail-fast?

每當迭代器使⽤ hashNext()或者next() 遍歷下⼀個元素之前,都會先檢測 modCount 變量是否等於expectedModCount 值,是的話就返回遍歷;否則拋出異常,終⽌遍歷。如果我們在集合被遍歷期間對其進⾏修改的話,就會改變 modCount 的值,進⽽導致 modCount不等於expectedModCount ,進⽽拋出 ConcurrentModificationException 異常。

注意:通過 Iterator 的⽅法修改集合的話會修改到 expectedModCount 的值,所以不會拋出異常。

8.什麼是安全失敗(fail-safe)?

採⽤安全失敗機制的集合容器,在遍歷時不是直接在集合內容上訪問的,⽽是先複製原有集合內容,在
拷⻉的集合上進⾏遍歷。所以,在遍歷過程中對原集合所作的修改並不能被迭代器檢測到,故不會拋
ConcurrentModificationException 異常。

注意:Arrays.asList() 將數組轉換爲集合後,底層其實還是數組。不能對其進行修改。

9.說一說HashSet、LinkedHashSet和TreeSet三者有什麼異同?

  • HashSet是Set接口的主要實現類,HashSet底層是基於HashMap實現的,線程是不安全的,可以存儲null值。
  • LinkedHashSet是HashSet的子類,可以按照添加的順序進行遍歷。
  • TreeSet底層使用紅黑樹,能夠按照元素添加的順序進行遍歷,排序方式有自然排序也有定製排序。

10.講一下comparable 和 Comparator 的區別

  • comparable 接⼝實際上是出⾃java.lang包,它有⼀個 compareTo(Object obj) ⽅法⽤來排序
  • comparator 接⼝實際上是出⾃java.util包,它有⼀個 compare(Object obj1, Object obj2) ⽅法⽤來排序

11.爲什麼集合類沒有實現 Cloneable 和 Serializable 接口?

克隆 (cloning) 或者是序列化 (serialization) 的語義和含義是跟具體的實現相關的。因此,應該由集合類的具體實現來決定如何被克隆或者是序列化。

12.講一下Collection 和 Collections 的區別。

  • collection 是集合類的上級接口, 繼承與它的接口主要是 set 和 list。
  • collections 類是針對集合類的一個幫助類. 它提供一系列的靜態方法對各種集合的搜索, 排序, 線程安全化等操作。

13.什麼是迭代器 (Iterator)?

Iterator 接口提供了很多對集合元素進行迭代的方法。每一個集合類都包含了可以返回迭代器實例的迭代方法。迭代器可以在迭代的過程中刪除底層集合的元素, 但是不可以直接調用集合的 remove(Object Obj) 刪除,可以通過迭代器的 remove() 方法刪除。

14.Iterator 和 ListIterator 的區別是什麼?

  1. Iterator 可用來遍歷 Set 和 List 集合,但是 ListIterator 只能用來遍歷 List。
  2. Iterator 對集合只能是前向遍歷,ListIterator 既可以前向也可以後向。
  3. ListIterator 實現了 Iterator 接口,幷包含其他的功能,比如:增加元素,替換元素,獲取前一個和後一個元素的索引等等。

15.爲什麼要使用集合?

當我們需要保存多組類型相同的數據的時候,我們應該是多個容器來保存,這個容器就是數組,但是,使用數組存儲對象具有一定的弊端, 因爲我們在實際開發中,存儲的數據的類型是多種多樣的,於是,就出現了“集合”,集合同樣也是用來存儲多個數據的。數組的缺點是一旦聲明之後,長度就不可變了;同時,聲明數組時的數據類型也決定了該數組存儲的數據的類型;並且,數組存儲的數據是有序的、可重複的,特點單一。 但是集合提高了數據存儲的靈活性,Java 集合不僅可以用來存儲不同類型不同數量的對象,還可以保存具有映射關係的數據。

16.如何恰當的選用集合?

主要根據集合的特點來選用,假如我們需要根據鍵值獲取到元素值時就選用Map 接口下的集合,需要排序時選擇 TreeMap ,不需要排序時就選擇 HashMap ,需要保證線程安全就先用ConcurrentHashMap 。當我們只需要存放元素值時,就選擇實現 Collection 接口的集合,需要保證元素唯一時選擇實現Set 接口的集合比如 TreeSet 或 HashSet ,不需要就選擇實現 List 接口的比如 ArrayList或 LinkedList ,然後再根據實現這些接口的集合的特點來選用。

17.有沒女朋友,家住在哪裏?

HR問你這個,主要是考查是否上班太遠了,浪費時間,且容易換⼯作。個人建議,實話實說。當然如果擔心因爲家太遠,導致與offer失之交臂(可能性比較小),那麼可以考慮把距離說小一點。

特別提醒:HashMap和ArrayList是集合框架的重點,也是面試的高頻考點,一般問的都比較深。這兩塊內容我會在後續兩天單獨抽出來寫。

每天提升一點點,讓你的面試信心滿滿!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章