Java集合總結【面試題+腦圖】,將知識點一網打盡!

前言

聲明,本文用的是jdk1.8

花了一個星期,把Java容器核心的知識過了一遍,感受集合已經無所畏懼了!!(哈哈哈....),如今來總結一下吧~~java

回顧目錄:面試

Java容器可分爲兩大類:數組

  • Collection安全

    • List微信

      • ArrayList
      • LinkedList
      • Vector(瞭解,已過期)
    • Set多線程

      • HashSet併發

        • LinkedHashSet
      • TreeSet
  • Mapapp

    • HashMap框架

      • LinkedHashMap
    • TreeMap
    • ConcurrentHashMap
    • Hashtable(瞭解,,已過期)

着重標出的那些就是咱們用得最多的容器。工具

其實,我也不知道要怎麼總結好,由於以前寫每一篇的時候都總結過了。如今又把他們從新羅列出來好像有點水,因此,我決定去回答一些Java容器的面試題!

固然了,個人答案未必就是正確的。若是有錯誤的地方你們多多包含,但願不吝在評論區留言指正~~

1、ArrayList和Vector的區別

共同點:

  • 這兩個類都實現了List接口,它們都是有序的集合(存儲有序),底層是數組。咱們能夠按位置索引號取出某個元素,容許元素重複和爲null

區別:

  • 同步性:

    • ArrayList是非同步的
    • Vector是同步的
    • 即使須要同步的時候,咱們可使用Collections工具類來構建出同步的ArrayList而不用Vector
  • 擴容大小:

    • Vector增加原來的一倍,ArrayList增加原來的0.5倍

2、HashMap和Hashtable的區別

共同點:

  • 從存儲結構和實現來說基本上都是相同的,都是實現Map接口~

區別:

  • 同步性:

  • 是否容許爲null:

    • HashMap容許爲null
    • Hashtable不容許爲null
  • contains方法

    • 這知識點是在牛客網刷到的,沒想到這種題還會有(我不太喜歡)....
    • Hashtable有contains方法
    • HashMap把Hashtable的contains方法去掉了,改爲了containsValue和containsKey
  • 繼承不一樣:

    • HashMap<K,V> extends AbstractMap<K,V>
    • public class Hashtable<K,V> extends Dictionary<K,V>

3、List和Map的區別

共同點:

  • 都是Java經常使用的容器,都是接口(ps:寫出來感受好像和沒寫同樣.....)

不一樣點:

  • 存儲結構不一樣

    • List是存儲單列的集合
    • Map存儲的是key-value鍵值對的集合
  • 元素是否可重複

    • List容許元素重複
    • Map不容許key重複
  • 是否有序

    • List集合是有序的(存儲有序)
    • Map集合是無序的(存儲無序)

4、Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==仍是equals()?

咱們知道Set集合實際大都使用的是Map集合的put方法來添加元素

以HashSet爲例,HashSet裏的元素不能重複,在源碼(HashMap)是這樣體現的:

// 1. 若是key 相等  
    if (p.hash == hash &&
        ((k = p.key) == key || (key != null && key.equals(k))))
        e = p;
    // 2. 修改對應的value
       if (e != null) { // existing mapping for key
            V oldValue = e.value;
            if (!onlyIfAbsent || oldValue == null)
                e.value = value;
            afterNodeAccess(e);
            return oldValue;
       }

添加元素的時候,若是key(也對應的Set集合的元素)相等,那麼則修改value值。而在Set集合中,value值僅僅是一個Object對象罷了(該對象對Set自己而言是無用的)。

也就是說:Set集合若是添加的元素相同時,是根本沒有插入的(僅修改了一個無用的value值)!從源碼(HashMap)中也看出來,==和equals()方法都有使用

5、Collection和Collections的區別

  1. Collection是集合的上級接口,繼承它的有Set和List接口
  2. Collections是集合的工具類,提供了一系列的靜態方法對集合的搜索、查找、同步等操做

6、說出ArrayList,LinkedList的存儲性能和特性

ArrayList的底層是數組,LinkedList的底層是雙向鏈表。

  • ArrayList它支持以角標位置進行索引出對應的元素(隨機訪問),而LinkedList則須要遍歷整個鏈表來獲取對應的元素。所以通常來講ArrayList的訪問速度是要比LinkedList要快的
  • ArrayList因爲是數組,對於刪除和修改而言消耗是比較大(複製和移動數組實現),LinkedList是雙向鏈表刪除和修改只須要修改對應的指針便可,消耗是很小的。所以通常來講LinkedList的增刪速度是要比ArrayList要快的

6.1擴展:

