2012-03-16 42 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帖子。