程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 【Simple Java】HashMap vs TreeMap vs Hashtable vs LinkedHashMap,hashmaptreemap

【Simple Java】HashMap vs TreeMap vs Hashtable vs LinkedHashMap,hashmaptreemap

編輯:JAVA綜合教程

【Simple Java】HashMap vs TreeMap vs Hashtable vs LinkedHashMap,hashmaptreemap


Map是一個重要的數據結構,本篇文章將介紹如何使用不同的Map,如HashMap,TreeMap,HashTable和LinkedHashMap。

Map概覽

 

Java中有四種常見的Map實現,HashMap,TreeMap,HashTable和LinkedHashMap,我們可以使用一句話來描述各個Map,如下:

  • HashMap:基於散列表實現,是無序的;
  • TreeMap:基於紅黑樹實現,按Key排序;
  • LinkedHashMap:保存了插入順序;
  • Hashtable:是同步的,與HashMap類似;

HashMap

如果HashMap的Key是自己定義的對象,那麼一般需要覆蓋equals()和hashCode()方法,且要遵循他們之間的約定。

package simplejava;

import java.util.HashMap;
import java.util.Map.Entry;

class Dog {
    String color;

    Dog(String c) {
        color = c;
    }

    public String toString() {
        return color + " dog";
    }
}

public class Q26 {

    public static void main(String[] args) {
        HashMap<Dog, Integer> hashMap = new HashMap<Dog, Integer>();
        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<Dog, Integer> entry : hashMap.entrySet()) {
        System.out.println(entry.getKey().toString() + " - " +
        entry.getValue());
        }
    }

}

結果輸出:

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

注意,我們不小心添加了兩個"white dogs“,但是HashMap仍然存儲它。這是不合理的,現在我們困惑到底有多少條白狗存入了HashMap,5還是20呢。

其實,Dog類應該是這樣定義的:

class Dog {
    String color;

    Dog(String c) {
        color = c;
    }

    public boolean equals(Object o) {
        return ((Dog) o).color.equals(this.color);
    }

    public int hashCode() {
        return color.length();
    }

    public String toString() {
        return color + " dog";
    }
}

結果輸出:

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

原因是因為HashMap不允許兩個相同的元素存入,默認情況下,Object的hashCode()和equals()會被用於判斷兩個對象是否相同。默認的hashCode()方法對於不同的對象會返回不同的值,而equals()方法只有當兩個引用相等,即指向同一個對象的時候才返回true。如果你不是很清楚,可以自己檢驗下hashCode()和equals()之間的關系。

舉個例子,可以檢驗下HashMap中最常用的方法,如iteration,print等。

TreeMap

TreeMap是按key排序的,讓我們先看下如下代碼,了解其“按key排序”思想。

package simplejava;

import java.util.Map.Entry;
import java.util.TreeMap;

class Dog {
    String color;

    Dog(String c) {
        color = c;
    }

    public boolean equals(Object o) {
        return ((Dog) o).color.equals(this.color);
    }

    public int hashCode() {
        return color.length();
    }

    public String toString() {
        return color + " dog";
    }
}

public class Q26 {

    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<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
        treeMap.put(d1, 10);
        treeMap.put(d2, 15);
        treeMap.put(d3, 5);
        treeMap.put(d4, 20);

        for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }

}

結果輸出:

Exception in thread "main" java.lang.ClassCastException: simplejava.Dog cannot be cast to java.lang.Comparable
    at java.util.TreeMap.compare(TreeMap.java:1188)
    at java.util.TreeMap.put(TreeMap.java:531)
    at simplejava.Q26.main(Q26.java:34)

由於TreeSet是基於Key排序的,所以作為key的對象需要相互比較,這就是為什麼key需要實現Comparable接口。舉個例子,你可以使用字符串作為Key,因為String已經實現了Comparable接口。

現在,讓我們改變一下Dog,讓它可比較,如下:

package simplejava;

import java.util.Map.Entry;
import java.util.TreeMap;

class 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 Q26 {

    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<Dog, Integer> treeMap = new TreeMap<Dog, Integer>();
        treeMap.put(d1, 10);
        treeMap.put(d2, 15);
        treeMap.put(d3, 5);
        treeMap.put(d4, 20);
        for (Entry<Dog, Integer> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }

}

結果打印:

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

在這個例子中,我們是按dog的size來排序的;

如果"Dog d4 = new Dog("white", 10);"被替換成"Dog d4 = new Dog("white",40);",結果將輸出如下信息:

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


這是因為當前TreeMap使用compareTo()去比較key,不同的size意味著不同的dogs。

HashTable

參考java文檔:HashMap與HashTable基本類似,除了非同步和允許null外。

LinkedHashMap

LinkedHashMap是HashMap的子類,意味著它繼承了HashMap的特性,除此之外,LinkedHashMap還保存了插入順序。

讓我們使用同樣的代碼,然後將HashMap替換成LinkedHashMap,如下:

package simplejava;

import java.util.LinkedHashMap;
import java.util.Map.Entry;

class Dog {
    String color;

    Dog(String c) {
        color = c;
    }

    public boolean equals(Object o) {
        return ((Dog) o).color.equals(this.color);
    }

    public int hashCode() {
        return color.length();
    }

    public String toString() {
        return color + " dog";
    }
}

public class Q26 {

    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<Dog, Integer> linkedHashMap = new LinkedHashMap<Dog, Integer>();
        linkedHashMap.put(d1, 10);
        linkedHashMap.put(d2, 15);
        linkedHashMap.put(d3, 5);
        linkedHashMap.put(d4, 20);
        for (Entry<Dog, Integer> entry : linkedHashMap.entrySet()) {
            System.out.println(entry.getKey() + " - " + entry.getValue());
        }
    }

}

輸出結果:

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

如果我們使用HashMap,結果如下,區別在於沒有保存插入順序:

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

 

更多閱讀:ArrayList vs. LinkedList vs. Vector

譯文鏈接:http://www.programcreek.com/2013/03/hashmap-vs-treemap-vs-hashtable-vs-linkedhashmap/

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved