【面試題】Java集合部分面試題


集合與數組?

數組:(可以存儲基本數據類型)是用來存儲對象的一種容器,但是數組的長度固定,不適合在對象數量未知的情況下使用

集合:(只能存儲對象,對象類型可以不一樣)集合的長度可變,可在多數情況下使用

 

Collection接口是集合類的根接口,Java中沒有提供這個接口的直接的實現類,但是卻讓其被繼承產生了兩個接口

Set:不包含重復的元素

List:有序的集合,可以包含重復的元素,提供了按索引訪問的方式

 

Map是Java.util包中的另一個接口,它和Collection接口沒有關系,是相互獨立的,但是都屬於集合的一部分,Map包含了Key – Value對,Map不能包含重復的Key,但是可以包含相同的Value。

 

Iterator,所有的集合類都實現了Iterator接口,這是一個用於遍歷集合中元素的接口,主要包含以下三種方法:

  1. hasnext():是否還有下一個元素
  2. next():返回下一個元素
  3. remove():刪除當前元素

 

幾種重要的接口和類簡介

  1. List(有序,可重復)

List里存放的對象是有序的,同時也是可以重復的,List關注的是索引,擁有一系列和索引相關的方法,查詢速度快,因為往List集合里插入或刪除數據時,會伴隨着后面數據的移動,所以插入數據速度很慢

  1. Set(無序,不能重復)

Set里存放的對象是無序的,不能重復的,集合中的對象不按特定的方式排序,只是簡單的把對象放入集合中。

  1. Map(鍵值對,鍵唯一,值不唯一)

Map集合中存儲的時鍵值對,鍵不能重復,值可以重復,根據鍵得到值,對map集合遍歷時先得到鍵的Set集合,對Set集合遍歷,得到相對應的值。

 

遍歷

在集合中提供了以下四種的常見的輸出方式

  1. Iterator:迭代輸出,是使用最多的輸出方式
  2. ListIterator:是Iterator的子接口,用於專門輸出List中的內容‘
  3. Foreach輸出:JDK1.5之后提出的新功能。可以輸出數組或集合
  4. For循環

 

ArrayList和LinkedList

ArrayList和LinkedList在用法上沒有區別,但是在功能上還是有區別的

LinkedList經常用在增刪操作較多而查詢操作很少的情況

Arraylist經常用在查詢較多,增刪操作較少的情況下。

 

Map集合

實現類:HashMap,HashTable,LinkedHashMap和TreeMap

 

HashMap

HashMap是最常用的Map它根據鍵的HashCode來存儲元素,根據鍵可以直接獲取它的值,具有很快的訪問速度。

遍歷時,取得數據的順序是完全隨機的,因為鍵對象不可以重復,所以HashMap最多只允許一條記錄的鍵為Null,允許多條記錄的值為Null,是非同步的

  

HashTable

HashTable與HashMap類似,是HashMap的線程安全版,它支持線程的同步,任一時刻只有一個線程能寫HashTable

因此也導致了HashTable在寫入時會比較慢,它集成子Dictionary類,不同的時它不允許記錄的鍵或值為null,同時效率較低

 

LinkedHashMap

LinkedHashMap保存來記錄的插入順序,在用Iteraor遍歷LinkedHashMap時,先得到的記錄肯定是先插入的,在遍歷的時候會比HashMap慢,有HashMap的全部特性

 

TreeMap

TreeMap實現SortMap接口,能夠把它保存的記錄根據鍵順序,默認是按鍵值的升序排序(自然順序),可以指定排序的比較器,當用Iterator遍歷ThreeMap時,得到的記錄是排過序的,不允許Key值為空,非同步

 

Map的遍歷

  1. KeySet();

將Map中所有的鍵存入到set集合中因為set幾倍迭代器,所以可以迭代取出所有的鍵,再根據get方法獲取每一個鍵對應的值,KeySet()迭代后只能通過get()取Key。

 

  1. ebtrySet()

Set<Map.Entry<K,V>>entrySet()返回此映射值中包含的映射關系的Set視圖(一個關系就是一個兼職對)就是把(Key-value)作為一個整體一對一的存放到Set集合中,Map.Entry表示映射關系

