2011-04-20 94 views
2

我有一个关于使用下面的枚举文件提供给我的最佳方法的Java问题。Java枚举处理

public enum Foo{ 

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

有上述格式大致100ish项

/** 
* 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; 
    } 

那么我想这个枚举做的是以下几点: 用户发出命令,例如:/反弹1

程序将弹跳识别为命令并查找以下参数。由于1遵循命令,它现在检查1是枚举中的有效id#。如果它是执行命令。

用户以下面的形式发出示例2的命令:/弹跳平面。这一次它会检查该字符串是否在枚举中是一个有效的字符串名称,如果它是获取与其关联的id#以执行该命令。

如何检查这些标准是否存在id或其中一个字符串id,并始终返回id#以供以后使用。任何帮助,将不胜感激。

还应该注意的是,这个枚举文件是它自己的独立类文件被从main调用。

感谢所有帮助我走上正轨的人,我已经授予沃尔夫卡斯尔正确的答案,这里是我为我工作的东西,但我仍然乐于接受任何有关我的方法对逻辑或性能缺陷的批评。

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

我不清楚你的问题是什么。你的代码看起来应该做你想做的事情。你可以扩展你遇到的实际问题吗? – wolfcastle 2011-04-20 19:07:02

+0

这是通过合作团队提供给我的制作插件的文件。我的包在这个文件中使用enum来验证用户试图创建的“item”实际上是否通过项目ID#或它的字符串名称存在于枚举中。如果用户使用字符串名称发送命令,则需要根据字符串名称获取项目标识,以便可以创建该项目。 (希望这更有意义) – JDD 2011-04-20 20:36:43

+0

'BlockType'与'Foo'相同吗? – 2011-04-20 21:13:09

回答

2

所以,如果我理解正确的话,你已经发布的代码是不是你的代码,而是代码必须使用,和你想知道你如何使用它。

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

正确的Wolfcastle是我正要试图让我知道你的意见,请: \t \t尝试{ \t \t \t ID =的Integer.parseInt(S); \t \t}赶上(NumberFormatException的NFE){ \t \t \t \t \t} \t \t如果(BlockType.lookup(S).getName()!= NULL || BlockType.fromID(ID)!= NULL) \t \t { \t \t \t如果(BlockType.lookup(S).getName()!= NULL) \t \t \t { \t \t \t字符串块名称= BlockT ype.lookup(S).getName(); \t \t \t int blockid = BlockType.lookup(s).getID(); \t \t \t}否则{ \t \t \t \t字符串块名称= BlockType.fromID(ID).getName(); \t \t \t \t int blockid = BlockType.fromID(id).getID(); \t \t \t} \t \t} – JDD 2011-04-20 21:03:53

+0

@JDD:请不要将代码放在评论中,它会变得不可读。将其添加到问题(它有一个编辑链接)。 – 2011-04-20 21:16:47

+0

Paulo是对的,试着把它放在问题中。但是,您所写的内容是错误的,因为您正试图检查getName是否为调用查找的结果。这将导致无效输入的NPE。 BlockType类的javadoc明确指出查找方法可以返回null。这是你需要做的检查(以及我的例子)。假设枚举被正确定义,getName()将永远不会返回null,所以不要麻烦检查它。 – wolfcastle 2011-04-20 21:23:41

1

在这种情况下,您可以检查返回值是否为空。或者你想要检查什么?

还要注意的是,你不需要EnumSet:

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

也许我只是困惑,但我被告知,如果我返回null,我会得到一个空指针异常,会崩溃我的插件?至于你说我不需要的部分,你是正确的,但是有几个插件正在访问这个文件。我想要检查的确切是...用户发送/创建1或/创建飞机程序应该检查,以确保1是一个有效的ID或该飞机是一个有效的字符串名称附加到一个ID然后返回给我们那个ID。 – JDD 2011-04-20 20:41:00

+0

正如我所说的,无论是检查客户端代码返回的值!= null(这是安全的,因为你的Map永远不会包含空值),或提供一个contains/isSupportedId/isSupportedName方法,它调用contains方法地图。我没有得到你评论的插件和NPE部分。也许你可以提供一个显示问题的小样本? – Puce 2011-04-21 08:55:26

+0

出现的问题是,我正在写的接受用户输入,然后检查用户输入的id /字符串是否在枚举中。如果它不在枚举中,它可以返回一个npe,然后程序崩溃,但是我已经明白,并且使用添加到最初的帖子底部的代码正常工作。这里 – JDD 2011-04-22 22:53:05