// The worst possible legal hash function - never use!
@Override public int hashCode() { return 42; }
Это законно, поскольку гарантирует, что равные объекты имеют одинаковый хэш-код.Это ужасно, потому что гарантирует, что каждый объект имеет одинаковый хэш-код.Поэтому каждый объект хешируется в одно и то же ведро, а хеш-таблицы вырождаются в связанные списки.Программы, которые должны работать в линейном времени, вместо этого работают в квадратичном времени.
Я пытаюсь понять вышесказанное (цитата из стр. 47, пункт 9, Эффективная Java Джошуа Блоха).
Я вижу это следующим образом (рассмотрим следующий код):
Map<String, String> h = new HashMap<String,String>();
h.put("key1", "value1");
h.put("key1", "value2");
То, что происходит со второй командой h.put("key1",...)
, выглядит следующим образом: 1. Получите хэш-код key1
2. Получитеблок, представляющий вышеуказанный хэш-код 3. Внутри этого блока для каждого объекта вызовите метод equals, чтобы определить, существует ли идентичный объект.
Это немного быстрее, потому что сначала вы находите «группу» (сегмент) объектов, а затем фактический объект.
Теперь, когда реализация хэш-кода такова, что она возвращает то же целое число (например, 42
выше) для ALL объектов, тогдатолько один сегмент, и метод equals должен вызываться один за другим для каждого объекта во всей hashmap / hashtable.Это так же плохо, как связанный список, потому что, если объекты находятся в связанном списке, то тоже придется проходить через них один за другим, сравнивая (называя равенство) каждый объект.
Вот почему, как было сказано, хеш-таблицы вырождаются в связанный список?
(Прошу прощения за многословие приведенного выше текста. Мне не яснодостаточно в моих понятиях, чтобы изложить это более кратко)