ArrayList的增刪未必就是比LinkedList要慢。

  • 若是增刪都是在末尾來操做【每次調用的都是remove()和add()】,此時ArrayList就不須要移動和複製數組來進行操做了。若是數據量有百萬級的時,速度是會比LinkedList要快的。(我測試過)
  • 若是刪除操做的位置是在中間。因爲LinkedList的消耗主要是在遍歷上,ArrayList的消耗主要是在移動和複製上(底層調用的是arraycopy()方法,是native方法)。

    • LinkedList的遍歷速度是要慢於ArrayList的複製移動速度的
    • 若是數據量有百萬級的時,仍是ArrayList要快。(我測試過)

7、Enumeration和Iterator接口的區別

這個我在前面的文章中也沒有詳細去講它們,只是大概知道的是:Iterator替代了Enumeration,Enumeration是一箇舊的迭代器了。

與Enumeration相比,Iterator更加安全,由於當一個集合正在被遍歷的時候,它會阻止其它線程去修改集合

區別有三點:

  • Iterator的方法名比Enumeration更科學
  • Iterator有fail-fast機制,比Enumeration更安全
  • Iterator可以刪除元素,Enumeration並不能刪除元素

8、ListIterator有什麼特色

  • ListIterator繼承了Iterator接口,它用於遍歷List集合的元素
  • ListIterator能夠實現雙向遍歷,添加元素,設置元素

看一下源碼的方法就知道了:

9、併發集合類是什麼?

Java1.5併發包(java.util.concurrent)包含線程安全集合類,容許在迭代時修改集合

  • 迭代器被設計爲fail-fast的,會拋出ConcurrentModificationException。
  • 一部分類爲:

    • CopyOnWriteArrayList
    • ConcurrentHashMap
    • CopyOnWriteArraySet

10、Java中HashMap的key值要是爲類對象則該類須要知足什麼條件?

須要同時重寫該類的hashCode()方法和它的equals()方法

  • 從源碼能夠得知,在插入元素的時候是先算出該對象的hashCode。若是hashcode相等話的。那麼代表該對象是存儲在同一個位置上的。
  • 若是調用equals()方法,兩個key相同,則替換元素
  • 若是調用equals()方法,兩個key不相同,則說明該hashCode僅僅是碰巧相同,此時是散列衝突,將新增的元素放在桶子上

通常來講,咱們會認爲:只要兩個對象的成員變量的值是相等的,那麼咱們就認爲這兩個對象是相等的!由於,Object底層比較的是兩個對象的地址,而對咱們開發來講這樣的意義並不大~這也就爲何咱們要重寫equals()方法

重寫了equals()方法,就要重寫hashCode()的方法。由於equals()認定了這兩個對象相同,而同一個對象調用hashCode()方法時,是應該返回相同的值的!

11、與Java集合框架相關的有哪些最好的實踐

  1. 根據須要肯定集合的類型。若是是單列的集合,咱們考慮用Collection下的子接口ArrayList和Set。若是是映射,咱們就考慮使用Map~
  2. 肯定完咱們的集合類型,咱們接下來肯定使用該集合類型下的哪一個子類~我認爲能夠簡單分紅幾個步驟:

    • 是否須要同步

      • 去找線程安全的集合類使用
    • 迭代時是否須要有序(插入順序有序)

      • 去找Linked雙向列表結構的
    • 是否須要排序(天然順序或者手動排序)

      • 去找Tree紅黑樹類型的(JDK1.8)
  3. 估算存放集合的數據量有多大,不管是List仍是Map,它們實現動態增加,都是有性能消耗的。在初始集合的時候給出一個合理的容量會減小動態增加時的消耗~
  4. 使用泛型,避免在運行時出現ClassCastException
  5. 儘量使用Collections工具類,或者獲取只讀、同步或空的集合,而非編寫本身的實現。它將會提供代碼重用性,它有着更好的穩定性和可維護性

12、ArrayList集合加入1萬條數據,應該怎麼提升效率

ArrayList的默認初始容量爲10,要插入大量數據的時候須要不斷擴容,而擴容是很是影響性能的。所以,如今明確了10萬條數據了,咱們能夠直接在初始化的時候就設置ArrayList的容量

這樣就能夠提升效率了~

十3、總結

2018年4月15日17:14:03,上面找了一些面試題答了一下,感受不夠過癮呀。不少我以爲比較重要的知識點我都沒有找到對應的面試題(可能我搜索的能力太水了?)。

將這篇文章做爲集合的總結篇,但以爲沒什麼好寫就回答一些面試題去了,找了一會面試題又以爲不夠系統。而這篇總結我又不想複製前面的章節總結到這裏來。因而我決定畫一個腦圖來結束這篇文章

2018年4月15日19:31:33 畫完啦!!!!!

須要更多腦圖的同窗可關注公衆號:Java3y,回覆【腦圖】便可~

若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠 關注微信公衆號:Java3y。爲了你們方便,剛新建了一下 qq羣:742919422,你們也能夠去交流交流。謝謝支持了!但願能多介紹給其餘有須要的朋友

文章的目錄導航https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang

目前初步打算寫多線程,大家以爲怎麼樣呢?能夠在評論區留言~

相關文章
相關標籤/搜索