- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个要求,需要将多个决定因素映射到值。
给定作业执行中的每组决定因素都保证是唯一的。要确定的值不一定是唯一的,但可能是唯一的。
根据作业执行的输入,这可以是一个键,也可以是两个键的组合,或者是映射到单个值的 n
个键的组合。实际上,此 n
可能会限制为不超过 5,但也有可能超过该值。
每个作业执行的所有输入都将具有一定数量的决定因素(即,所有输入将具有 2 个决定因素、3 个决定因素或 n 个决定因素,并且不会混合)。
一个关键示例:foo --> bar
两个键:foo、bar --> baz
三个键:foo、bar、baz --> hai
在此之前,要求是我只能将两个值映射到另一个值。我创建了一个不可变的 Key 类,其中包含两个成员变量以及对 equals 和 hashCode 的适当重写。
public class Key {
String determinant0;
String determinant1;
public Key(String d0, d1) {
determinant0 = d0;
determinant1 = d1;
}
// ..
}
但是,现在我可能要处理 n 个值,我想看看使用列表作为键。
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提醒我使用可变对象(如列表)作为映射中的键是不好的。但是,在我的应用程序中, key 仅设置一次并且永远不会更改。这是 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"));
使用普通数组作为键是行不通的,因为数组的 equal 方法只检查同一性:
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() {
//...
}
}
其中哪一种解决方案(或我未提出的另一种解决方案)最适合这些要求?
最佳答案
作为评论,您的问题包含太多细节,本来可以更短。现在是我的答案。
我更喜欢使用完全隐藏类表示的包装类。作为一个小优化,您可以做的一件事是存储 key 的哈希码,以防止每次都计算它。 equals
方法将很少被调用( map 中的每次碰撞),并且您对此无能为力:
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;
}
}
关于java - 在 Java 中将多个决定因素映射到一个值的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32914118/
我有一个users表,其中包含以下字段:id、username。Id是使用主键自动递增的,我是思考我是否也应该将用户名作为主键。 我有另一个表,audit_results,其中用户名作为users 表
我是一名优秀的程序员,十分优秀!