Java 使用另一个对象及其哈希代码从哈希映射获取密钥

Java 使用另一个对象及其哈希代码从哈希映射获取密钥,java,dictionary,key,Java,Dictionary,Key,假设我有一个包含大量对象的映射,所有这些对象都包含大量杂项数据,在比较它们时会被忽略(使用.equals())。例如,这: public class Complex { private long id; // Many other fields... // Methods, getters, setters... public boolean equals(Object obj) { if (this == obj) r

假设我有一个包含大量对象的映射,所有这些对象都包含大量杂项数据,在比较它们时会被忽略(使用
.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(newcomplex(id)),我可以在固定时间内轻松找到这个映射或集合是否包含具有特定id的键
mySetOrMap.contains(新复合体(id)),但不幸的是,这不是我需要的

我需要的是包含原始键(包含所有杂项数据)和值的条目

我可能的解决办法如下:

  • 我可以很容易地遍历hashmap,但这不是很优雅或快速
  • 我可以更改map的整个实现,使其成为
    map
    ,但这似乎有点过分
  • 我可以有另一张地图:
    Map
    ,这可能是最合理的
总之:假设您有与之相同的哈希代码,有没有一种优雅的方法来检索用于在映射中创建条目的原始密钥


写完这篇文章后,我确实找到了一个4年前的答案,但我想知道我们是否可以修改答案(这是Java 7之前的版本)。

您只有两个选择:

a) 创建第二个映射:
Map
以查找相关的
复杂对象,如前面所述,或者

b) 您可以在地图上迭代,最好使用流:

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);
Long searchID=42L;
Map x=新的HashMap();
条目y=x.entrySet()
.stream()
.filter(e->e.getKey().getId().equals(searchID))
.findFirst()
.orElse(空);
顺便说一句:在xtend中也是一样(“addon”到Java):

val Long searchID=42L
val x=newHashMap()
val y=x.filter[id==searchID]
我不会创建
地图

什么对您最有利取决于您的“环境”->有多少RAM可用/需要多快。但我认为没有比这更“优雅”的方法了

我可以更改我的map的整个实现,使其成为map,但这似乎有点过分


这有什么过分之处?它是从您的密钥到您试图获取的数据的映射,这正是应该如何使用映射的。当然,使用
Entry
类作为通用元组会带来一些问题,因此您可以使用MyValueType
定义一个新的类
ComplexWithMyValueType
(可能具有更好的特定于域的名称),以准确地表示您试图检索的数据的形状。然后你可以有一张
地图

你能解释清楚一点吗?您当前的hashmap是什么样子的
HashMap
我可以有另一个Map:Map,这可能是最合理的。
-我同意。我不认为有任何方法可以从原始映射中获取原始密钥而不进行迭代,这是没有效率的(可能有一种使用Java 8流编写原始密钥的较短方法,但它仍然需要迭代密钥集或入口集)。@karthik-值是什么并不重要,因为它在这里无关紧要(或者我是这么想的?)但如果你有想法,就说地图吧
val Long searchID = 42L
val x = <Complex, MyValueType>newHashMap()
val y = x.filter[id==searchID]