20

Hashcode() and equals() concept is

1) If two Objects are equal according to equal(), then calling the hashcode method on each of those two objects should produce same hashcode.

and other one is

2) It is not required that if two objects are unequal according to the equal(), then calling the hashcode method on each of the two objects must produce distinct values.

I tried and understood first one and this is the code for first point.

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

        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        map.put(1, 11);
        map.put(4, 11);
        System.out.println(map.hashCode());
        Map<Integer, Integer> map1 = new HashMap<Integer, Integer>();
        map1.put(1, 11);
        map1.put(4, 11);
        System.out.println(map1.hashCode());
        if (map.equals(map1)) {
            System.out.println("equal ");
        }
    }
}

the above program gives same hashcode for two different objects.

Can someone explain me with an example,how can two different objects which are unequal according to the equals() have same hashcode.

4

9 に答える 9

30

2) equal() に従って2 つのオブジェクトが等しくない場合、2 つのオブジェクトのそれぞれで hashcode メソッドを呼び出すと、異なる値が生成される必要はありません。

ハッシュ関数によっては、2 つの異なるオブジェクトが同じハッシュ コードを持つ場合があります。ただし、同じ2つのオブジェクトは、ハッシュされたときに同じ結果を生成する必要があります(誰かが乱数を使用してハッシュ関数を実装していない限り、その場合は役に立ちません)

たとえば、整数をハッシュしていて、ハッシュ関数が単純な(n % 10)場合、数値17と数値27は同じ結果を生成します。これは、これらの数値が同じであることを意味しません。

于 2013-05-06T14:20:47.577 に答える
8

文字列の例 (以下のすべての文字列のハッシュコードは 0 です):

public static void main(String[] args) {
    List<String> list = Arrays.asList("pollinating sandboxes",
                                      "amusement & hemophilias",
                                      "schoolworks = perversive",
                                      "electrolysissweeteners.net",
                                      "constitutionalunstableness.net",
                                      "grinnerslaphappier.org",
                                      "BLEACHINGFEMININELY.NET",
                                      "WWW.BUMRACEGOERS.ORG",
                                      "WWW.RACCOONPRUDENTIALS.NET",
                                      "Microcomputers: the unredeemed lollipop...",
                                      "Incentively, my dear, I don't tessellate a derangement.",
                                      "A person who never yodelled an apology, never preened vocalizing transsexuals.");
    for (String s : list) {
        System.out.println(s.hashCode());
    }
}

(この投稿から盗まれた)。

于 2013-05-06T14:22:17.513 に答える
8

hashCode() には 32 ビットの可能な値があります。オブジェクトはこれよりもはるかに多く持つことができるので、同じ hashCode を持ついくつかのオブジェクトを持つことになります。つまり、それらが一意であることを保証できません。

これは、限られたサイズのハッシュ コレクションではさらに悪化します。HashMap の最大容量は 1 << 30 または約 10 億です。これは、実際に使用されるのは 30 ビットのみであることを意味し、コレクションが 16 GB 以上を使用せず、1000 個のバケット (または技術的には 1 << 10) しか使用しない場合、実際には可能なバケットは 1000 個しかありません。

注: HotSpot JVM では、デフォルトの Object.hashCode() が負になることはありません。つまり、31 ビットのみです。ただし、理由はわかりません。

同じ hashCode を持つオブジェクトをたくさん生成したい場合は、Long を見てください。

// from Long
public int hashCode() {
    return (int)(value ^ (value >>> 32));
}

for(long i = Integer.MIN_VALUE; i < Integer.MAX_VALUE;i++) {
    Long l = (i << 32) + i;
    System.out.print(l.hashCode()+" ");
    if (i % 100 == 0)
        System.out.println();
}

これにより、hashCode が 0 の 40 億の Long がすべて生成されます。

于 2013-05-06T14:20:24.790 に答える
5

HashMap の実装方法とその目的を知っていれば、理解するのは簡単ではありません。Hashmap は大量の値のセットを受け取り、それらをより小さなセット (バケット) に分割して、要素をより高速に取得します。基本的に、要素の完全なリストではなく、1 つのバケットのみを検索する必要があります。バケットは、インデックスがハッシュ コードである配列内にあります。各バケットには、同じハッシュコードを持つ要素のリンクされたリストが含まれていますが、equal() ではありません。Java 8 では、バケットのサイズが大きくなると、ツリーマップの使用に切り替えたと思います。

于 2016-04-18T14:42:52.547 に答える
0

Actullay、このリンクは、ハッシュコードがより明確に等しい場合に何が起こるかを説明しています。

http://www.javamadesoeasy.com/2015/02/hashmap-custom-implementation.html

于 2016-07-22T18:48:36.193 に答える
0

の目的はhashCode、次の公理と結果を可能にすることです。

  • たまたま 2 つのオブジェクトのハッシュ コードを知っていて、それらのハッシュ コードが一致しない場合、それらのオブジェクトが一致しないことを知るためにオブジェクトをさらに調べる必要はありません。任意に選択された 2 つの一致しないオブジェクトが一致するハッシュ コードを持つ可能性が 10% であったとしても、ハッシュ コードをテストすることで、そうでなければ必要となる比較の 90% を排除できます。99.99% を排除するほど大きな勝利ではありませんが、それでも価値があることは間違いありません。

  • 束の中のどのオブジェクトも特定のハッシュ コードを持っていないという知識は、その束の中のどのオブジェクトもそのハッシュ コードを持つオブジェクトと一致しないことを意味します。オブジェクトのコレクションをハッシュ コードが偶数のオブジェクトと奇数のオブジェクトに分割し、ハッシュ コードがたまたま偶数である特定のアイテムがあるかどうかを調べたい場合、何も調べる必要はありません。奇数ハッシュ項目のコレクション内。同様に、偶数ハッシュ コレクションで奇数ハッシュ アイテムを探す必要もありません。したがって、2 つの値のハッシュであっても、検索速度がほぼ半分になる可能性があります。コレクションを小さなパーティションに分割すると、さらに高速化できます。

hashCode()異なるアイテムごとに異なるハッシュが返される場合に最大のメリットが得られますが、多くのアイテムが同じハッシュ値を持つ場合でも大きなメリットが得られることに注意してください。多くの場合、90% の節約と 99.99% の節約の差は、数値が示唆するよりもはるかに大きくなります。誤った一致がゼロで、コレクションにいくつかの誤った一致があることは非常にわずかです。

于 2013-12-06T18:06:22.570 に答える
-1

私の理解では、hashCode はメモリ アドレスの数値表現ですが、実際のアドレスではありません。実際のアドレスに影響を与えずに変更できます。したがって、すべてのオブジェクトがまったく異なるものであっても、すべてのオブジェクトを同じ hashCode に設定できるはずです。あるブロックにいる全員が突然同じ住所になったとします。彼らはまったく別人ですが、今では全員が同じ住所を共有しています。彼らの家は動かず、いたずら好きな 10 代の若者は、全員に「100 N. Main」というラベルを付けただけでした。

私はJavaにかなり慣れていないので、返信には少し注意してください。

于 2013-05-06T14:23:42.190 に答える