4

次のコードでは、2 つのマップに対して同じハッシュ コードが生成されます。アイデアはありますか?


import java.util.HashMap;
import java.util.Map;

public class Foo
{
    @SuppressWarnings("unchecked")
    public static void main (String[] args)
    {
        Map map;

        map = new HashMap();

        map.put("campaignId", 4770L);
        map.put("location", "MINI_PROFILE");
        map.put("active", "true");
        map.put("lazy", true);

        System.out.println(map.hashCode());

        map = new HashMap();

        map.put("campaignId", 4936L);
        map.put("location", "MINI_PROFILE");
        map.put("active", "true");
        map.put("lazy", false);

        System.out.println(map.hashCode());


    }
}

結果は次のとおりです。

-1376467648
-1376467648

コードで 2 つの異なるハッシュ コードを生成するには、キー名を変更するだけで十分です。

4

4 に答える 4

9

単なる偶然の一致だと思います...衝突が発生する可能性があり、この場合、最初の値の関連するさまざまなビットが効果的に失われているように見えます。

ただし、違いはありません。ハッシュ コードを使用するものはすべて、衝突に対処する必要があります。

編集:ハッシュがたまたま計算される方法です。このコードは、何が起こっているかを示しています。

import java.util.*;

public class Test
{
    @SuppressWarnings("unchecked")
    public static void main (String[] args)
    {
        AbstractMap.SimpleEntry[] entries = {
            new AbstractMap.SimpleEntry("campaignId", 4770L),
            new AbstractMap.SimpleEntry("campaignId", 4936L),
            new AbstractMap.SimpleEntry("lazy", true),
            new AbstractMap.SimpleEntry("lazy", false)
        };
        for (AbstractMap.SimpleEntry entry : entries) {
            System.out.println(entry + ": " + entry.hashCode());
        }
    }
}

結果:

campaignId=4770: -1318251287
campaignId=4936: -1318251261
lazy=true: 3315643
lazy=false: 3315617

したがって、あるペアでは、最初のマップのハッシュは 2 番目のマップよりも 26小さく、別のペアでは、最初のマップのハッシュは 2 番目のマップよりも 26 大きくなります。

AbstractMapハッシュ値を合計するだけなので(順序が無関係であることを確認する1つの方法)、2つは同じハッシュコードになります。

それは本当にBoolean.hashCode()次のようになります。

return value ? 1231 : 1237;

...そしてLong.hashCode()これは次のようになります:

return (int)(value ^ (value >>> 32));

彼らがたまたま選んだ値を考えると、値が 26 (または 26 * 2^32) しか離れていないBoolean.hashCode()場合、同じことが起こります。long

于 2010-09-02T20:23:14.437 に答える
6

これは単なる偶然だと思います。AbstractMap#hashCode() の Javadoc から:

マップのハッシュ コードは、マップの entrySet() ビュー内の各エントリのハッシュ コードの合計として定義されます。

Entry#hashCode() の場合:

このマップ エントリのハッシュ コード値を返します。マップ エントリ e のハッシュ コードは次のように定義されます。

 (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
 (e.getValue()==null ? 0 : e.getValue().hashCode())

したがって、マップのハッシュ コードは、マップに含まれるキーと値の両方に基づいています。明確な理由もなく、2 つのマップが同じハッシュ コードを持つ奇妙な状況が発生しています。

于 2010-09-02T20:24:48.180 に答える
3

衝突が起こります。実際、 hashCode() をオーバーライドして、すべてに対して常に 0 を返すようにすることができます。HashMapこれは正しいでしょう (ただし、多くの構造が遅くなります)。

于 2010-09-02T20:28:19.850 に答える
0

偶然ではありません。

文字列オブジェクトは両方で同じです。同じオブジェクトは同じハッシュコードを与えます。

于 2013-06-21T12:07:39.653 に答える