2012-03-16 88 views
2

是否有可能在下列情況下使用枚舉:枚舉幫助/建議 - java的

比方說,你有一定的預定義的「讀類型」。示例讀取類型可以是:診斷,KWH,MaxDemand,OnPeak等。對於這些讀取類型中的每一種,都有一個'TIMTagNumber',它是一種用於檢索每種預定義讀取類型的協議。

例如,TIMTagNumber 1100將檢索讀取類型診斷 TIMTagNumber 1300將檢索讀取類型KWH。 問題是,預定義的讀取類型可能會被多個TIMTagNumber檢索到,其中有時會被檢索。

我想創建一個枚舉ReadType來定義每個讀取類型和所有可用於檢索讀取的TIMTagNumbers。 你可以用這種方式使用枚舉嗎?

public enum ReadType{ 
    KWH(1300) 
    Diagnostic(1100) 
    ReadType3(1400, 1401) // This read can be retrieved by both 1400 and 1401 
} 

如果枚舉不是要走的路,有沒有一種優雅或有效的方法來定義這些讀取類型?所有這一切的總體預期結果都是在識別基於TIMTagNumbers的讀取類型。

I.E.鑑於1400或1401,你會知道它是'ReadType3'。

回答

4

你可以這樣做嗎?是。這是否是正確的決定取決於您是否希望將這些TIMTagNumbers耦合到讀取類型。如果不是,一個簡單的Map<Integer, ReadType>可能就足夠了。

這裏是你如何能做到這一點:

public static enum MyEnum { 
    KWH(1300), 
    Diagnostic(1100), 
    ReadType3(1400, 1401); 

    private Set<Integer> timTagNumbers; 

    MyEnum(Integer... timTagNumbers) { 
     this.timTagNumbers = new HashSet<Integer>(Arrays.asList(timTagNumbers)); 
     //add check to make sure that values are unique across all instances 
    } 

    public static MyEnum forTIMTagNumber(int num) { 
     for (MyEnum readType : values()) { 
      if (readType.timTagNumbers.contains(num)) { 
       return readType; 
      } 
     } 
     throw new NoSuchElementException("No ReadType matching TIMTagNumber " + num); 
    } 
} 

//... 
int timTagNumber = 1400; 
ReadType readType = ReadType.forTIMTagNumber(timTagNumber); 

正如我前面所說,這種風格的效果很好,當數據和枚舉類型本質上已經加上。當枚舉類型與映射值分離時(例如,這些值用於序列化枚舉的多種方式之一),或者這些值是特定於配置的或甚至是動態的(例如,如果它們是價格上一個物品)。在這些情況下,通常最好將EnumMapMap中的映射外化。

+0

到目前爲止,這看起來不錯!我會試試看。但有一個問題,我對增強型for循環並不是很熟悉,尤其是在你使用它的方式上。 'values()'代表什麼以及它在哪裏定義? – TyC 2012-03-16 18:30:20

+2

@TyC每個枚舉類型都有一個'values()'方法,返回枚舉值的有序數組,參見[documentation](http://docs.oracle.com/javase/1.5.0/docs/guide/language /enums.html)。 'for(x:y)'是'for(int i = 0; i ' – 2012-03-16 18:34:27

+0

@ jabu.10245謝謝。 – TyC 2012-03-16 19:10:48

0

確實可以用這種方式使用枚舉,但是您的示例缺少私有字段和構造函數。

喜歡的東西:

public enum Bla{ 
    CASE1(100),CASE2(200); 

    private int amount; 

    private Bla(int amount) { 
     this.amount = amount; 
    } 

    public Bla getByValue(int value){ 
     switch (value) { 
      case 100: return CASE1; 
      case 200: return CASE2; 
     } 
     return null; 
    } 

} 

我已經提供了返回枚舉給定的值「反向查找」的方法。

最主要的優點是你可以使用「Bla」代替int的其他代碼,這將保證操作的類型安全性,基本上,它將不可能傳遞一個無效的int值作爲方法參數(也可以在枚舉上使用switch語句,在某些使用場景中這非常棒)。

編輯:我注意到,我發佈後,你需要更多的一個int來指定枚舉,但同樣的邏輯適用,當然在方法中的應有更改。

0

當你在enum變量被聲明的圓括號中提供值時,你可以做如下的事情,它調用enum的構造函數。您需要在枚舉中創建一個不同的方法來從整數值中獲取枚舉類型。見下文。

public enum ReadType { 
     KWH(), DIAGNOSTIC(), READTYPE3(); 

     public ReadType getReadType(int num) { 
      ReadType toReturn = KWH; 
      switch (num) { 
      case 1300: 
       toReturn = KWH; 
       break; 
      case 1100: 
       toReturn = DIAGNOSTIC; 
       break; 
      case 1400: 
       toReturn = READTYPE3; 
       break; 
      case 1401: 
       toReturn = READTYPE3; 
       break; 
      } 
      return toReturn; 

     } 
3
public enum ReadType { 
    KWH(1300), 
    Diagnostic(1100), 
    ReadType3(1400, 1401); 

    private int[] timTagNumbers; 

    private ReadType(int ... numbers) { 
     this.timTagNumbers = numbers; 
    } 

    public int[] getTimTagNumbers() { 
     return timTagNumbers; 
    } 

    public static ReadType forTimTagNumber(int n) { 
     for (ReadType type : values()) { 
      if (Arrays.binarySearch(type.timTagNumbers, n) != -1) { 
       return type; 
      } 
     } 

     throw new NoSucheElementException(); // if not found 
    } 

有了這個,你可以做

int[] timTagNumbers = ReadType.Diagnostic.getTimTagNumbers(); // [ 1100 ] 

ReadType type3 = ReadType.forTimTagNumber(1401); // ReadType.ReadType3 
0

如果可以施加一些限制,像不超過2個標籤可以讀類型相關聯,並每個標籤不大於2^15,則可以將這兩個數字存儲爲1個整數。有關更多詳細信息,請參閱this S/O帖子。