Java面試集錦:集合思惟導圖與30道集合面試題

Java面試集錦:集合思惟導圖與30道集合面試題.png

Collection集合.png

List集合.png
ArrayListandVectorandLinkedList.png

hashmapandtreemapandhashtable.png

map.png

set集合.png

其餘.png

Java集合框架爲Java編程語言的基礎,也是Java面試中很重要的一個知識點。這裏,我列出了一些關於Java集合的重要問題和答案。java

1.Java集合框架是什麼?說出一些集合框架的優勢?

每種編程語言中都有集合,最初的Java版本包含幾種集合類:VectorStackHashTableArraygit

隨着集合的普遍使用,Java1.2提出了囊括全部集合接口、實現和算法的集合框架。在保證線程安全的狀況下使用泛型和併發集合類,Java已經經歷了好久。它還包括在Java併發包中,阻塞接口以及它們的實現。github

集合框架的部分優勢以下:面試

(1)使用核心集合類下降開發成本,而非實現咱們本身的集合類。算法

(2)隨着使用通過嚴格測試的集合框架類,代碼質量會獲得提升。編程

(3)經過使用JDK附帶的集合類,能夠下降代碼維護成本。設計模式

(4)複用性和可操做性。數組

2.集合框架中的泛型有什麼優勢?

1.Java1.5引入了泛型,全部的集合接口和實現都大量地使用它。安全

2.泛型容許咱們爲集合提供一個能夠容納的對象類型,所以,若是你添加其它類型的任何元素,它會在編譯時報錯。微信

3.這避免了在運行時出現ClassCastException,由於你將會在編譯時獲得報錯信息。

4.泛型也使得代碼整潔,咱們不須要使用顯式轉換和instanceOf操做符。

5.它也給運行時帶來好處,由於不會產生類型檢查的字節碼指令。

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

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

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

List是一個有序集合,能夠包含重複元素。你能夠經過它的索引來訪問任何元素。List更像長度動態變換的數組。

Map是一個將key映射到value的對象.一個Map不能包含重複的key:每一個key最多隻能映射一個value。

一些其它的接口有Queue、Dequeue、SortedSet、SortedMap和ListIterator。

4.爲什麼Map接口不繼承Collection接口?

儘管Map接口和它的實現也是集合框架的一部分,但Map不是集合,集合也不是Map。所以,Map繼承Collection毫無心義,反之亦然。

若是Map繼承Collection接口,那麼元素去哪兒?Map包含key-value對,它提供抽取key或value列表集合的方法,可是它不適合「一組對象」規範。

5.ArrayList和Vector有何異同點?

ArrayList和Vector在不少時候都很相似。

(1)二者都是基於索引的,內部由一個數組支持。

(2)二者維護插入的順序,咱們能夠根據插入順序來獲取元素。

(3)ArrayList和Vector的迭代器實現都是fail-fast的。

(4)ArrayList和Vector二者容許null值,也可使用索引值對元素進行隨機訪問。

如下是ArrayList和Vector的不一樣點。

(1)Vector是同步的,而ArrayList不是。然而,若是你尋求在迭代的時候對列表進行改變,你應該使用CopyOnWriteArrayList。

(2)ArrayList比Vector快,它由於有同步,不會過載。

(3)ArrayList更加通用,由於咱們可使用Collections工具類輕易地獲取同步列表和只讀列表。

6.Array和ArrayList有何區別?何時更適合用Array?

Array能夠容納基本類型和對象,而ArrayList只能容納對象。

Array是指定大小的,而ArrayList大小是固定的。

Array沒有提供ArrayList那麼多功能,好比addAll、removeAll和iterator等。儘管ArrayList明顯是更好的選擇,但也有些時候Array比較好用。

(1)若是列表的大小已經指定,大部分狀況下是存儲和遍歷它們。

(2)對於遍歷基本數據類型,儘管Collections使用自動裝箱來減輕編碼任務,在指定大小的基本類型的列表上工做也會變得很慢。

(3)若是你要使用多維數組,使用[][]比List>更容易。

7.ArrayList和LinkedList有何區別?

ArrayList和LinkedList二者都實現了List接口,可是它們之間有些不一樣。

