Kluczowym pytaniem jest klucz. (Żadna gra słów nie jest przeznaczona.) Jak wskazali inni, celem jest zminimalizowanie liczby kolizji mieszania. Jeśli możesz uzyskać liczbę konfliktów mieszania do zera, tj. Twoja funkcja mieszająca generuje unikalną wartość dla każdego klucza, który jest do niej przekazywany, otrzymasz doskonały skrót.
Należy zauważyć, że w języku Java funkcja mieszania ma naprawdę dwa kroki: Najpierw klucz jest uruchamiany przez funkcję hashCode dla swojej klasy. Następnie obliczyć wartość indeksu do tabeli mieszania, biorąc tej wartości modulo rozmiar tabeli mieszania.
Myślę, że ludzie dyskutujący o idealnej funkcji skrótu zwykle zapominają o tym drugim kroku. Nawet jeśli napisałeś funkcję hashCode, która wygenerowała unikalną wartość dla każdego przekazanego do niej klucza, nadal możesz uzyskać absolutnie straszny hasz, jeśli ta wartość modulo rozmiar tabeli mieszającej nie jest unikalny. Na przykład powiedzmy, że masz 100 kluczy, a funkcja hashCode zwraca wartości 1, 1001, 2001, 3001, 4001, 5001, ... 99001. Jeśli twój stół hash ma 100 000 miejsc, będzie to doskonały skrót. Każdy klucz ma swój własny slot. Ale jeśli ma 1000 slotów, wszystkie mają hash do tego samego gniazda. Byłby to najgorszy możliwy haszysz.
Należy więc rozważyć skonstruowanie dobrej funkcji skrótu. Weź ekstremalne przypadki. Załóżmy, że kluczem jest data. Wiesz, że wszystkie daty będą w styczniu tego samego roku. Następnie użyj dnia miesiąca, ponieważ wartość mieszania powinna być tak dobra, jak to będzie: wszystko będzie mieszało się z unikalną liczbą całkowitą w małym zakresie. Z drugiej strony, jeśli twoje daty byłyby pierwszymi miesiącami przez wiele lat i wiele miesięcy, przyjęcie dnia miesiąca byłoby okropnym haszyszem, ponieważ każdy rzeczywisty klucz zamieniłby się na "1".
Chodzi mi o to, że jeśli naprawdę chcesz zoptymalizować swój hash, musisz znać charakter swoich danych. Jaki jest rzeczywisty zakres wartości, które otrzymasz?
jaki jest twój klucz? – jjnguy
Publikowanie tego jako komentarza, ponieważ tak naprawdę nie odpowiada na twoje pytanie. Ale jeśli używasz java.util.Hashtable, nie. Użyj java.util.HashMap zamiast: –