EnumMap的或HashMap的,如果查找键是一个String(EnumMap or HashMa

2019-07-29 06:07发布

我试图权衡使用的利弊EnumMapHashMap 。 因为,我会一直使用查找String ,它似乎是一个HashMapString钥匙是正确的选择。 然而, EnumMap似乎是更好的设计,因为它传达了我的意图,以限制键来具体的枚举。 思考?

这是一个虚构的例子,显示我将如何使用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我应该使用?

Answer 1:

如果所有有效键可以列举,我会使用,因为它确保您始终有一个有效值工作。

也可避免混乱字符串可以用于很多事情,很容易把“动物”串入用于别的东西的字符串。 由于枚举类型不是一般与其他类型互换(除非你使用一个通用的接口),有编码错误的机会较少。



Answer 2:

如果这组可能的密钥是有限的和已知的提前(如你的例子/问题提示),然后枚举就是一个完美的表现。 由于对方表示,使用一个枚举确保没有错误会在使用该密钥进行。

此外,该实现地图的相当优化的,因为键的范围是预先已知的(据我knwow,所述EnumMap的内部使用长度numberOfEnums的阵列,由枚举的序数索引)。

所以我也建议EnumMap

两个(小)的事情要记住,虽然:

  • 您将无法通过继承增加专门的情况下(不能扩展一个枚举,因此与哺乳动物的专题地图的动物在侧面例如没有地图)
  • 加入会员时,你的枚举,如果你“在中间”的其他成员加入它,你改变序号。 由于这些信息可以通过EnumMap的使用,如果重新从旧版本的枚举构成的EnumMap的(例如,使用序列化),这可以证明是有问题


Answer 3:

关键的地图应该是不可修改的和独特的,这可以通过枚举可以存在保证。

同时管理会更容易且不易出错的比较来管理字符串。

所以要为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;
  }

}


Answer 4:

首先,你关键是最终不可改变的。 你一定要使用EnumMap

这就像在Ruby中的Hash:

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

:font_size是Ruby的符号,在Java最终静态副本。



文章来源: EnumMap or HashMap if lookup key is a String