1)ArrayList是由Array所支持的基於一個索引的數據結構,因此它提供對元素的隨機訪問,複雜度爲O(1),但LinkedList存儲一系列的節點數據,每一個節點都與前一個和下一個節點相鏈接。因此,儘管有使用索引獲取元素的方法,內部實現是從起始點開始遍歷,遍歷到索引的節點而後返回元素,時間複雜度爲O(n),比ArrayList要慢。 2)與ArrayList相比,在LinkedList中插入、添加和刪除一個元素會更快,由於在一個元素被插入到中間的時候,不會涉及改變數組的大小,或更新索引。

3)LinkedList比ArrayList消耗更多的內存,由於LinkedList中的每一個節點存儲了先後節點的引用。

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

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

9.哪些集合類是線程安全的?

Vector、HashTable、Properties和Stack是同步類,因此它們是線程安全的,能夠在多線程環境下使用。Java1.5併發API包括一些集合類,容許迭代時修改,由於它們都工做在集合的克隆上,因此它們在多線程環境中是安全的。點擊這裏一文搞懂問什麼線程不安全。

10.併發集合類是什麼?

Java1.5併發包(java.util.concurrent)包含線程安全集合類,容許在迭代時修改集合。迭代器被設計爲fail-fast的,會拋出ConcurrentModificationException。一部分類爲:CopyOnWriteArrayList、 ConcurrentHashMap、CopyOnWriteArraySet。

11.隊列和棧是什麼,列出它們的區別?

棧和隊列二者都被用來預存儲數據。java.util.Queue是一個接口,它的實現類在Java併發包中。隊列容許先進先出(FIFO)檢索元素,但並不是老是這樣。Deque接口容許從兩端檢索元素。棧與隊列很類似,但它容許對元素進行後進先出(LIFO)進行檢索。Stack是一個擴展自Vector的類,而Queue是一個接口。

12.Collections類是什麼?

Java.util.Collections是一個工具類僅包含靜態方法,它們操做或返回集合。它包含操做集合的多態算法,返回一個由指定集合支持的新集合和其它一些內容。這個類包含集合框架算法的方法,好比折半搜索、排序、混編和逆序等。

13.Comparable和Comparator接口有何區別?

Comparable和Comparator接口被用來對對象集合或者數組進行排序。Comparable接口被用來提供對象的天然排序,咱們可使用它來提供基於單個邏輯的排序。Comparator接口被用來提供不一樣的排序算法,咱們能夠選擇須要使用的Comparator來對給定的對象集合進行排序。

14.Iterator是什麼?

Iterator接口提供遍歷任何Collection的接口。咱們能夠從一個Collection中使用迭代器方法來獲取迭代器實例。迭代器取代了Java集合框架中的Enumeration。迭代器容許調用者在迭代過程當中移除元素。

15.Enumeration和Iterator接口的區別?

Enumeration的速度是Iterator的兩倍,也使用更少的內存。Enumeration是很是基礎的,也知足了基礎的須要。可是,與Enumeration相比,Iterator更加安全,由於當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合。迭代器取代了Java集合框架中的Enumeration。迭代器容許調用者從集合中移除元素,而Enumeration不能作到。爲了使它的功能更加清晰,迭代器方法名已經通過改善。

16.Iterater和ListIterator之間有什麼區別?

(1)咱們可使用Iterator來遍歷Set和List集合,而ListIterator只能遍歷List。 (2)Iterator只能夠向前遍歷,而LIstIterator能夠雙向遍歷。 (3)ListIterator從Iterator接口繼承,而後添加了一些額外的功能,好比添加一個元素、替換一個元素、獲取前面或後面元素的索引位置。

17.經過迭代器fail-fast屬性,你明白了什麼?

每次咱們嘗試獲取下一個元素的時候,Iterator fail-fast屬性檢查當前集合結構裏的任何改動。若是發現任何改動,它拋出ConcurrentModificationException。Collection中全部Iterator的實現都是按fail-fast來設計的(ConcurrentHashMap和CopyOnWriteArrayList這類併發集合類除外)。

18.fail-fast與fail-safe有什麼區別?

