gpt4 book ai didi

java - 在 Java 中将多个决定因素映射到一个值的最佳方法

转载 作者:行者123 更新时间:2023-12-01 11:06:14 27 4
gpt4 key购买 nike

我有一个要求,需要将多个决定因素映射到值。

  • 给定作业执行中的每组决定因素都保证是唯一的。要确定的值不一定是唯一的,但可能是唯一的。

  • 根据作业执行的输入,这可以是一个键,也可以是两个键的组合,或者是映射到单个值的 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com