4

今日面接を受けて、次の Java コードを入手しました。

public class Question_6 {
    public static void main(String[] args){
        Map<Integer,String> map1 = new HashMap<Integer,String>();
        map1.put(new Integer(1),"001a");
        map1.put(new Integer(1),"001b");
        map1.put(new Integer(2),"002");

        System.out.println(map1.size());

        Map<MyInt,String> map2 = new HashMap<MyInt,String>();
        map2.put(new MyInt(1),"001a");
        map2.put(new MyInt(1),"001b");
        map2.put(new MyInt(2),"002");

        System.out.println(map2.size());

    }

}
public class MyInt {
    int i;
    public MyInt(int i) {
       this.i = i;
    }

}

質問は次のとおりです。

  1. コンソールには何が出力されますか?

  2. 問題の解決策を提案します。

最初の質問に対する答えは次のとおりです。

2

3

しかし、私は理由を知りませんか?何が問題なのMyIntですか?

4

7 に答える 7

12

あなたの問題は、equals()hashcode()実装されていないことMyIntです。

2どちらの場合も結果として期待されます。

HashMapは、その名前が示すように、キーのhashcode()に基づいてキーをバケットにグループ化します。ただし、デフォルトのハッシュコードは、同じ値を持つ の2 つのインスタンスには一致しません。MyInt

同等かどうかを判断するには、オーバーライドequals()も必要です。

1 つの解決策:

public class MyInt {

    [...]

    @Override
    public int hashCode() {
       return value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof MyInt) {
            return i == ((MyInt)obj).i;
        }
        return false;
    }

}
于 2013-05-29T16:33:50.833 に答える
3

isを理解できるように、クラスのequals()andhashCode()メソッドをオーバーライドする必要があります。MyIntHashMapnew MyInt(1).equals(new MyInt(1))true

于 2013-05-29T16:33:43.507 に答える
2

Integer クラスはequals()メソッドをオーバーライドして、値ベースの比較を行います。ハッシュマップには「等しい」2 つのキーを含めることはできないため、map1 への 2 回目の挿入によって最初のエントリが上書きされます。同様に、hashcode()メソッドはオーバーライドされます。

equals()ただし、 MyInt はorメソッドをオーバーライドしないhashcode()ため、等価性はメモリ位置に基づいています。したがって、map2 は 3 つの異なるキーを認識し、3 つの異なるエントリを作成します。

    Map<MyInt,String> map2 = new HashMap<MyInt,String>();
    MyInt one = new MyInt(1);
    MyInt two = new MyInt(2);
    map2.put(one,"001a");
    map2.put(one,"001b");
    map2.put(two,"002");

    System.out.println(map2.size());

2この場合は one.equals(one) が true であるため、この場合は出力が生成されます。

于 2013-05-29T16:34:42.497 に答える
0

hashCode()およびメソッドをオーバーライドする必要がありますequals。equals が 2 つのオブジェクトに対して true を返すすべてのケースで、hashCode は同じ値を返します。ハッシュ コードは、2 つのオブジェクトが等しい場合に等しくなければならないコードです。

どうして??

HashMap.putメソッドのソースコードで調べると。このメソッドは、挿入前にと の両方hashcodeをチェックすることがわかります。equalityしたがって、これらのメソッドをオーバーライドしないと、オブジェクトごとに異なる値を返すスーパークラス (オブジェクトの) メソッドが使用されます。したがって、同じキーに対して 2 つの値が の別々の場所に挿入されHashmapます。したがって、これら2つをオーバーライドし、2つの等しいオブジェクトに対して同じを返す必要があることを確認する必要がありますhashcode

コード

したがって、 MyInt は次のようになります

public class MyInt {
    int i;
    public MyInt(int i) {
       this.i = i;
    }        

    public int hashCode() {
       return i;
    }    

    public boolean equals(Object obj) {
        if (obj instanceof MyInt && i == ((MyInt)obj).i) {
            return true;
        } else
            return false;
    }
}
于 2013-05-29T16:54:29.773 に答える