http://en.wikipedia.org/wiki/Hash_table

Я просматривал вики, и вот шаги, чтобы найти индекс таблицы.

hash = hashfunc(key) // calculate hash value.
index = hash % array_size // calculate index value through modulus. 

Но похоже, что в Java это делается по-другому.

static int hash(int h) {
   h ^= (h >>> 20) ^ (h >>> 12);
   return h ^ (h >>> 7) ^ (h >>> 4);
}

static int indexFor(int h, int length) {
   return h & (length-1);
}

Метод indexFor, который вычисляет индекс таблицы, кажется другим. Кто-нибудь может пролить свет на это.

Обновление:

Алгоритм хеширования может соответственно меняться, но способ вычисления индекса таблицы должен быть таким, даже если я не ошибаюсь, но я вижу конфликт в том, что делает wiki и как делает java ?.

Пример кода для тестирования:

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

public class Test {

    public static void main(String args[]) {
        Map<String, String> m = new HashMap<String, String>();
        m.put("Shane", null);
        Iterator<String> itr = m.keySet().iterator();
        while (itr.hasNext()) {
            String key = itr.next();
            int hash = hash(key.hashCode());
            System.out.println("&&& used" + "table[" + (hash & 15) + "]=" + key);
            System.out.println("%%% used" + "table[" + (hash % 15) + "]=" + key);
        }
    }

    static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }   

}

Вывод:

&&& usedtable[14]=Shane
%%% usedtable[8]=Shane

Запустите указанную выше программу, и вы увидите, что индекс таблицы отличается, когда я использую%, и индекс таблицы отличается, когда я использую &.

-1
Shane 26 Сен 2013 в 19:18
2
Какой у вас точный вопрос? Формула, которую вы видите в Википедии, - это всего лишь один из способов определения хэш-ключа / индекса. Это не должно быть так всегда.
 – 
Luiggi Mendoza
26 Сен 2013 в 19:20
@LuiggiMendoza: похоже, что один в вики и один в Java-коде различаются для вычисления индекса таблицы.
 – 
Shane
26 Сен 2013 в 19:23
И проблема в том ...
 – 
Luiggi Mendoza
26 Сен 2013 в 19:24
Судя по ссылке в википедии, похоже, вы забыли прочитать эту часть (подчеркиваю мой): Часто это делается в два этапа: <формулы, которые вы разместили в вопросе>. Примечание: хеш Java попадает в нечастую часть :).
 – 
Luiggi Mendoza
26 Сен 2013 в 19:25
1
Еще кое-что. Вы просто просматриваете код Java из OpenJDK или, возможно, из HotSpot, другие реализации JVM, такие как JRockit или IBM JVM, могут использовать совершенно другую реализацию.
 – 
Luiggi Mendoza
26 Сен 2013 в 19:28

1 ответ

Лучший ответ

Но похоже, что в Java это делается по-другому.

На самом деле они точно такие же.

hash = hashfunc(key) // calculate hash value.

Такой же как

hash = hash(key.hashCode());

А также

index = hash % array_size       (assumes the hash is unsigned)

Такой же как

return h & (length-1);

Так как длина является степенью 2.

3
Peter Lawrey 26 Сен 2013 в 19:32
Спасибо, Питер, я обновил свой вопрос образцом тестового кода ... не могли бы вы объяснить по этому поводу.
 – 
Shane
26 Сен 2013 в 19:40
Обратите внимание на (length -1), где длина является степенью 2;) т.е. вам нужно сравнить hash & 15 с hash % 16
 – 
Peter Lawrey
26 Сен 2013 в 19:59