Что такое хэш-коллизия

хэш-коллизия или хэш-коллизия в HashMap-это не новая тема, и я столкнулся с несколькими блогами и дискуссионными досками, объясняющими, как создать хэш-коллизию или как избежать ее неоднозначным и подробным образом. Недавно я столкнулся с этим вопросом в интервью. У меня было много вещей, чтобы объяснить, но я думаю, что это было действительно трудно точно дать правильное объяснение. Извините, если мои вопросы повторяются здесь, пожалуйста, направьте меня к точному ответу:

  1. что именно хэш-коллизия - это особенность или распространенное явление, которое ошибочно делается, но хорошо избегать?
  2. что именно вызывает хэш-столкновение-плохое определение пользовательского класса'hashCode() метод, или оставить equals() метод un-overridden при несовершенном переопределении hashCode() только метод, или это не зависит от разработчиков, и многие популярные библиотеки java также имеют классы, которые могут вызвать хэш-коллизию?
  3. что-то идет не так или неожиданно, когда хэш Столкновение происходит? Я имею в виду, есть ли причина, по которой мы должны избегать столкновения хэша?
  4. создает ли Java или, по крайней мере, пытается создать уникальный хэш-код для каждого класса во время инициализации объекта? Если нет, правильно ли полагаться только на Java, чтобы гарантировать, что моя программа не столкнется с хэш-столкновением для классов JRE? Если нет, то как избежать хэш-столкновения для хэш-карт с конечными классами, такими как String as key?

Я буду greateful если вы смогли пожалуйста делить вас ответы по одному или по всем этим вопросам.

5 ответов


что такое хэш-коллизия-это особенность или распространенное явление, которое ошибочно делается, но хорошо избегать?

Это особенность. Он возникает из природы хэш-кода: отображение из большого пространства значений в гораздо меньшее пространство значений. Будут столкновения, по замыслу и намерению.

что именно вызывает хэш-коллизию-плохое определение метода hashCode () пользовательского класса,

плохой дизайн может сделать его хуже, но это распространено в понятие.

или оставить метод equals () не переопределенным при несовершенном переопределении метода hashCode (),

нет.

или это не зависит от разработчиков, и многие популярные библиотеки java также имеют классы, которые могут вызвать хэш-коллизию?

Это действительно не имеет смысла. Хэши рано или поздно столкнутся, и плохие алгоритмы могут это сделать рано. Вот и все.

что-то идет не так или неожиданно, когда происходит хэш-столкновение?

нет, если хэш-таблица грамотно написано. Хэш-столкновение означает только то, что хэш-код не уникален, что ставит вас в вызов equals(), и чем больше дубликатов, тем хуже производительность.

Я имею в виду, есть ли причина, по которой мы должны избегать столкновения хэша?

вы должны обменять легкость вычисление против разброса значений. Нет единого черно-белого ответа.

создает ли Java или по крайней мере пытается создать уникальный hasCode для каждого класса во время инициализации объекта?

нет. Уникальный хэш-код-это противоречие в терминах.

Если нет, правильно ли полагаться только на Java, чтобы гарантировать, что моя программа не столкнется с хэш-столкновением для классов JRE? Если нет, то как избежать хэш-столкновения для хэш-карт с окончательные классы, такие как String as key?

вопрос бессмысленный. Если вы используете String у вас нет выбора в алгоритме хэширования, и вы также используете класс, чей хэш-код был обработан экспертами в течение двадцати или более лет.


что такое хэш-коллизия-это особенность или распространенное явление, которое ошибочно делается, но хорошо избегать?

  • хэш-столкновение-это именно то, что, столкновение этого хэш-кода поля на объектах...

что именно вызывает хэш-коллизию-плохое определение метода hashCode () пользовательского класса или оставить метод equals() un-overrided при несовершенном переопределении хэш-кода() метод в одиночку, или это не зависит от разработчиков и многих популярных java библиотеки также имеют классы, которые могут вызвать хэш-коллизию?

  • нет, столкновение может произойти, потому что они управляются математической вероятностью, и в таких случаях парадокс дня рождения-лучший способ объяснить это.

что-нибудь идет не так или неожиданно, когда происходит хэш-столкновение? Я имею в виду, есть ли причина, по которой мы должны избегать хэша Столкновение?

  • нет, класс String в java очень хорошо разработан, и вам не нужно искать слишком много, чтобы найти столкновение (проверьте hascode этих строк " Aa "и" BB " - > оба имеют столкновение с 2112)

обобщить: столкновение hashcode безвредно, вы знаете, что это за и почему не то же самое, что и идентификатор, используемый для доказательства равенства


