我有一个要求,即多个枚举需要在ie Map<Key,Value>
中找到一个值(枚举的组合将返回一个唯一值)。
我认为有许多选项,比如使用包装器对象说Key,它将充当Key。此外,如果键限制为两个(不确定),我们可以使用Guava Table。
想要检查下面的方法,其中两个枚举将映射到唯一的计算值,需要建议理解 -
i)如果这种方法没问题?
ii)如果是,它是否可扩展?即,它可以很容易地通用,以支持'n'枚举
如toKey(Enum ...enums)
以下是两个枚举的片段 -
static Integer toKey(Status s, SubStatus ss) {
return Integer.valueOf(s.ordinal() * SubStatus.values().length + ss.ordinal());
}
和
Status { NONE, PASS, WARN, REJECT }
SubStatus { NONE, SOFT_REJECT, HARD_REJECT }
Integer key1 = toKey(Status.REJECT, SubStatus.HARD_REJECT)
Integer key2 = toKey(Status.WARN, SubStatus.NONE)
then key1 != key2
谢谢!
答案 0 :(得分:0)
您可以尝试使用此代码生成用作密钥的哈希码:
static int toKey(Status s, SubStatus ss) {
final int prime = 31;
int result = 1;
result = prime * result + ((s == null) ? 0 : s.hashCode());
result = prime * result + ((ss == null) ? 0 : ss.hashCode());
return result;
}
由于素数而对碰撞应该相当稳健,并且它可以扩展为支持n个枚举。
答案 1 :(得分:0)
如果你想要一个通用的解决方案,你可以引入一个这样的数组包装器:
import java.util.Arrays;
import java.util.Objects;
public final class MultiKey {
private final Object[] elements;
public MultiKey(Object... elements) {
this.elements = Objects.requireNonNull(elements);
}
@Override
public int hashCode() {
return Arrays.hashCode(elements);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
return Arrays.equals(elements, ((MultiKey) obj).elements);
}
@Override
public String toString() {
return Arrays.toString(elements);
}
}
它可以用作HashMap
键:
Map<MultiKey, String> testMap = new HashMap<>();
testMap.put(new MultiKey(Status.NONE), "none");
testMap.put(new MultiKey(Status.REJECT, SubStatus.SOFT_REJECT), "soft-reject");
testMap.put(new MultiKey(Status.WARN, SubStatus.SOFT_REJECT), "warn");
System.out.println(
testMap.get(new MultiKey(Status.REJECT, SubStatus.SOFT_REJECT))); // prints "soft-reject"
请注意,它既不能组合枚举,也可以组合使用正确定义hashCode
和equals
的任何类型。但是,您应该在MultiKey
构造函数中保持相同的参数顺序。