Iterator的fail-fast屬性與當前的集合共同起做用,所以它不會受到集合中任何改動的影響。Java.util包中的全部集合類都被設計爲fail-fast的,而java.util.concurrent中的集合類都爲fail-safe的。Fall—fast迭代器拋出ConcurrentModificationException,fall—safe迭代器從不拋出ConcurrentModificationException。

19.在迭代一個集合的時候,如何避免?

ConcurrentModificationException?在遍歷一個集合的時候咱們可使用併發集合類來避免ConcurrentModificationException,好比使用CopyOnWriteArrayList,而不是ArrayList。

20.HashMap和HashTable有何不一樣?

(1)HashMap容許key和value爲null,而HashTable不容許。 (2)HashTable是同步的,而HashMap不是。因此HashMap適合單線程環境,HashTable適合多線程環境。 (3)在Java1.4中引入了LinkedHashMap,HashMap的一個子類,假如你想要遍歷順序,你很容易從HashMap轉向LinkedHashMap,可是HashTable不是這樣的,它的順序是不可預知的。 (4)HashMap提供對key的Set進行遍歷,所以它是fail-fast的,但HashTable提供對key的Enumeration進行遍歷,它不支持fail-fast。 (5)HashTable被認爲是個遺留的類,若是你尋求在迭代的時候修改Map,你應該使用CocurrentHashMap。

21.如何決定選用HashMap仍是TreeMap?

對於在Map中插入、刪除和定位元素這類操做,HashMap是最好的選擇。然而,假如你須要對一個有序的key集合進行遍歷,TreeMap是更好的選擇。基於你的collection的大小,也許向HashMap中添加元素會更快,將map換爲TreeMap進行有序key的遍歷。

22.咱們如何對一組對象進行排序?

若是咱們須要對一個對象數組進行排序,咱們可使用Arrays.sort()方法。若是咱們須要排序一個對象列表,咱們可使用Collection.sort()方法。兩個類都有用於天然排序(使用Comparable)或基於標準的排序(使用Comparator)的重載方法sort()。Collections內部使用數組排序方法,全部它們二者都有相同的性能,只是Collections須要花時間將列表轉換爲數組。

23.有哪些關於 Java 集合框架的最佳實踐?

  • 基於應用的需求來選擇使用正確類型的集合,這對性能來講是很是重要的。例如,若是元素的大小是固定的,而且知道優先級,咱們將會使用一個 Array ,而不是 ArrayList
  • 一些集合類容許咱們指定他們的初始容量。所以,若是咱們知道存儲數據的大概數值,就能夠避免重散列或者大小的調整。
  • 老是使用泛型來保證類型安全,可靠性和健壯性。同時,使用泛型還能夠避免運行時的 ClassCastException 異常。
  • Map 中使用 JDK 提供的不可變類做爲一個 key,這樣能夠避免 hashcode 的實現和咱們自定義類的 equals 方法。
  • 應該依照接口而不是實現來編程。
  • 返回零長度的集合或者數組,而不是返回一個 null ,這樣能夠防止底層集合是空的。

24. List 和 Set 區別?

ListSet 都是繼承自 Collection 接口。

  • List 特色:元素有放入順序,元素可重複。
  • Set 特色:元素無放入順序,元素不可重複,重複元素會覆蓋掉。

注意:元素雖然無放入順序,可是元素在 Set 中的位置是有該元素的 hashcode 決定的,其位置實際上是固定的。

另外 List 支持 for 循環,也就是經過下標來遍歷,也能夠用迭代器,可是 Set只能用迭代,由於他無序,沒法用下標來取得想要的值。

SetList 對比:

  • Set:檢索元素效率高,刪除和插入效率低,插入和刪除不會引發元素位置改變。
  • List:和數組相似,List 能夠動態增加,查找元素效率低,插入刪除元素效率,由於可能會引發其餘元素位置改變。

25. HashSet 和 TreeSet 的區別?

HashSet 是用一個hash 表來實現的,所以,它的元素是無序的。添加,刪除和 HashSet 包括的方法的持續時間複雜度是O(1)TreeSet 是用一個樹形結構實現的,所以,它是有序的。添加,刪除和 TreeSet 包含的方法的持續時間複雜度是 O(logn)

如何決定選用 HashMap 仍是 TreeMap

