1. 程式人生 > >HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap

HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap

entry object類 ref feedback list dog ole exception line

本文由 ImportNew - 唐小娟 翻譯自 Programcreek。歡迎加入翻譯小組。轉載請見文末要求。

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

1. Map概覽

Java SE中有四種常見的Map實現——HashMap, TreeMap, Hashtable和LinkedHashMap。如果我們使用一句話來分別概括它們的特點,就是:

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

如果HashMap的鍵(key)是自定義的對象,那麽需要按規則定義它的equals()和hashCode()方法。

123456789101112131415161718192021222324252627282930313233class Dog { String color; Dog(String c) { color = c; } public String toString(){
return color + " dog"; }} public class TestHashMap { public static void main(String[] args) { HashMap hashMap = new HashMap(); Dog d1 = new Dog("red"); Dog d2 = new Dog("black"); Dog d3 = new Dog("white"); Dog d4 = new Dog("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()); } }}

輸出:

123454white dog - 5black dog - 15red dog - 10white dog - 20

註意,我們錯誤的將”white dogs”添加了兩次,但是HashMap卻接受了兩只”white dogs”。這不合理(因為HashMap的鍵不應該重復),我們會搞不清楚真正有多少白色的狗存在。

Dog類應該定義如下:

12345678910111213141516171819class Dog { String color; Dog(String c) { color = c; } public boolean equals(Object o) { return ((Dog) o).color == this.color; } public int hashCode() { return color.length(); } public String toString(){ return color + " dog"; }}

現在輸出結果如下:

12343red dog - 10white dog - 20black dog - 15

輸出結果如上是因為HashMap不允許有兩個相等的元素存在。默認情況下(也就是類沒有實現hashCode()和equals()方法時),會使用Object類中的這兩個方法。Object類中的hashCode()對於不同的對象會返回不同的整數,而只有兩個引用指向的同樣的對象時equals()才會返回true。如果你不是很了解hashCode()和equals()的規則,可以看看這篇文章。

來看看HashMap最常用的方法,如叠代、打印等。

3. TreeMap

TreeMap的鍵按順序排列。讓我們先看個例子看看什麽叫作“鍵按順序排列”。

123456789101112131415161718192021222324252627282930313233343536class Dog { String color; Dog(String c) { color = c; } public boolean equals(Object o) { return ((Dog) o).color == this.color; } public int hashCode() { return color.length(); } public String toString(){ return color + " dog"; }} public class TestTreeMap { public static void main(String[] args) { Dog d1 = new Dog("red"); Dog d2 = new Dog("black"); Dog d3 = new Dog("white"); Dog d4 = new Dog("white"); TreeMap treeMap = new TreeMap(); 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()); } }}

輸出:

123Exception 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接口。

12345678910111213141516171819202122232425262728293031323334353637class Dog implements Comparable<Dog>{ String color; int size; Dog(String c, int s) { color = c; size = s; } public String toString(){ return color + " dog"; } @Override public int compareTo(Dog o) { return o.size - this.size; }} public class TestTreeMap { public static void main(String[] args) { Dog d1 = new Dog("red", 30); Dog d2 = new Dog("black", 20); Dog d3 = new Dog("white", 10); Dog d4 = new Dog("white", 10); TreeMap treeMap = new TreeMap(); 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()); } }}

輸出:

123red dog - 10black dog - 15white dog - 20

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

如果我們將“Dog d4 = new Dog(“white”, 10);”替換成“Dog d4 = new Dog(“white”, 40);”,那麽輸出會變成:

1234white dog - 20red dog - 10black dog - 15white dog - 5

這是因為TreeMap使用compareTo()方法來比較鍵值的大小,size不相等的狗是不同的狗。

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基礎上增加的特性就是保存了插入對象的順序。

123456789101112131415161718192021222324252627282930313233343536373839class Dog { String color; Dog(String c) { color = c; } public boolean equals(Object o) { return ((Dog) o).color == this.color; } public int hashCode() { return color.length(); } public String toString(){ return color + " dog"; }} public class TestHashMap { public static void main(String[] args) { Dog d1 = new Dog("red"); Dog d2 = new Dog("black"); Dog d3 = new Dog("white"); Dog d4 = new Dog("white"); LinkedHashMap linkedHashMap = new LinkedHashMap(); 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()); } }}

輸出:

123red dog - 10black dog - 15white dog - 20

如果我們使用HashMap的話,輸出將會如下,會打亂插入的順序:

123red dog - 10white dog - 20black dog - 15
原文鏈接: Programcreek 翻譯: ImportNew.com - 唐小娟
譯文鏈接: http://www.importnew.com/8658.html
[ 轉載請保留原文出處、譯者和譯文鏈接。]

HashMap vs. TreeMap vs. Hashtable vs. LinkedHashMap