EntrySet()迭代后可以e.getKey() ,e.getValue() 兩種方法來去Key和Value,返回的值是Entry接口

推薦使用entrySet()方法,效率較高

對於KeySet其實是遍歷了2次,一次轉為iterator,一次就是從HashMap中取出Key所對應的Value

Entryset()只是遍歷了第一次,它把Key和Value都放到了entry中,所以快了。兩種遍歷的遍歷時間相差還是很明顯的。

 

ArrayList和LinkedList的區別

  1. ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構
  2. 對於隨機訪問get和set,ArrayList性能優於LinkedList,因為LinkedList要移動指針
  3. 對於新增和刪除操作,add和remove,linkedList比較占優勢,因為ArrayList要移動數據,這一點要看實際情況的,若值對單條數據插入或刪除,ArrayList的速度反而要優於LinkedList,但是要是批量隨機的插入刪除數據,LinkedList的書讀大大優於ArrayList,因為ArrayList每插入一條數據,要移動插入點及之后的所有數據

 

HashMap與TreeMap

  1. HashMap通過hashcode對其內容進行快速查找,而TreeMap中所有的元素都保持着某種固定的順序,如果你需要得到一個有許多結果你就應該去使用TreeMap(HashMap中元素排列順序是不固定的)
  2. 在Map中插入,刪除和定位元素,HashMap是最好的選擇,但如果要按照自然順序或自定義順序遍歷鍵,那么TreeMap會更好,使用HashMap要求添加的鍵類明確定義了hashCode()和equals()的實現

連個Map中的元素一樣,但順序不一樣,導致hashCode()不一樣

同樣做測試:

在HashMap中,同樣的值的map。順序不同,equals時,false

在TreeMap中,同樣的值的map,順序不同,equals時,true,說明TreeMap在equals()時是整理了順序的。

 

HashTable與HashMap的區別

  1. 同步性:HashTable是線程安全的,也就是說是同步的,而HashMap是線程不安全的,不是同步的
  2. HashMap允許存在一個為null 的key,多個為null的元素
  3. HashTable的Key和Value都不允許為null

 

Java集合框架是什么,說出一些集合框架的優點

每種編程語言中都有集合,最初的Java版本中包含擊中集合類:Vector,Stack,HashTable和Array,隨着集合的廣泛使用,Java1.2提出囊括所有集合接口,實現和算法的集合框架,在保證線程安全的情況下,使用泛型和並發集合類,Java已經經歷了很久,它還包括在Java並發包中,阻塞接口以及他們的實現。集合框架的部分優點如下

  1. 使用核心集合類降低開發成本,而非實現我們自己的集合類
  2. 通過使用經過嚴格測試的結合框架,代碼質量會得到提高
  3. 通過使用JDK附帶的集合類,可以降低代碼維護成本
  4. 復用性和可操作性

 

集合框架中的泛型有什么優點

Java1.5中引入了泛型,所有的集合接口和實現都大量的使用它,泛型允許我們為集合提供一個可以容納的對象類型,因此,如果你想添加其他類型的任何元素,它都會在編譯時報錯,避免了再運行時出現錯誤,因此你將會在編譯時得到報錯信息,泛型也是的代碼整潔,我們不需要使用顯式轉換和instanceOf操作符。

 

Java集合框架的基礎接口有哪些

Collection為集合層級的根接口,一個集合代表一組對象,這些對象即為它的元素,Java不提供這個接口的任何直接實現。

Set是一個包含不重復元素的集合,這個接口對數字集合抽象進行建模,被用來代表集合,就如一副牌一樣。

List是一個有序集合,可以包含重復元素,你可以通過它的索引來訪問任何元素,List更像長度動態變換的數組

Map是一個將Key映射到Value的對象,一個Map不能包含重復的Key,每個Key最多只能映射一個Value

 

為何Map接口不繼承Collection接口

盡管Map接口和它的實現也是集合框架的一部分,但Map不是集合,集合也不是Map,因此Map繼承Collection毫無意義,反之亦然

 

Iterator是什么?

Iterator接口提供遍歷任何Collection的接口,我們可以從一個Collection中使用迭代器的方法來獲取迭代器實例,迭代器允許調用者在迭代過程中移出元素

 

