java 如果 hashtable 中的 key 是一个类对象,那么 containsKey 是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6485186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 16:04:06  来源:igfitidea点击:

If key in hashtable is a class object, how does containsKey work?

javaoophashtable

提问by bespectacled

When we put a class Object (that has say three data members) in a hashtable, how can I prevent putting another entry into the hash table whose key has the same three data members ? Cos I am guessing this will be a new object. So hashtable.containsKey() will return false even when there is a key (this class object) that has the very same data members as the one that is waiting to be inserted.

当我们将一个类 Object(即三个数据成员)放入哈希表时,如何防止将另一个条目放入哈希表中,其键具有相同的三个数据成员?因为我猜这将是一个新对象。所以 hashtable.containsKey() 将返回 false,即使有一个键(此类对象)与等待插入的键具有相同的数据成员。

More clearly: I have a class like

更清楚:我有一个类

class Triplet {
private Curr curr;
private Prev prev;
private Next next;
}

I have a hashtable structure like:

我有一个哈希表结构,如:

Hashtable<Triplet, Integer> table = new Hashtable<Triplet, Integer>();

When I do:

当我做:

if(!table.containsKey(triplet_to_inserted))
table.put(triplet, new Integer(0));

will this insert a duplicate even if the table contains a triplet that already has the same data members ? That is: triplet_to_be_inserted.curr, triplet_to_be_inserted.next and triplet_to_be_inserted.prev If yes, how to prevent this ?

即使表包含已经具有相同数据成员的三元组,这是否会插入重复项?即:triplet_to_be_inserted.curr、triplet_to_be_inserted.next 和triplet_to_be_inserted.prev 如果是,如何防止?

Also, for any entry to be inserted, will containsKey() ever return true at all ? How to work around this problem ?

此外,对于要插入的任何条目, containsKey() 是否会返回 true ?如何解决这个问题?

Thanks.

谢谢。

回答by Rob Harrop

All classes that have instances used as keys in a hash-like data structure mustcorrectly implement the equalsand hashCodemethods. Brian Goetz has a great article on thisfrom a while back.

所有在类哈希数据结构中具有用作键的实例的类都必须正确实现equalshashCode方法。不久前,Brian Goetz 发表了一篇很棒的文章

Without knowing the structure of Curr, Prevand Nextand exact example is difficult, but assuming they are not null and have sensible hashCodeimplementations, you could do something like this:

不知道Curr, Prevand的结构Next和确切的例子是困难的,但假设它们不为空并且有合理的hashCode实现,你可以做这样的事情:

public boolean equals(Object obj) {
    if (!(obj instanceof Triplet)) {
        return false;
    } else {
        Triplet that = (Triplet)obj;
        return this.curr.equals(that.curr) &&
            this.next.equals(that.next) &&
            this.prev.equals(that.prev);
    }
}

public int hashCode() {
    int hash = this.curr.hashCode();
    hash = hash * 31 + this.next.hashCode();
    hash = hash * 31 + this.prev.hashCode();
    return hash;
}

回答by Jarek Potiuk

The easiest way is to use Eclipse's generate hashCode() and equals(). You can select which members should be taken into account for the hashCode and equals calculation, so in case you have some transient members (you don't) you can only use those which are relevant.

最简单的方法是使用 Eclipse 的 generate hashCode() 和 equals()。您可以选择在 hashCode 和 equals 计算中应考虑哪些成员,因此如果您有一些临时成员(您没有),则只能使用相关的成员。

And similiarly (and recursively) for Curr, Prev and Next...

对于 Curr、Prev 和 Next 类似地(并且递归地)...

回答by Yochai Timmer

From java documentation:

从java文档:

To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCodemethod and the equalsmethod.

要从哈希表中成功存储和检索对象,用作键的对象必须实现 hashCode方法和equals方法。