0

hashCode()メソッドを間違って実装した場合に直面する可能性のある問題を理解しようとしています。

たとえば、クラスHashExのすべてのインスタンスに対して静的に同じハッシュ値(100)を返すサンプルクラスを作成してから、さまざまな操作HashExHashSet/で使用しようとしました。HashMap

HashSet -> add,read,contains
HashMap -> put,get

これまでのところ、すべての操作が正常に機能しているようです。このワイルドなアイデアについて何か考えはありますか?この間違った実装がどこでhashCode()問題を引き起こすのかを理解しようとしていますか?

public class HashEx {

    public int id;
    public String name;

    public static void main(String[] args){

        HashEx e1 = new HashEx();
        e1.id=1;
        e1.name="Tom";

        HashEx e2 = new HashEx();
        e2.id=2;
        e2.name="Jerry";

        // set
        HashSet<HashEx> myset = new HashSet<HashEx>();
        myset.add(e1);
        myset.add(e2);

        System.out.println("Set size : "+ myset.size());
        for(HashEx e : myset){
            System.out.println("id: " + e.id + ", name: " + e.name);
        }

        HashEx e4 = new HashEx();
        e4.id = 2;
        e4.name = "Jerry";

        System.out.println("myset.contains(e4) : " + myset.contains(e4));

        // map
        HashMap<HashEx, String> map = new HashMap<HashEx, String>();

        map.put(e1, "Tom");
        map.put(e2, "Jerry");

        System.out.println("Map size : "+ map.size());
        System.out.println(map.get(e1));
        System.out.println(map.get(e2));
    }

    @Override
    public boolean equals(Object obj) {
        if(((HashEx)obj).id != id)
            return false;
        if(!((HashEx)obj).name.equals(name))
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        return 100;
    }
}
4

1 に答える 1

0

不正な動作が見られないという意味で、(クラスに正しくequals(Object)実装している限り)すべてが適切に機能します。HashEx

しかし、これらのオブジェクトを大量にHashSet(または のキーとしてHashMap) 取得すると、パフォーマンスが非常に低下し始めます。オブジェクトは に基づいてバケットに入れられhashCode、コレクション操作の 1 つが完了するたびに、同じバケット内のすべてのオブジェクトを直線的に検索する必要があります。

したがって、問題を実証するためのより良いテストは、(プログラムがメモリ不足になるか、プログラムを強制終了するまで) オブジェクトの追加を開始するループを作成し、10,000 オブジェクトごとにステータス メッセージを出力することです。追加操作がますます遅くなることがわかります (二次的に)。

代わりにオブジェクトが異なるhashCode場合、操作はまったく (あまり) 遅くならず、はるかに速くメモリ不足になります。

于 2012-07-08T15:36:25.753 に答える