HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMa

Map是最重要的數據結構。這篇文章中,我會帶大家看看HashMap, TreeMap, HashTable和LinkedHashMap的區別。 java

1. Map概覽

Java SE中有四種常見的Map實現——HashMap, TreeMap, Hashtable和LinkedHashMap。若是咱們使用一句話來分別歸納它們的特色,就是: git

  • HashMap就是一張hash表,鍵和值都沒有排序。
  • TreeMap以紅-黑樹結構爲基礎,鍵值按順序排列。
  • LinkedHashMap保存了插入時的順序。
  • Hashtable是同步的(而HashMap是不一樣步的)。因此若是在線程安全的環境下應該多使用HashMap,而不是Hashtable,由於Hashtable對同步有額外的開銷。
  1. HashMap

若是HashMap的鍵(key)是自定義的對象,那麼須要按規則定義它的equals()和hashCode()方法github

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
    publicString toString(){  
        returncolor +" dog";
    }
}
 
publicclassTestHashMap {
    publicstaticvoidmain(String[] args) {
        HashMap hashMap =newHashMap();
        Dog d1 =newDog("red");
        Dog d2 =newDog("black");
        Dog d3 =newDog("white");
        Dog d4 =newDog("white");
 
        hashMap.put(d1,10);
        hashMap.put(d2,15);
        hashMap.put(d3,5);
        hashMap.put(d4,20);
 
        //print size
        System.out.println(hashMap.size());
 
        //loop HashMap
        for(Entry entry : hashMap.entrySet()) {
            System.out.println(entry.getKey().toString() +" - "+ entry.getValue());
        }
    }
}

輸出: 安全

1
2
3
4
5
4
white dog - 5
black dog - 15
red dog - 10
white dog - 20

注意,咱們錯誤的將」white dogs」添加了兩次,可是HashMap卻接受了兩隻」white dogs」。這不合理(由於HashMap的鍵不該該重複),咱們會搞不清楚真正有多少白色的狗存在。 數據結構

Dog類應該定義以下: ide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
 
    publicbooleanequals(Object o) {
        return((Dog) o).color ==this.color;
    }
 
    publicinthashCode() {
        returncolor.length();
    }
 
    publicString toString(){  
        returncolor +" dog";
    }
}

如今輸出結果以下: 函數

1
2
3
4
3
red dog - 10
white dog - 20
black dog - 15

輸出結果如上是由於HashMap不容許有兩個相等的元素存在。默認狀況下(也就是類沒有實現hashCode()和equals()方法時),會使用Object類中的這兩個方法。Object類中的hashCode()對於不一樣的對象會返回不一樣的整數,而只有兩個引用指向的一樣的對象時equals()纔會返回true。若是你不是很瞭解hashCode()和equals()的規則,能夠看看這篇文章oop

來看看HashMap最經常使用的方法,如迭代、打印等。 this

3. TreeMap

TreeMap的鍵按順序排列。讓咱們先看個例子看看什麼叫做「鍵按順序排列」。 spa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
    publicbooleanequals(Object o) {
        return((Dog) o).color ==this.color;
    }
 
    publicinthashCode() {
        returncolor.length();
    }
    publicString toString(){  
        returncolor +" dog";
    }
}
 
publicclassTestTreeMap {
    publicstaticvoidmain(String[] args) {
        Dog d1 =newDog("red");
        Dog d2 =newDog("black");
        Dog d3 =newDog("white");
        Dog d4 =newDog("white");
 
        TreeMap treeMap =newTreeMap();
        treeMap.put(d1,10);
        treeMap.put(d2,15);
        treeMap.put(d3,5);
        treeMap.put(d4,20);
 
        for(Entry entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() +" - "+ entry.getValue());
        }
    }
}

輸出:

1
2
3
Exception in thread "main" java.lang.ClassCastException: collection.Dog cannot be cast to java.lang.Comparable
    at java.util.TreeMap.put(Unknown Source)
    at collection.TestHashMap.main(TestHashMap.java:35)

由於TreeMap按照鍵的順序進行排列對象,因此鍵的對象之間須要可以比較,因此就要實現Comparable接口。你可使用String做爲鍵,String已經實現了Comparable接口。

咱們來修改下Dog類,讓它實現Comparable接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
classDogimplementsComparable<Dog>{
    String color;
    intsize;
 
    Dog(String c,ints) {
        color = c;
        size = s;
    }
 
    publicString toString(){  
        returncolor +" dog";
    }
 
    @Override
    publicintcompareTo(Dog o) {
        return o.size -this.size;
    }
}
 
publicclassTestTreeMap {
    publicstaticvoidmain(String[] args) {
        Dog d1 =newDog("red",30);
        Dog d2 =newDog("black",20);
        Dog d3 =newDog("white",10);
        Dog d4 =newDog("white",10);
 
        TreeMap treeMap =newTreeMap();
        treeMap.put(d1,10);
        treeMap.put(d2,15);
        treeMap.put(d3,5);
        treeMap.put(d4,20);
 
        for(Entry entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() +" - "+ entry.getValue());
        }
    }
}

輸出:

1
2
3
red dog - 10
black dog - 15
white dog - 20

結果根據鍵的排列順序進行輸出,在咱們的例子中根據size排序的。

若是咱們將「Dog d4 = new Dog(「white」, 10);」替換成「Dog d4 = new Dog(「white」, 40);」,那麼輸出會變成:

1
2
3
4
white dog - 20
red dog - 10
black dog - 15
white dog - 5

這是由於TreeMap使用compareTo()方法來比較鍵值的大小,size不相等的狗是不一樣的狗,若是顏色不一樣可是size相同則也算相同,具體看Dog類的cmpareTo()函數的實現。

4. Hashtable

Java文檔寫道:

HashMap類和Hashtable類幾乎相同,不一樣之處在於HashMap是不一樣步的,也容許接受null鍵和null值。

5. LinkedHashMap

LinkedHashMap is a subclass of HashMap. That means it inherits the features of HashMap. In addition, the linked list preserves the insertion-order.

Let’s replace the HashMap with LinkedHashMap using the same code used for HashMap.

LinkedHashMap是HashMap的子類,因此LinkedHashMap繼承了HashMap的一些屬性,它在HashMap基礎上增長的特性就是保存了插入對象的順序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
classDog {
    String color;
 
    Dog(String c) {
        color = c;
    }
 
    publicbooleanequals(Object o) {
        return((Dog) o).color ==this.color;
    }
 
    publicinthashCode() {
        returncolor.length();
    }
 
    publicString toString(){  
        returncolor +" dog";
    }
}
 
publicclassTestHashMap {
    publicstaticvoidmain(String[] args) {
 
        Dog d1 =newDog("red");
        Dog d2 =newDog("black");
        Dog d3 =newDog("white");
        Dog d4 =newDog("white");
 
        LinkedHashMap linkedHashMap =newLinkedHashMap();
        linkedHashMap.put(d1,10);
        linkedHashMap.put(d2,15);
        linkedHashMap.put(d3,5);
        linkedHashMap.put(d4,20);
 
        for(Entry entry : linkedHashMap.entrySet()) {
            System.out.println(entry.getKey() +" - "+ entry.getValue());
        }      
    }
}

輸出:

1
2
3
red dog - 10
black dog - 15
white dog - 20

若是咱們使用HashMap的話,輸出將會以下,會打亂插入的順序:

1
2
3
red dog - 10
white dog - 20
black dog - 15
相關文章
相關標籤/搜索