在以下情况下是否可以使用枚举:
假设您有一定数量的预定义“读取类型”。例如读类型可以是:诊断,KWH,MaxDemand,OnPeak等,并为每个这些读类型,有一个“TIMTagNumber”,这是essientally用于检索每个预定义的读类型的协议。
例如,TIMTagNumber 1100将检索读取类型Diagnostic 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的读取类型。
即。鉴于1400 OR 1401,您会知道它是'ReadType3'。
答案 0 :(得分:4)
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);
正如我上面所说,当数据和枚举类型已经内在耦合时,这种风格很有效。当枚举类型与映射值分离时(例如,这些值用于序列化枚举的多种方式之一)或者值是特定于配置的还是动态的(例如,如果它们是价格的话),那就不好了一个物品)。在这些情况下,通常最好将此映射外部化为EnumMap
或Map
。
答案 1 :(得分: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
答案 2 :(得分: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来指定枚举,但同样的逻辑适用,当然还有方法的适当变化。
答案 3 :(得分:0)
您可以执行以下操作,当您在声明枚举变量的括号中提供值时,它会调用枚举的构造函数。您需要在枚举本身中创建一个不同的方法,以从整数值中获取枚举类型。见下文。
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;
}
答案 4 :(得分:0)
如果您可以施加一些限制,例如不超过2个标签可以与读取类型相关联,并且每个标签不大于2 ^ 15,那么您可以将这两个数字存储为1个整数。有关详细信息,请参阅this S / O帖子。