自定义对象作为HashMap中的键。

huangapple go评论120阅读模式
英文:

Custom object as a key in HashMap

问题

众所周知,我们可以在Java HashMap中使用任何对象作为键,前提是它遵循equals和hashCode的约定。
但我在某处读到过,如果自定义对象是不可变的,那么这个问题就已经得到了解决。
那么这是否意味着,如果我的自定义对象是不可变的,我就不需要重写hashCode和equals方法,以使其适用于作为哈希映射的键呢?

我理解这是错误的,即使我的自定义对象是不可变的,为了使其适用于哈希映射键,仍然需要重写hashCode和equals方法。
如果你们有不同看法,请评论一下。

英文:

As we all know, we can use any Object as key in Java HashMap provided it follows equals and hashCode contract.
But I have read it somewhere that - if the custom object is Immutable than this will be already taken care.
So does it mean if my custom object is immutable I don't need to override hashcode and equals method to make it eligible for using it as key of my hashmap.

My understanding is this is wrong, even if my custom object is immutable it has to override hashcode and equals method in order to make it eligible for hashmap key.
Please comment if you guys think otherwise.

答案1

得分: 2

构建地图不会是一个问题,除非对象的哈希码发生冲突,否则每个条目都将是唯一的。然而,基于键进行搜索将会是一个问题。由于它是不可变的,你实际上无法创建与地图中的键相匹配的键。

{
        HashMap<ImmutableKey, String> map = new HashMap<>();
        ImmutableKey key = new ImmutableKey("A", "B");
        map.put(key, "Test");
        map.put(new ImmutableKey("A", "B"), "Test1");
        map.put(new ImmutableKey("A", "B"), "Test2");
        map.put(new ImmutableKey("A", "B"), "Test3");

        System.out.println(map);
        String data = map.get(new ImmutableKey("A", "B"));
        System.out.println(data);

}

final class ImmutableKey {
    private String key;
    private String value;

    public ImmutableKey(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }
}
英文:

Constructing the map will not be a problem, and each of your entry, unless the object's hashcode collides will be unique. However searching based on key will be a problem. As its immutable, you really cannot create the key which can match the key in the map.

{
        HashMap&lt;ImmutableKey, String&gt; map = new HashMap&lt;&gt;();
        ImmutableKey key = new ImmutableKey(&quot;A&quot;, &quot;B&quot;);
        map.put(key, &quot;Test&quot;);
        map.put(new ImmutableKey(&quot;A&quot;, &quot;B&quot;), &quot;Test1&quot;);
        map.put(new ImmutableKey(&quot;A&quot;, &quot;B&quot;), &quot;Test2&quot;);
        map.put(new ImmutableKey(&quot;A&quot;, &quot;B&quot;), &quot;Test3&quot;);

        System.out.println(map);
        String data = map.get(new ImmutableKey(&quot;A&quot;, &quot;B&quot;));
        System.out.println(data);

}

final class ImmutableKey {
    private String key;
    private String value;

    public ImmutableKey(String key, String value) {
        this.key = key;
        this.value = value;
    }

    public String getKey() {
        return key;
    }

    public String getValue() {
        return value;
    }
}

答案2

得分: 0

Immutability意味着多个方面,但在其最基本的形式中,一旦创建对象,就无法更改对象。这在哈希查找中可能很有用,但您可能想到的是持久性,这是一个相关但独立的概念,其中对对象的更改会返回一个新对象,而不是更改现有对象(写时复制语义)。

然而,要理解为什么不可变性或持久性可以帮助哈希查找,就需要理解如何实现基本哈希码和相等性方法。幸运的是,这些实现通常相当简单:只需返回对象在内存中的位置。这通常效果不佳,因为即使类的两个实例的数据完全相同,它们在内存中的位置也会不同。如果要对没有setter的类进行哈希处理,通常仍然需要基于成员计算相等性和哈希值。

对于持久性,这可能很有用,因为持久性数据结构(例如hash array mapped trie)通常对于以不同方式构造的两个结构返回完全相同的对象,例如 set(&quot;a&quot;).add(&quot;b&quot;).id == set(&quot;a&quot;, &quot;b&quot;).id。随后,持久性数据结构可以使用ID有效地进行哈希和相等性比较。

所以,为了回答您最初的问题,您应该在没有setter的类上实现hashCodeequals方法 自定义对象作为HashMap中的键。

英文:

Immutability means several things, but in its most basic form that you can’t change an object once it is made. This can be useful in hash lookups, but what you’re probably thinking of is persistence, which is a related but separate concept where changes to an object return a new object instead of changing the existing one (copy on write semantics).

However, to understand why either immutability or persistence can help with hash lookups, understanding how the base hash code and equality methods are implemented is required. Luckily, these implementations are usually fairly straight forward: just return the object’s position in memory. This usually doesn’t work well because two instances of a class will have two different positions in memory even if the data in the class is exactly the same. If you want to hash a class with no setters, you generally still need to calculate the equality and hash based on the members.

With persistence, this can be useful because a persistent data structure (such as hash array mapped trie) generally returns literally the same object for two structures constructed differently, e.g. set(&quot;a&quot;).add(&quot;b&quot;).id == set(&quot;a&quot;, &quot;b&quot;).id. Subsequently, a persistent data structure can use the ID for hashing and equality effectively.

So, to answer your original question, you should implement hashCode and equals on your class without setters 自定义对象作为HashMap中的键。

huangapple
  • 本文由 发表于 2020年9月11日 12:46:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63840923.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定