HashMap是如何工作的

HashMap使用哈希算法,在put和get方法中,他是用hashCode()和equals()方法,當我們通過傳遞Key-value對,調用put方法的時候,HashMap使用key hashCode()和哈希算法,來找出存儲Key-value對的索引Entry存儲在LinkedList中,如果存在Entry,它使用equals()方法來檢查傳遞的Key是否已經存在如果存在,它會覆蓋Value,如果不存在,它會創建一個新的entry然后保存,讓我們通過傳遞key調用get()方法是,它再次使用hashCode()來找到數組中的索引,然后使用equals()方法找出正確的Entry,然后返回它的值。

 

HashCode()和equals()方法有和重要性

HashMap使用Key對象的HashCode()和equals()方法去決定Key-Value對的索引,當我們試着從HashMap中獲取值的時候,這些方法也會被用到,如果這些方法沒有正確的實現,這種情況下,兩個不同Key也會產生相同的HashCode()和equals()輸出

HashMap將會認為他們是相同的,然后覆蓋他們,而非把他們存儲到不同的地方,同樣的所有不允許存儲重復數據的集合類都使用HashCode()和equals()去查找重復,所以他們非常重要

Equals()和hashCode()的實現應該遵循以下規則:

  1. 如果o1.equals(o2),那么o1,hashCode()==o2.hashCode()總是為true 的
  2. 如果o1.hashCode()==02.hashCode(),並不意味着o1.equals(o2)會為true。

簡單來講:

HashCode相同,不一定對象相同

對象相同,HashCode一定相同。

 

能否使用任何類作為Map的Key

可以!

使用之前要考慮幾點

  1. 如果類重寫了equals()方法,它也應該重寫HashCode()方法
  2. 類的所有實例要遵循與equals()和HashCode()相關的規則
  3. 如果一個類沒有使用equals(),你不應該在HashCode()中使用它

 

HashMap和HashTable有何不同

  1. HashMap允許key和value為空,而HashTable不允許
  2. HashTable是同步的是安全的,而HashMap不是,所以HashMap適合單線程環境,HashTable適合多線程環境

 

如何決定選用HashMap還是ThreeMap

對於在Map中插入,刪除和定位元素這類的操作,HashMap是孔的選擇,然而,假如你需要對一個有序的Key集合進行遍歷,ThreeMap是更高的選擇,基於你的Collection的大小,也許想HashMap中添加元素會更快,將Map換位TheeMap進行有序Key的遍歷

 

ArrayList 和 Vertor有何異同

ArrayList和Vector在很多時候都很類似

  1. 兩者都是基於索引的,內部又一個數組支持
  2. 兩者維護插入的順序,我們可以根據插入順序來獲取元素
  3. ArrayList和Vector兩者允許null值,也可以使用索引值對元素進行隨機訪問

不同點

  1. Vector是同步的是安全的,而ArrayList不是
  2. ArrayList比Vector快
  3. ArrayList更加的通用

 

Array和ArrayList有何區別?什么時候更適合用Array?

  1. Array可以容納基本類型和對象,而ArrayList只能容納對象
  2. Array是指定大小的,而ArrayList大小是固定的
  3. Array沒有ArrayList那么多的功能,比如addAll,rumoveAll和Iterator等
  4. 如果列表的大小已經指定,大部分的情啊狂還是存儲和遍歷它們
  5. 如果要使用多維數組,使用Array[][]要比List<List<>>更容易

 

ArrayList和LinkedList有何區別?

ArrayList和Linked兩者都實現了List接口,但是它們之間有些不同

  1. ArrrayList是時間了基於動態數組的數據結構,ListedList是基於鏈表的數據結構
  2. 對於隨機訪問get()和set()ArrayList速度優於LinkedList,因為LinkedList要移動指針
  3. 對於新增和刪除操作add和remove,LinkedList比較占優勢,因為ArrayList要移動數據,
  4. 兩者都是現成不安全的,允許重復的。

 

哪些集合提供對元素的隨機訪問?

ArrayList,HashMap,TreeMap和HashTable都提供對元素的隨機訪問。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM