1

カスタム オブジェクトを HashMap のキーとして、または HashSet に格納されたオブジェクトとして使用する方法に関する決定的なドキュメントを見つけようとしています。

さまざまな投稿を読んで、カスタム オブジェクトで equals() と hashCode() の 2 つのメソッドをオーバーライドする必要があることを発見しました (たとえばJava での equals と hashCode のオーバーライド)。

ただし、 HashSetおよびHashMapの Oracle/Sun 公式 Javadoc を読んだとき、これらのメソッドのオーバーライドについてはまったく言及されていません。これらの指示はドキュメントの別の場所に埋め込まれていますか? もしそうなら、どこでそれらを見つけることができますか?

4

5 に答える 5

3

andをオーバーライドする必要はありませんが、一貫したandメソッドが必要です。equalshashCode equalshashCode

つまり、 の場合obj.equals(obj2)、 の場合に違いありませんobj.hashCode() == obj2.hashCode()。逆 (equals()異なるhashCode()値を持つ非オブジェクト) は、良好なパフォーマンスを得るためにできるだけ頻繁に true にする必要がありますが、これは要件ではなく、オブジェクトの状態が 2^32 を超える場合は常に満たされるとは限りません)。

デフォルトequals()hashCode()メソッドはこれに従い、同一性セマンティクスを持ちます。オブジェクトは、実際に同じオブジェクト (obj == obj2) である場合にのみ同等です。

値のセマンティクスが必要な場合 (たとえば、同じ状態の 2 つのオブジェクトが等しい場合)、それらのメソッドをオーバーライドする必要があります。

于 2013-02-20T00:10:41.113 に答える
0

SetとのドキュメントMapでは、それらが実装するインターフェイスです。

要件は任意ではありません。たとえば、異なるJavaオブジェクトである可能性のあるキーを実際に同じキーとして処理する必要があるかどうかを判断できるようにすることで、インターフェイスのメソッドが期待どおりに機能することを保証する唯一の方法です。 、"abc"および"ab" + "c"は異なるオブジェクトですが、の実装equalsにより、それらが同じキーと見なされることが保証されます。に関してはhashCode、これらのインターフェースの基礎となるデータ構造内に意味のある配置を見つける必要があります。

于 2013-02-20T00:08:30.007 に答える
0

私の知る限り、キーは不変オブジェクトでなければなりません。

変更可能である場合、マップに追加した後にハッシュコードが変更される可能性があります。その後、マップはそれを見つけるのに問題が発生する可能性があります

Javaハッシュマップでキーとして独自のクラスを設定する

これを説明する例を次に示します。

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
*/
于 2013-02-20T00:08:50.853 に答える
0

Collections API は、equals() と hashCode() の観点からコントラクトを記述します。キーの複数のインスタンスを互いに等しくしたい場合は、 Object クラスで指定された規約に従って equals() と hashCode() をオーバーライドする必要があります。

Set インターフェイスは、そのコントラクトを記述します。

より正式には、セットには、e1.equals(e2) のような要素 e1 と e2 のペアが含まれず、最大でも 1 つの null 要素が含まれます。その名前が示すように、このインターフェイスは数学的集合の抽象化をモデル化します。

equals() と hashCode() のコントラクトは、Object クラスによって指定されます。

Joshua Bloch は、「Effective Java」で、 をオーバーライドhashCodeするときは常にオーバーライドしてequals、これらの規約に違反しないようにすることを提案しています。

于 2013-02-20T00:06:41.213 に答える
0

java.lang.Objectの契約で詳細に説明されています。

于 2013-02-20T00:06:52.877 に答える