Soru Garip Java karma işlevini anlama


Aşağıdaki bir karma işlevi için kaynak kodudur. java.util.HashMap. Yorumlar, neyi başardığını yeterince açıklıyor. ama nasıl? Neler var ^ ve >>> operatörler yapıyor? Birisi kodun aslında nasıl olduğunu açıklayabilir mi yapar ne yorumlar söylemek?

/**
 * Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 */
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).

    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

32
2018-02-17 20:47


Menşei


Onlar konum bitum işlemleri ayrıca bkz: docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html - Brian Roach


Cevaplar:


Dunno 'İngilizce hakkında, ama burada bir kod ve örnek çıktı:

public static void main ( String[] args ) {
    int h = 0xffffffff;
    int h1 = h >>> 20;
    int h2 = h >>> 12;
    int h3 = h1 ^ h2;
    int h4 = h ^ h3;
    int h5 = h4 >>> 7;
    int h6 = h4 >>> 4;
    int h7 = h5 ^ h6;
    int h8 = h4 ^ h7;

    printBin ( h );
    printBin ( h1 );
    printBin ( h2 );
    printBin ( h3 );
    printBin ( h4 );
    printBin ( h5 );
    printBin ( h6 );
    printBin ( h7 );
    printBin ( h8 );

}

static void printBin ( int h ) {
    System.out.println ( String.format ( "%32s", 
        Integer.toBinaryString ( h ) ).replace ( ' ', '0' ) );
}

Hangi baskılar:

11111111111111111111111111111111
00000000000000000000111111111111
00000000000011111111111111111111
00000000000011111111000000000000
11111111111100000000111111111111
00000001111111111110000000011111
00001111111111110000000011111111
00001110000000001110000011100000
11110001111100001110111100011111

Böylece, kod ne olduğunu görebilmeniz için karma işlevini adımlara ayırır. 20 pozisyonun ikinci konumu olan 12 pozisyonun ilk vardiyası, int'nin alt 20 bitinin 0 veya daha fazlasını çevirebilen bir maske oluşturur. Böylece, potansiyel olarak daha iyi dağıtılmış daha yüksek bitlerin kullanılmasını sağlayan alt bitlere eklenmiş bazı rasgeleler alabilirsiniz. Bu daha sonra, bu rastgeleliği alt bitlere eklemek için xor yoluyla orijinal değere uygulanır. 4 pozisyonun kaymasıyla 7 pozisyonun ikinci vardiyası, alt 28 bitlerin 0 veya daha fazlasını çevirebilen bir maske oluşturur. Bu da, önceki xor'dan yararlanarak alt bitlere ve daha önemli olanların bir kısmına bazı rastgelelikler getirir. Daha önce alt bitlerdeki bazı dağıtımlara değinmişti. Sonuç, karma değerinden bitlerin daha pürüzsüz bir dağılımıdır.

Java'daki hashmap, kepçeyi kepçelerin sayısı ile birleştirerek kepçe endeksini hesapladığından, girdileri her bir kepçeye eşit olarak yaymak için karma değerin alt bitlerinin eşit bir dağılımına sahip olmanız gerekir.

Bu, çarpışma sayısını sınırlandıran ifadeyi kanıtlamak için, üzerinde hiç bir girişim yok. Ayrıca, bkz. İşte hash fonksiyonları oluşturma hakkında bazı iyi bilgiler ve iki sayının xorunun sonuçta bitlerin rastgele dağılımına neden olduğu konusunda birkaç ayrıntı için.


46
2018-02-17 22:46



Philwb, cevabın için teşekkürler. Gerçekten bilmek istiyorum, Neden bu özel olarak 20,12,7 ve 4'tür. Rastgelelikleri nasıl ölçerler. Buradaki cevapların çoğu, rastgelelik vb. Tanıtıyor. Bu rastlantıyı nasıl yaratıyor? Neden doğru vardiya pozisyonları 20 olmalı, neden 21 veya 19 olamaz? Bunu da açıklayabilir misiniz? Üzgünüm bazı temel şeyleri kaçırıyorsam. - Rengasami Ramanujam
Ne yazık ki, bu spesifik vardiyaların neden seçildiğini söyleyemem. Diğer vardiyalarla bir rastgelelik elde edeceksin. Belki de bu belirli değişimler, matematiksel olarak, çarpışmaların sayısının sınırlandırıldığı iddiasına yol açar. Ancak, muhtemelen bunu daha fazla araştırmak için matematikte daha fazla akıma danışmanız gerekir. Makul bir cevap bulursanız, bunu duymak isterim. - philwb
Yani, kısacası, bu hashing değerlerden dolayı tasarlanmıştır potansiyel olarak kovalar üzerinden daha iyi dağıtılmış? - MC Emperor


>>> sıfır doldurma ile bitshift.

^ bir XOR.

XOR özel olarak da adlandırılır veya - iki sayıyı birleştiren bir matematik operatörüdür. Görmek http://en.wikipedia.org/wiki/Exclusive_or

Tarafından sağ bitshift n düşüyor gibi n sayının en düşük bitleri. Eğer sayı ise 00010111ve sen 1'e doğru kaydırdın, 00001011.


6
2018-02-17 20:49



teşekkür ederim. lütfen güncellemeye bakın - paislee
Burayı oku: en.wikipedia.org/wiki/Bitwise_operation - Dan Passaro


İşte bir Tamsayı karma işlevlerini ele alan makale ve tasarlandıkları bazı düşünceler. Çok detaylı değil, ama asıl nokta şudur:

Operasyonlar çığa ulaşmak için bir hesaplama zinciri kullanmalıdır.   Çığ, girişteki tek bir farkın biteceği anlamına gelir   Çıkış bitlerinin yaklaşık 1/2 farklı olabilir.

Temel olarak amaç, girdideki herhangi bir düzenliliği ortadan kaldırmak için tamamlayıcı karma işlevidir, çünkü bunlar karma tablosunun bozulmasına neden olabilir.


4
2018-02-17 22:05





^ olduğu bitly XOR, >>> olduğu bit kayması.


1
2018-02-17 20:49



teşekkür ederim. lütfen güncellemeye bakın - paislee
Birisi, kodun yorumların gerçekte ne yaptığını açıklayabilir mi? - cstheory.stackexchange.com Bu tür sorular için daha uygundur. - penartur


>>> imzasız sağdan bit kayması gibi görünüyor ve ^ bitly XOR

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html


0
2018-02-17 20:50





Bitwise özel VEYA imzasız doğru kaymanın birleşimidir.

Daha fazla açıklama için buraya bakınız: http://www.roseindia.net/java/master-java/bitwise-bitshift-operators.shtml


-1
2018-02-17 20:51