使用另一个具有其哈希码的对象从HashMap中获取密钥

3

假设我有一个包含大量对象的Map,其中所有对象都包含大量杂乱数据,在比较它们时会被忽略(使用.equals())。例如:

public class Complex {
    private long id;
    // Many other fields...

    // Methods, getters, setters...

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Complex other = (Complex) obj;
        if (id != other.id) // Note that only id is compared.
            return false;
        return true;
    }
}

我可以轻松地使用myMap.get(new Complex(id));mySetOrMap.contains(new Complex(id)); 在常数时间内找到这个map或set是否包含一个特定id的键,但不幸的是这不是我所需要的。
我需要的是条目,其中包含原始键(它包含所有杂项数据)和值。
我的可能解决方案如下:
1. 我可以轻松地遍历hashmap,但那不太优雅也不快。
2. 我可以更改我的整个映射实现,使其成为 Map >,但这似乎有点过度。
3. 我可以有另一个映射: Map ,这可能是最可行的。
总之:是否有一种优雅的方法可以检索用于创建映射中的条目的原始键,假设您具有与其相同的哈希码的东西?
在编写本文后,我找到了一个4年前的重复,但想知道我们是否可以修改答案(它是Java 7之前的)。

你能再解释清楚一点吗?你当前的哈希表长什么样子?HashMap<Long,?> - Karthik
我可以有另一个Map: Map<Long, Complex>,这可能是最合理的选择。- 我同意。我认为没有办法在不迭代原始Map的情况下获取原始键(可能有一种使用Java 8 Streams更短的写法,但仍需要迭代keySet或entrySet),这并不高效。 - Eran
@karthik - 这里的值并不重要,因为它在这里是无关紧要的(或者我是这样认为的?)。但如果你有想法,只需说Map<Complex, ValueType>。 - Addison
2个回答

0

你只有两种选择:

a)创建第二个Map:Map<Long,Complex>来查找相关的Complex对象,就像你已经提到的那样,或者

b)最好使用流迭代Map:

Long searchID = 42L;
    Map<Complex, MyValueType> x = new HashMap<Complex, MyValueType>();
    Entry<Complex, MyValueType> y = x.entrySet()
                                    .stream()
                                    .filter(e -> e.getKey().getId().equals(searchID))
                                    .findFirst()
                                    .orElse(null);

顺便提一下:在xtend中也是一样的(Java的“附加组件”):
val Long searchID = 42L
val x = <Complex, MyValueType>newHashMap()
val y = x.filter[id==searchID]

我不会创建一个Map<Long, Entry<Complex, MyValueType>>

最好的方案取决于你的“环境”——有多少可用的RAM/需要多快。但我认为没有更加“优雅”的方法来做这件事。


0
我可以更改整个地图的实现,使其成为Map<Long,Entry<Complex,MyValueType>>,但这似乎有点过度了。
这有什么过度的?这是从您的键到您要获取的数据的映射,这正是Maps应该使用的方式。当然,将Entry类用作通用元组会带来一些问题,因此您可以定义一个新类ComplexWithMyValueType(可能具有更好的特定于域的名称),以表示您要检索的数据形状。然后您可以拥有一个Map<Long,ComplexWithMyValueType>。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接