J'ai plusieurs énumes Java qui ressemblent à quelque chose comme ci-dessous (édité pour la confidentialité, etc.).
Dans chaque cas, j'ai une méthode de recherche que je ne suis vraiment pas satisfaite; Dans l'exemple ci-dessous, il est Le problème est que je me sens stupide de faire ces recherches linéaires lorsque je pouvais simplement utiliser un Ma solution: P> FindByChannelCode Code>.
hashmap
public static PresentationChannel findByChannelCode(String channelCode) {
return enumMap.get(channelCode);
}
7 Réponses :
Si vous attendez que le code Channel fourni soit toujours valide, vous pouvez simplement essayer d'obtenir la bonne instance de l'énum à l'aide de la méthode ValueOf (). Si la valeur fournie n'est pas valide, vous pouvez renvoyer NULL ou propager l'exception.
try { return PresentationChannel.valueOf(channelCode); catch (IllegalArgumentException e) { //do something. }
Pourquoi ne nommez-vous pas vos membres a, b, c, d, e code> et utilisez
Valeur de code>
? P>
Parce qu'ils peuvent être comme ça 1,2,3,4 aussi bien ou Николас1, Николас2, etc., c'est-à-dire des identifiants Java.
Je préférerais ne pas que les noms soient si étroitement couplés aux valeurs.
Je pense que vous utilisez des classes non-JDK ici droite?
Une solution similaire avec JDK API: P>
private static final Map<String, PresentationChannel> channels = new HashMap<String, PresentationChannel>(); static{ for (PresentationChannel channel : values()){ channels.put(channel.getChannelCode(), channel); } }
Pour quelques valeurs ok, itération via le tableau de valeurs (). Une note seulement: utilisez Smth comme ça. valeurs () code> close le tableau sur chaque invocation.
public interface Identifiable<T> {
T getId();
public static class EnumRepository{
private static final ConcurrentMap<Class<? extends Identifiable<?>>, Map<?, ? extends Identifiable<?>>> classMap = new ConcurrentHashMap<Class<? extends Identifiable<?>>, Map<?,? extends Identifiable<?>>>(16, 0.75f, 1);
@SuppressWarnings("unchecked")
public static <ID, E extends Identifiable<ID>> E get(Class<E> clazz, ID value){
Map<ID, E> map = (Map<ID, E>) classMap.get(clazz);
if (map==null){
map=buildMap(clazz);
classMap.putIfAbsent(clazz, map);
}
return map.get(value);
}
private static <ID, E extends Identifiable<ID>> Map<ID, E> buildMap( Class<E> clazz){
E[] enumConsts = clazz.getEnumConstants();
if (enumConsts==null)
throw new IllegalArgumentException(clazz+ " is not enum");
HashMap<ID, E> map = new HashMap<ID, E>(enumConsts.length*2);
for (E e : enumConsts){
map.put(e.getId(), e);
}
return map;
}
}
}
enum X implements Identifiable<String>{
...
public String getId(){...}
}
Voici un autre moyen d'implémenter une carte non modifiable:
protected static final Map<String, ChannelCode> EnumMap; static { Map<String, ChannelCode> tempMap = new HashMap<String, ChannelCode>(); tempMap.put("A", ChannelA); tempMap.put("B", ChannelB); tempMap.put("C", ChannelC); tempMap.put("D", ChannelD); tempMap.put("E", ChannelE); EnumMap = Collections.unmodifiableMap(tempMap); }
Je voulais obtenir une partie de la sagesse Sage de ce groupe: quel est le moyen approprié d'indexer une énumération par valeur? EM> P>
Peut-être probablement ne pas le faire du tout em>. p>
tandis que les tables de hachage fournissent
O (1) code> Recherche, ils ont également une grande augmentation constante (pour les calculs de hachage, etc.), donc pour les petites collections, une recherche linéaire peut bien être plus rapide (Si "le moyen efficace" est votre définition de "la manière appropriée"). p>
Si vous voulez juste une manière sèche de le faire, je suppose que
itérables de Guava.find code> est une alternative: p>
xxx pré> blockQuote>
Bon appel à "Que veux-je dire par" bon "". Ce n'est pas nécessairement le plus efficace. S'il y a des frais généraux inutiles, ce n'est pas bon. Si c'est sujette d'erreur, ce n'est pas bon non plus. Je suppose que je pensais dans le sens de "qu'est-ce que Josh Bloch faire?"
Oui, c'est probablement une assez bonne définition de "la bonne façon".
@Ray, Joshua a explosé AbstarCtCollection.Tearray () et une nouvelle arraylist (collection) à Java 1.4, depuis lors quelques désaccords.
@gustafc Je veux faire une correction / suggestion - une carte très i> une carte efficace. Pas de hachage requis car il peut utiliser un tableau avec un index interne pour la valeur Enum.
@pope en effet, mais ils ne travaillent que lorsque les touches i> sont énumérables, ce qui n'est pas le cas ici.
Je cherchais quelque chose de similaire et trouvé sur Ce site un simple, propre et droit au point de vue. Créez et initialisez une carte finale statique à l'intérieur de votre Enum et ajoutez une méthode statique pour la recherche, ce serait donc quelque chose comme:
Au lieu d'utiliser un Enumset code>, vous pouvez utiliser juste
présentationChannel.values () code>
Vous comprenez que EnumMap Maps Enum-> Objet Pas Vice Verse?
Le profil de code montre-t-il que la recherche linéaire est inadéquate?
@Bestssss, peut-être que ma carte est mal nommée. Ce n'est pas un EnumMap, juste une carte de String-> PrésentationChannel (c'est-à-dire de la valeur-> instance)
@trashgod, dans l'exemple ici, il n'y a que quelques instances de clarté. Dans le code réel, il y a plusieurs exemples de cet idiome qui en ont beaucoup d'autres et que des recherches arrivent fréquemment.
Si vous n'avez pas besoin de solution personnalisée mais générale ... Je modifie la réponse pour vous sortir, vous avez essentiellement besoin d'un référentiel externe et d'une interface pour mettre en œuvre.