對於在Map中插入、刪除和定位元素這類操做,HashMap 是最好的選擇。 然而,假如你須要對一個有序的 key 集合進行遍歷, TreeMap 是更好的選擇。 基於你的 collection 的大小,也許向 HashMap 中添加元素會更快,再將 HashMap 換爲 TreeMap 進行有序 key 的遍歷。

26. HashMap 和 ConcurrentHashMap 的區別?

ConcurrentHashMap 是線程安全的 HashMap 的實現。主要區別以下:

一、ConcurrentHashMap 對整個桶數組進行了分割分段(Segment),而後在每個分段上都用 lock 鎖進行保護,相對 於Hashtable 的 syn 關鍵字鎖的粒度更精細了一些,併發性能更好。而 HashMap 沒有鎖機制,不是線程安全的。JDK8 以後,ConcurrentHashMap 啓用了一種全新的方式實現,利用 CAS 算法。 二、HashMap 的鍵值對容許有 null ,可是 ConCurrentHashMap 都不容許。

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

迭代器是一種設計模式,它是一個對象,它能夠遍歷並選擇序列中的對象,而開發人員不須要了解該序列的底層結構。迭代器一般被稱爲「輕量級」對象,由於建立它的代價小。Java中的Iterator功能比較簡單,而且只能單向移動:對已集合類中的任何一個實現類,均可以返回這樣一個Iterator對象。跟循環差很少。

好處是能夠適合用於任何一個類,並且java也對它進行了優化,比直接用index訪問快一點。迭代器是一種模式,它可使得對於序列類型的數據結構的遍歷行爲與被遍歷的對象分離,迭代器至關於有個指針,每次調用hasNext()方法若是返回值是true,說明有下一個元素,再執行next()方法得到該元素的值.

在迭代器Iteartor接口中,有如下3個方法: 1.hasNext() 該方法英語判斷集合對象是否還有下一個元素,若是已是最後一個元素則返回false 2.next() 把迭代器的指向移到下一個位置,同時,該方法返回下一個元素的引用 3.remove()  從迭代器指向的Collection中移除迭代器返回的最後一個元素,該操做使用的比較少。

28. 什麼是Java優先級隊列(Priority Queue)?

PriorityQueue是一個基於優先級堆的無界有序隊列,它的元素是按照天然順序(natural order)排序的。在建立的時候,咱們能夠給它提供一個負責給元素排序的比較器。PriorityQueue不容許null值,由於他們沒有天然順序,或者說他們沒有任何的相關聯的比較器。最後,PriorityQueue不是線程安全的,入隊和出隊的時間複雜度是O(log(n))。

29.你瞭解大O符號(big-O notation)麼?你能給出不一樣數據結構的例子麼?

大O:描述了當數據結構裏面的元素增長的時候,算法的規模或者是性能在最壞的場景下有多麼好。 大O符號也可用來描述其餘的行爲,好比:內存消耗。由於集合類其實是數據結構,咱們通常使用大O符號基於時間,內存和性能來選擇最好的實現。大O符號能夠對大量數據的性能給出一個很好的說明。

30.如何權衡是使用無序的數組仍是有序的數組?

有序數組最大的好處在於查找的時間複雜度是O(log n),而無序數組是O(n)。有序數組的缺點是插入操做的時間複雜度是O(n),由於值大的元素須要日後移動來給新元素騰位置。相反,無序數組的插入時間複雜度是常量O(1)。 因此,查找操做多的時候,使用有序;增刪操做多的使用無序的便可。

推薦

大廠筆試內容集合(內有詳細解析) 持續更新中....

ProcessOn是一個在線做圖工具的聚合平臺~

文末

歡迎關注我的微信公衆號:Coder編程 歡迎關注Coder編程公衆號,主要分享數據結構與算法、Java相關知識體系、框架知識及原理、Spring全家桶、微服務項目實戰、DevOps實踐之路、每日一篇互聯網大廠面試或筆試題以及PMP項目管理知識等。更多精彩內容正在路上~ 新建了一個qq羣:315211365,歡迎你們進羣交流一塊兒學習。謝謝了!也能夠介紹給身邊有須要的朋友。

文章收錄至 Github: github.com/CoderMerlin… Gitee: gitee.com/573059382/c… 歡迎關注並star~

微信公衆號
相關文章
相關標籤/搜索