Java集合類知識整理

CHEN_DOUDOU發表於2017-10-12

一、元素是否有序?

  • 有序:List、TreeSet、TreeMap
  • 無序:Set(AbstractSet、HashSet)、Map(AbstractMap、HashMap)
  • 原因:List最常用的實現類是ArrayList和LinkedList,前者以一種類似陣列的形式進行儲存,後者是以連結串列的形式進行儲存,都是有序的。對於TreeSet和TreeMap,顧名思義是採用樹的形式進行儲存的,所以也是有序的。而Set的其它實現類則是無序的,就像一個口袋一樣,它無法記住我們放入元素的順序,所以是無序的。Map也是一樣,除了使用樹形儲存的實現類外,其它實現類中放入的資料也是無序。

二、是否可以重複?

  • 能:List、Map(這裡的重複指的是value而不是key,key必須唯一)
  • 否:Set
  • 原因:前面提到因為List常用的兩個類是採用連結串列或者陣列的形式進行儲存的,是有序的,可以區分相同元素,所以能加入相同的元素。而Map可重複指的是value可重複,但是必須保證key是唯一的,才能保證正確的取出資料。對於Set,如果放入重複元素,怎麼知道取出的是哪一個?所以不執行放入重複的元素。

二、是否可以加入null?

對各個集合能否放入null,並不能統一的用能和否進行解釋。
對於Map集合而言:
(1)TreeMap:允許加入的value為null但是key一定不可以是null,否則會引發NullPointerException

Map set = new TreeMap() ;
set.put(null, "a") ;

結果:

Exception in thread "main" java.lang.NullPointerException
        at java.util.TreeMap.compare(Unknown Source)
        at java.util.TreeMap.put(Unknown Source)
        at review.test.collection.TestNull.main(TestNull.java:11)

有的地方說TreeMap只有在元素數量大於1的時候才會呼叫Comparator比較器,所以TreeMap在新增的第一個元素key為null的時候不會引發NullPointerException,但是通過實驗證明,即使將null作為第一個加入元素的key值,亦或者只加入一個null-value鍵值對,結果都是會引發NullPointerException的,所以得出的結果是TreeMap所有鍵值對的key都不可以為null。
(2)HashMap:允許新增null-null鍵值對,但是要求只能加入一個key為null的鍵值對,如果加入多個key為null的鍵值對,則後加入的鍵值對會覆蓋先加入的鍵值對,保持集合中最終只有一個key為null的鍵值對。但是可以多個鍵值對的value都為null。

Map set = new HashMap() ;
set.put(null, null) ;
set.put(null, 1) ;
set.put(2 , null) ;
set.put(3, null) ;

除錯結果:
這裡寫圖片描述

並且在對存在key為null的HashMap進行value的取出操作時,不能使用get方式,否則一樣會引發NullPointerException。只能通過遍歷去獲取

Set<Map.Entry<Integer,Integer>> s = set.entrySet();
for(Map<Integer,Integer> entry : s){
    System.out.println(entry);
} 

對於List而言:
ArrayList和LinkedList都是有序的,可以加入多個null值,並且可以正確輸出。

List list = new ArrayList() ;
list.add(null) ;
list.add(null) ;
list.add(1) ;
for(Object obj:list) {
    System.out.println(obj+" ");
}

除錯及輸出結果:
這裡寫圖片描述

對於Set而言:
(1)HashSet:允許新增null值,但因為是無序的,所以集合中實際最終只有一個null值,並且新增的null值將會第一個被輸出。這裡涉及到hash對null的處理實現,可參考: HashMap中插入null key的過程分析

Set set = new HashSet() ;
set.add(2) ;
set.add(null) ;
set.add(null) ;
set.add(1) ;
for(Object obj:set) {
    System.out.println(obj+" ");
}

除錯結果:
這裡寫圖片描述

(2)TreeSet:和TreeMap一樣,TreeSet對新增null值非常敏感,TreeSet完全不允許新增null,只要新增null值就會引發NullPointerException。

相關文章