2011-04-20 4 views
2

J'ai une question Java sur la meilleure méthode pour travailler avec le fichier enum suivant qui m'a été fourni.Java Enum handling

public enum Foo{ 

    PLANE(1, "Plane", "plane"), 
    CASTLE(2, "Castle", "castle"), 
    FEILD(3, "Feild", "field"), 
    ROAD(4, "Road", new String[] {"road", "pavement"}); 
} 

Il y a à peu près entrées 100ish des formats ci-dessus

/** 
* Stores a map of the names for fast access. Stores a map of the IDs for fast access. 
*/ 
    private static final Map<Integer,BlockType> ids = new HashMap<Integer,BlockType>(); 

    private static final Map<String,BlockType> lookup = new HashMap<String,BlockType>(); 

    private final int id; 
    private final String name; 
    private final String[] lookupKeys; 

    static { 
     for(Foo type : EnumSet.allOf(Foo.class)) { 
      ids.put(type.id, type); 
      for (String key : type.lookupKeys) { 
       lookup.put(key, type); 
      } 
     } 
    } 


    /** 
* Construct the type. 
* 
* @param id 
* @param name 
*/ 
    Foo(int id, String name, String lookupKey) { 
     this.id = id; 
     this.name = name; 
     this.lookupKeys = new String[]{lookupKey}; 
    } 

    /** 
* Construct the type. 
* 
* @param id 
* @param name 
*/ 
    Foo(int id, String name, String[] lookupKeys) { 
     this.id = id; 
     this.name = name; 
     this.lookupKeys = lookupKeys; 
    } 

    /** 
* Return type from ID. May return null. 
* 
* @param id 
* @return 
*/ 
    public static Foo fromID(int id) { 
     return ids.get(id); 
    } 

    /** 
* Return type from name. May return null. 
* 
* @param name 
* @return 
*/ 
    public static Foo lookup(String name) { 
     return lookup.get(name.toLowerCase()); 
    } 

    /** 
* Get block numeric ID. 
* 
* @return 
*/ 
    public int getID() { 
     return id; 
    } 

    /** 
* Get user-friendly name. 
* 
* @return 
*/ 
    public String getName() { 
     return name; 
    } 

Donc ce que je suis en train de faire avec ce ENUM est la suivante: Un utilisateur émet une commande, par exemple:/rebond 1

Le programme reconnaît bounce comme une commande et cherche l'argument suivant. Puisque 1 suit la commande, il vérifie maintenant que 1 est un identifiant valide # dans l'énumération. Si c'est le cas, il exécute la commande.

Un utilisateur émet une commande pour l'exemple 2 sous la forme suivante:/plan de rebond. Cette fois-ci, il vérifie si la chaîne est un nom de chaîne valide dans l'énumération et si elle est capturée, l'id # lui est associé pour exécuter la commande.

Comment puis-je vérifier pour ces critères que l'ID ou l'un des ID de chaîne existe et toujours retourner l'ID # pour une utilisation ultérieure. Toute aide serait appréciée.

Il convient également de noter que ce fichier enum est son propre fichier de classe indépendant appelé à partir du principal. Merci à tous ceux qui m'ont aidé à me mettre sur la bonne voie, j'ai donné la bonne réponse à Wolfcastle, voici ce que j'ai pu faire pour moi mais je suis toujours ouvert aux critiques sur la logique ou les défauts de performance avec ma méthode.

String s = null; 
     try { 
      s = in.readLine(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      id = Integer.parseInt(s); 
     } catch (NumberFormatException nfe) { 

     } 
     if (BlockType.lookup(s) != null 
       || BlockType.fromID(id) != null) { 
      if (BlockType.lookup(s)!= null) { 
       blockname = BlockType.lookup(s).getName(); 
       blockid = BlockType.lookup(s).getID(); 
      } else { 
       blockname = BlockType.fromID(id).getName(); 
       blockid = BlockType.fromID(id).getID(); 
      } 
     } 
+0

Ce n'est pas clair pour moi quel est votre problème. Votre code semble devoir faire ce que vous voulez. Pouvez-vous développer le problème réel que vous rencontrez? – wolfcastle

+0

Ceci est un fichier qui me est fourni via une équipe de collaboration pour faire des plugins. Mon paquet utilise l'enum dans ce fichier pour valider que l'item que l'utilisateur essaye de créer existe réellement dans l'enum soit par l'identifiant des éléments, soit par son nom. Si l'utilisateur envoie la commande en utilisant le nom de la chaîne, je dois obtenir l'identifiant de l'article en fonction du nom de la chaîne afin que l'article puisse être créé. (J'espère que cela a plus de sens) – JDD

