EnumMap ou HashMap si la clé de recherche est une chaîne

j'essaie de peser le pour et le contre de l'utilisation d'un EnumMap un HashMap. Depuis, je vais toujours chercher en haut en utilisant un String, il semble qu'un HashMap avec un String clé serait le bon choix. Cependant, un EnumMap semble être un meilleur design parce qu'il communique mon intention de restreindre les clés à une énumération spécifique. Pensées?

voici un exemple fictif, montrant comment je vais utiliser le 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;
    }
}

supposons que le AnimalType enum et map ne sera utilisé que par les AnimalFactory pour créer des animaux et nulle part ailleurs.

Map devrais-je utiliser?

27
demandé sur abbood 2012-05-04 12:24:15

4 réponses

si toutes les clés valides peuvent être énumérées, Je m'en servirais pour m'assurer que vous travaillez toujours avec une valeur valide.

il peut aussi éviter la confusion car la corde peut être utilisée pour beaucoup de choses et il est facile de transformer une corde "animale" en une corde utilisée pour autre chose. Comme les types enum ne sont pas interchangeables avec d'autres types en général (sauf si vous utilisez une interface commune), il y a moins de risque d'erreur dans le codage.

12
répondu Peter Lawrey 2013-03-08 00:14:29

Si l'ensemble des clés possibles est fini et connu à l'avance (comme votre exemple/question suggèrent), puis l'enum est une représentation parfaite de ce. Comme d'autres l'a dit, l'utilisation d'un enum assure qu'aucune erreur ne sera faite dans l'utilisation de la clé.

En outre, cette implémentation de Map est assez optimisée, car la portée des touches est connue à l'avance (pour autant que je sache, L'EnumMap utilise un tableau de longueur numberOfEnums interne, indexé par les enum ordinal.)

donc je recommande aussi EnumMap.

Deux (petites) choses à garder à l'esprit que :

  • vous ne serez pas en mesure d'ajouter des cas spécialisés par héritage (vous ne pouvez pas étendre un enum, donc pas de cartes des animaux avec des cartes spécialisées des mammifères sur le côté par exemple)
  • lors de l'ajout d'un membre à votre enum, si vous l'ajoutez "au milieu" des autres membres de vous changer les ordinaux. Comme cette information peut être utilisée par le EnumMap, cela peut s'avérer problématique si vous rechargez un EnumMap construit à partir de l'ancienne version de l'enum (par exemple en utilisant la sérialisation)
3
répondu Simon Baslé 2012-05-04 09:12:45

la clé du Map doit être immuable et Unique et cela peut être garanti en utilisant L'Enum.

gérer aussi serait plus facile et moins sujet aux erreurs que de gérer une chaîne.

Alors Allez Pour EnumMap.

aussi comme nous avons avancé enums, nous pouvons joindre beaucoup d'autres informations et opérations avec les clés elle-même.

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
répondu Javanator 2012-05-04 17:21:10

tout d'abord, toutes vos clés sont définitivement immuables. Vous devriez certainement utiliser EnumMap.

C'est comme de Hachage en Ruby:

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

:font_size est le symbole en Ruby, la contrepartie statique finale en Java.

0
répondu Hao Deng 2015-01-22 15:24:32