Как уже указывалось, в вашей реализации хэш-кода слишком много коллизий, и исправление должно привести к достойной производительности. Кроме того, поможет кэширование hashCodes и эффективная реализация equals.
Если вам нужно оптимизировать еще больше:
По вашему описанию есть только (52 * 51/2) * (52 * 51 * 50/6) = 29304600 различных ключей (из которых 26000000, то есть около 90%, будут присутствовать). Следовательно, вы можете создать хеш-функцию без каких-либо коллизий и использовать простой массив вместо хеш-карты для хранения ваших данных, уменьшая потребление памяти и увеличивая скорость поиска:
T[] array = new T[Key.maxHashCode];
void put(Key k, T value) {
array[k.hashCode()] = value;
T get(Key k) {
return array[k.hashCode()];
}
(Как правило, невозможно разработать эффективную хеш-функцию без столкновений, которая хорошо кластеризуется, поэтому HashMap будет терпеть коллизии, что приводит к некоторым накладным расходам)
Предполагая, что a
и b
отсортированы, вы можете использовать следующую хеш-функцию:
public int hashCode() {
assert a[0] < a[1];
int ahash = a[1] * a[1] / 2
+ a[0];
assert b[0] < b[1] && b[1] < b[2];
int bhash = b[2] * b[2] * b[2] / 6
+ b[1] * b[1] / 2
+ b[0];
return bhash * 52 * 52 / 2 + ahash;
}
static final int maxHashCode = 52 * 52 / 2 * 52 * 52 * 52 / 6;
Я думаю, что это без столкновений. Доказательство этого оставлено в качестве упражнения для математически склонного читателя.