2012-05-04 53 views
27

我試圖衡量使用EnumMap優於HashMap的優點和缺點。因爲,我會一直使用String查找,似乎HashMapString鍵將是正確的選擇。然而,EnumMap似乎更好的設計,因爲它傳達了我的意圖,以限制鍵到一個特定的枚舉。思考?EnumMap或HashMap如果查找鍵是一個字符串

這是一個虛構的例子,顯示我如何將使用Map

enum AnimalType { CAT, DOG } 
interface Animal {} 
class Cat implements Animal {} 
class Dog implements Animal {} 

public class AnimalFactory { 

    private static final Map<AnimalType, Animal> enumMap 
      = new EnumMap<AnimalType, Animal>(AnimalType.class); 
    // versus 
    private static final Map<String, Animal> stringMap 
      = new HashMap<String, Animal>(); 

    static { 
     enumMap.put(AnimalType.CAT, new Cat()); 
     enumMap.put(AnimalType.DOG, new Dog()); 
     stringMap.put("CAT", new Cat()); 
     stringMap.put("DOG", new Dog()); 
    } 
    public static Animal create(String type) { 
     Animal result = enumMap.get(AnimalType.valueOf(type)); 
     Animal result2 = stringMap.get(type); 
     return result; 
    } 
} 

假設AnimalType枚舉和地圖將只能由AnimalFactory可用於創建動物和其他地方。

Map我應該使用哪種?

+0

@dogbane有什麼進展? – Javanator

回答

12

如果所有有效的鍵都可以枚舉,我會使用它,因爲它可以確保您始終使用有效的值。

它還可以避免混淆,因爲字符串可用於很多事情,並且很容易將「動物」字符串轉換爲用於其他內容的字符串。由於枚舉類型與其他類型通常不可互換(除非使用通用接口),編碼中出現錯誤的可能性較小。

+0

考慮到動物枚舉和地圖只能被AnimalFactory用來創建動物而沒有其他地方,你還認爲EnumMap更好嗎?在使用EnumMap進行查找之前,將字符串轉換爲枚舉的成本如何? – dogbane

+1

它與在地圖中查找字符串的成本大致相同。 EnumMap沒有加倍,因爲它實際上是一個數組的封裝器。 ;) –

0

鍵映射應該是不可修改和唯一的,這可以使用枚舉保證。

與管理字符串相比,對其進行管理將更容易,也更少出錯。

所以去EnumMap。

此外,由於我們有先進的枚舉,我們可以附加許多其他信息和操作與密鑰本身。

enum AnimalType { 

    Dog("I am dog and I hate cats", true), 
    CAT("I am cat and I love to eat rats", true), 
    RAT("I am a mouse and I love tearing human cloths apart", false) ; 

    private final String description; 
    private final boolean isHelpFullToHuman; 

    private AnimalType(String description , boolean isHelpFullToHuman) { 
    this.description = description; 
    this.isHelpFullToHuman = isHelpFullToHuman; 
    } 

    public boolean isHelpFullToHuman() { 
    return isHelpFullToHuman; 
    } 

    public String getDescription() { 
    return description; 
    } 

} 
+0

它是如何「不容易出錯」? – dogbane

+0

沒有列出的鍵將不會被接受的情況下,枚舉和管理字符串鍵常量在某些類將是一個頭痛的問題。儘管我的評論中不容易出錯的詞不是中心聚焦的元素:) – Javanator

3

如果這組可能的密鑰是有限的,並且事先知道(如你的例子/問題提示),然後枚舉就是一個完美的表現。正如其他人所說,使用枚舉可以確保在使用密鑰時不會犯任何錯誤。

此外,該實現地圖的相當優化的,因爲鍵的範圍是預先已知的(據我knwow,所述EnumMap的使用長度的數組numberOfEnums內部,由枚舉的序數索引)。

所以我也建議EnumMap

兩個(小)的事情要記住,雖然:

  • 您將無法通過繼承增加專門的情況下(你不能與哺乳動物的專業地圖擴展一個枚舉,所以沒有動物的地圖例如)
  • 向您的枚舉中添加成員時,如果將其添加到其他成員的「中間」,則更改了序號。由於這些信息可以通過EnumMap的使用,如果重新從舊版本的枚舉構成的EnumMap的(例如,使用序列化),這可以證明是有問題
+0

正如你所說,一個'EnumMap '更快,但在執行查找之前將輸入字符串轉換爲枚舉需要額外的成本。 – dogbane

0

首先,你關鍵是最終不可改變的。你一定要使用EnumMap

這就好比散列紅寶石:

options = { :font_size => 10, :font_family => "Arial" } 

:font_size是Ruby的符號,在Java最終靜態副本。

相關問題