我有一个要求,我需要把多个决定因素映射到价值观上。
n键的组合。在实践中,这个n可能会被限制在不超过5,尽管它有可能超过这一点。一个关键的例子:foo --> bar
两个键:foo, bar --> baz
三个键:foo, bar, baz --> hai
在此之前,要求我只将两个值映射到另一个值。我创建了一个不可变的密钥类,其中包含两个成员变量以及equals和hashCode的适当覆盖。
public class Key {
String determinant0;
String determinant1;
public Key(String d0, d1) {
determinant0 = d0;
determinant1 = d1;
}
// ..
} 但是,现在我可能要处理n个值,我想看看如何使用list作为键。
Map<List, String> map = new HashMap<List, String>();
map.put(Arrays.asList("foo", "bar", "baz"), "hai");
String determined = map.get(Arrays.AsList("foo","bar","baz"));
assert (determined.equals("hai"));这个question提醒我,在地图中使用可变对象(如列表)作为键是不好的。但是,在我的应用程序中,密钥只设置一次,并且从不更改。下面是此question的另一种选择,它强制它不可变:
HashMap<List<String>, String> map;
map.put(
// unmodifiable so key cannot change hash code
Collections.unmodifiableList(Arrays.asList("foo", "bar", "baz")),
"hai"
);此外,为了防止列表中的突变,我可以做一个类似以下的类:
public class Key {
List<String> determinants;
public Key(List<String> determinants) {
this.determinants = determinants
}
@Override
public boolean equals(Object obj) {
//...
}
@Override
public int hashCode() {
//...
}
}
Key key = new Key(Arrays.asList("foo","bar","baz"));使用普通数组作为键是行不通的,因为数组的等效方法只检查标识:
Map<String[], String> map = new HashMap<String[], String>();
String[] key = new String[]{"foo", "bar", "baz"}
map.put(key, "hai");
System.out.println(map.get(key)); // null这可以通过以下办法加以解决:
public class Key {
String[] determinants;
public Key(String... determinants) {
this.determinants = determinants;
}
@Override
public boolean equals(Object obj) {
//...
}
@Override
public int hashCode() {
//...
}
}把所有的决定因素串联在一个字符串中怎么样?
public class Key {
String hash = "";
public Key(String... determinants) {
for (String determinant : determinants) {
hash += determinant + "_";
}
}
@Override
public boolean equals(Object obj) {
//...
}
@Override
public int hashCode() {
//...
}
}这些解决方案中的哪一个(或者另一个我没有提出)最适合这些需求?
发布于 2015-10-02 19:37:57
作为一个评论,你的问题包含了太多的细节,可能要短得多。现在我的答案来了。
我更喜欢使用一个完全隐藏类表示的包装类。作为一个小的优化,您可以做的一件事是存储密钥的hashCode,以防止每次计算。equals方法将被调用得更少(映射中的每一次碰撞),并且您不能对它做太多事情:
public class Key {
private String[] determinants;
private int hashCode;
public Key(String... determinants) {
if (determinants == null || determinants.length == 0) {
throw new IllegalArgumentException("Please provide at least one value");
}
this.determinants = determinants;
this.hashCode = Objects.hash(determinants);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Key)) return false;
Key that = (Key) o;
return Arrays.equals(determinants, that.determinants);
}
@Override
public int hashCode() {
return hashCode;
}
}https://stackoverflow.com/questions/32914118
复制相似问题