что такое хэш-коллизия-это функция или обычное явление что делается ошибочно, но чего следует избегать?

ни... оба... это распространенное явление, но не ошибочное, которого хорошо избегать.

что именно вызывает хэш-коллизию-плохое определение custom метод hashCode () класса или оставить метод equals () un-переопределено при несовершенном переопределении метода hashCode() один, или это так? не до разработчиков и многих популярных java библиотеки также имеют классы, которые могут вызвать хэш-коллизию?

плохо проектируя метод hashCode (), вы можете произвести слишком много коллизий, оставляя метод equals не переопределенным, не должен напрямую влиять на количество коллизий, многие популярные библиотеки java имеют классы, которые могут вызвать коллизии (почти все классы на самом деле).

что-то идет не так или неожиданно, когда хэш-столкновение случается? Я есть ли причина, по которой мы должны избегать столкновения хэшей?

наблюдается снижение производительности, что является причиной их избежать, но программа должна продолжать работать.

создает ли Java или, по крайней мере, пытается создать уникальный хэш-код на класс во время инициации объекта? Если нет, можно ли полагаться на Java только для того, чтобы моя программа не столкнулась с хэш-коллизией для JRE и классы? Если не правильно, то как избежать хэша столкновения hashmaps с окончательными классами, такими как String в качестве ключа?

Java не пытается создать уникальный хэш-код во время инициализации объекта, но он имеет реализацию по умолчанию hashCode() и equals(). Реализация по умолчанию работает, чтобы узнать, указывают ли две ссылки на объект на один и тот же экземпляр или нет, и не полагается на содержимое (значения полей) объектов. Таким образом, класс String имеет собственную реализацию.


на самом деле я думаю, что хэш-коллизии-это нормально. Давайте поговорим о деле думать. У нас есть 1000000 больших чисел (множество S из x), скажем, x находится в 2^64. И теперь мы хотим сделать карту для этого числа. сопоставим это число S с [0,1000000].

но как? используйте хэш!!

определите хэш-функцию f (x) = x mod 1000000. И теперь x в S будет преобразован в [0,1000000), хорошо, но вы обнаружите, что многие числа в S будут преобразованы в одно число. например. этот номер k * 1000000 + y будет расположен в y, потому что (k * 1000000 + y ) % x = y. Итак, это столкновение хэшей.

и как бороться с столкновения? В этом случае мы говорили выше, очень трудно разграничить столкновение, потому что математические вычисления имеют некоторую posibillity. Мы можем найти более сложную, более хорошую хэш-функцию, но не можем определенно сказать, что мы устраняем столкновение. Мы должны приложить усилия, чтобы найти более хорошую хэш-функцию для уменьшения хэш-столкновения. Поскольку хэш-столкновение увеличивает стоимость времени, мы используем хэш, чтобы найти что-то.

просто есть два способа справиться с хэш-коллизией. связанный список является более прямым способом, например: если два числа выше получают одинаковое значение после функции hash_function, мы создаем linkedlist из этого ведра значений, и все то же значение помещается в linkedlist значения. И еще один способ - просто найти новую позицию для более позднего номера. например, если номер 1000005 занял позицию в 5 и когда 2000005 получить значение 5, он не может быть расположен в позиции 5, то идти вперед и найти пустую позицию, чтобы взял.

для последнего вопроса: создает ли Java или, по крайней мере, пытается создать уникальный хэш-код для каждого класса во время инициации объекта?

хэш-код объекта, как правило, реализуется путем преобразования внутренний адрес объекта в целое число. Таким образом, вы можете думать, что разные объекты имеют разные хэш-коды, если вы используете хэш-код объекта().


  1. хэш-столкновение происходит, когда два отдельных значения производят тот же хэш, что вы могли бы знать. Хэши производят фиксированное количество символов для данного значения, и поэтому всегда есть возможность получения двух значений одного и того же хэша, несмотря на малую вероятность. Таким образом, мы можем сказать, что он поставляется с самой хэш-функцией. При его использовании мы понимаем, что два значения могут производить один и тот же хэш. Как трудно вычислить хэш-столкновение, Google имеет успешно рассчитал столкновение SHA-1 несколько месяцев назад, если я правильно помню. https://www.theregister.co.uk/2017/02/23/google_first_sha1_collision/

  2. Я не думаю, что у меня есть знания об этом.

  3. да. Предположим, для какой-то функции мы вычисляем хэш для ее запуска. Поэтому в некоторых случаях, если человек неосознанно создает хэш-коллизию, эта конкретная функция будет работать. Это может вызвать дефект или сбой в система.