+0

BlockType est-il le même que Foo? –

Répondre

2

Donc, si je vous comprends bien, le code que vous avez affiché est pas votre code, mais vous devez utiliser le code, et vous vous demandez comment vous pouvez l'utiliser.

String param = getParam(); // get the '1' or 'plane' string from your input 
    BlockType type = null; 
    try { 
     // Check for an integer 
     int id = Integer.parseInt(param); 
     type = BlockType.getFromId(id); 
    } catch(NumberFormatException e) { 
     // Okay, not an integer, check the lookup value 
     type = BlockType.lookup(param); 
    } 

    if(type != null) { 
       int blockid = type.getID(); 
       String blockname = type.getName(); 
       // continue on 
    } else { 
    // else the input parameter was invalid and we can't get a BlockType for it 
    // return some kind of error 
    } 
+0

est correcte Wolfcastle ici ce que j'allais tenter me faire connaître vos opinions s'il vous plaît: \t \t try { \t \t \t id = Integer.parseInt (s); \t \t} catch (NumberFormatException NFE) { \t \t \t \t \t} \t \t si (BlockType.lookup (s) .getName()! = Null || BlockType.fromID (id)! = Null) \t \t { \t \t \t si (BlockType.lookup (s) .getName()! = null) \t \t \t { \t \t \t Chaîne blockname = BlockT ype.lookup (s) .getName(); \t \t \t int blockid = BlockType.lookup (s) .getID(); \t \t \t} else { \t \t \t \t Chaîne blockname = BlockType.fromID (id) .getName(); \t \t \t \t int blockid = BlockType.fromID (id) .getID(); \t \t \t} \t \t} – JDD

+0

@JDD: s'il vous plaît ne pas mettre le code dans un commentaire, il devient illisible. Ajoutez-le à la question à la place (il a un lien d'édition). –

+0

Paulo a raison, essayez de le mettre dans la question. Ce que vous avez écrit, cependant, est faux, car vous essayez de vérifier si getName est null à partir du résultat de la recherche d'appel. Cela entraînera un NPE pour une entrée non valide. Le javadoc de la classe BlockType indique clairement que la méthode de recherche peut renvoyer null. C'est la vérification que vous devez faire (et ce que mon exemple fait). En supposant que les énumérations sont définies correctement, getName() ne renverra JAMAIS de valeur nulle, alors ne vous embêtez pas à le vérifier. – wolfcastle

1

Dans ce cas, vous pouvez simplement vérifier si la valeur renvoyée est nulle. Ou que voulez-vous vérifier exactement?

Notez également que vous n'avez pas besoin EnumSet:

static { 
    for(Foo type : values()) { 
     ids.put(type.id, type); 
     for (String key : type.lookupKeys) { 
      lookup.put(key, type); 
     } 
    } 
} 
+0

peut-être que je suis simplement confus mais on m'a dit que si je retournais null j'obtiendrais une Exception Null Pointer qui planterait mon plugin? Quant à la partie que vous avez dit que je n'ai pas besoin, vous avez raison cependant plusieurs plugins accèdent à ce fichier. Ce que je veux vérifier, c'est exactement ... l'utilisateur envoie/crée 1 ou/crée un plan que le programme doit vérifier pour s'assurer que 1 est un identifiant valide ou que ce plan est un nom de chaîne valide attaché à un identifiant puis nous retourner cet id. – JDD

+0

Comme je l'ai dit, soit vérifier dans le code client que la valeur retournée! = Null (qui est sûr ici, car votre carte ne contiendra jamais de valeurs nulles), ou fournir une méthode contains/isSupportedId/isSupportedName, qui appelle la méthode contains de Carte. Je n'ai pas eu le plugin et NPE partie de votre commentaire.Peut-être que vous pourriez fournir un petit échantillon qui montre le problème? – Puce

+0

Le problème qui se pose est que ce que j'écris accepte une entrée de l'utilisateur, puis vérifie si l'id/chaîne que l'utilisateur a entré est dans l'énumération. Si ce n'est pas dans l'énumération, il peut renvoyer un npe qui écrase le programme, mais j'ai tout compris et je travaille correctement en utilisant le code qui a été ajouté au bas de mon message initial. – JDD