关于Java HashSet / HashMap自定义对象的权威文档是否为关键?

时间:2013-02-19 23:54:45

标签: java hashmap hashset

我正在尝试找到关于如何使用自定义对象作为HashMap的键或作为存储在HashSet中的对象的权威文档。

通过阅读各种帖子,我发现你应该在自定义对象中覆盖两个方法equals()和hashCode()(例如Overriding equals and hashCode in Java)。

但是,当我阅读HashSetHashMap的Oracle / Sun官方Javadoc时,他们根本没有提到覆盖这些方法。这些说明是否埋在文档中的其他位置?如果是这样,我在哪里可以找到它们?

5 个答案:

答案 0 :(得分:3)

需要来覆盖equalshashCode,但您确实需要一致 equals和{ {1}}方法。

也就是说,如果hashCode,则必须是obj.equals(obj2)的情况。为了获得良好的性能,反向(非obj.hashCode() == obj2.hashCode()对象具有不等equals()值)应尽可能正常,但这不是必需的,如果您的对象具有多个,则不能始终满足2 ^ 32个州)。

默认的hashCode()equals()方法遵循这一点并具有标识语义 - 如果对象实际上是同一个对象(obj == obj2),则它们是相等的。

如果您想要值语义 - 例如,具有相同状态的两个对象相等,则应覆盖这些方法。

答案 1 :(得分:0)

Collections API根据equals()和hashCode()描述合同。如果您希望键的多个实例彼此相等,则需要按照Object类指定的契约覆盖equals()和hashCode()。

Set interface描述了合同:

  

更正式地说,集合不包含任何元素对e1和e2   e1.equals(e2),最多一个null元素。正如其名称所暗示的那样,   这个界面模拟了数学集抽象。

equals()和hashCode()的契约由Object类指定。

在“有效的Java”中,Joshua Bloch建议您在覆盖hashCode时始终覆盖equals,以避免违反这些合同。

答案 2 :(得分:0)

java.lang.Object的合同中详细讨论了这个问题。

答案 3 :(得分:0)

SetMap的文档中,它们是它们实现的接口。

要求不是任意的,它是保证接口方法按预期工作的唯一方法 - 通过能够判断哪些可能是不同Java对象的键应该被真正地视为相同的键而不是 - 例如,"abc""ab" + "c"是不同的对象,但equals的实现确保它们被视为相同的密钥。至于hashCode,需要在作为这些接口基础的数据结构中找到有意义的位置。

答案 4 :(得分:0)

据我所知,密钥必须是一个不可变对象。

  

如果它是可变的,那么在将其添加到地图后,它的哈希码可能会发生变化。   然后地图可能会遇到问题

Setting own class as key in java Hashmap

以下示例说明了这一点:

import java.util.HashMap;
class Test{

    public int i=0;
    @Override
    public int hashCode() {
        return i;
    }
}

public class Main {
    public static void main(String[] args) {

        HashMap<Test, String> hm = new HashMap<>();
        Test t1 = new Test();
        hm.put(t1, "found");

        System.out.println(hm.get(t1));

        t1.i=2;

        System.out.println(hm.get(t1));


    }


}

/*
output:
found
null
*/