2011-04-20 98 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