У чому полягає використання хеш-коду на Java?


161

У Java obj.hashCode()повертає деяке значення. У чому полягає використання цього хеш-коду в програмуванні?


Це питання додає ще кілька деталей. stackoverflow.com/questions/18078779 / ...
MaheshVarma

1
приємне пояснення, дане в цій публікації. eclipsesource.com/blogs/2012/09/04 / ...
Віджай Vankhede

Відповіді:


222

hashCode()використовується для bucketing в Hashреалізації подобається HashMap, HashTable, HashSetі т.д.

Значення, отримане від hashCode(), використовується як номер відра для зберігання елементів набору / карти. Цей номер відра - це адреса елемента всередині набору / карти.

Коли ви contains()це зробите , візьмете хеш-код елемента, тоді шукайте відро, на яке вказує хеш-код. Якщо в одному відрі знайдено більше 1 елемента (кілька об'єктів можуть мати один і той же хеш-код), то він використовує equals()метод для визначення, чи об'єкти рівні, а потім вирішує, чи contains()правда чи помилка, або вирішує, чи може елемент бути додано в набір чи ні.


28
Привіт приятелю. Дуже приємна відповідь, але я знайшов дуже цікаве посилання на те саме, з легким для розуміння практичним прикладом: coderanch.com/t/321515/java/java/HashCode
Logicalj

Дякую Айшу Тепер я отримав чіткі знання про хеш-код із поясненням, пов’язаним із відра.
Баласубрамані

2
"якщо в одному відрі знайдено більше 1 елемента. тоді він використовує equals()для оцінки", і що, якщо знайдений лише один елемент хеш-коду, відповідний, він повертає істину безпосередньо? але оскільки кілька об'єктів можуть мати один і той же хеш-код, тож він повинен запуститись, equals()щоб оцінити, чи збігається елемент рівний, інакше це може дати вам несподіваний результат, я прав?
Саорікідо

Відра в сторону, хеш-код - це метод, який об'єкт викликає для визначення порядку зберігання кожного об'єкта в пам'яті. Якщо об’єкти рівні, то їх хеш-код також повинен бути рівним. (зворотне це твердження хибне)
NoName

1
У якому випадку програміст вручну викликає hashCode()метод?
Кардинал - Відновіть Моніку

33

Від Javadoc :

Повертає значення об'єкта хеш-коду. Цей метод підтримується на користь хештелів, таких, як це надано java.util.Hashtable.

Загальний контракт Росії hashCode:

  • Кожного разу, коли він під час виконання програми Java викликає один і той же об'єкт не один раз, hashCodeметод повинен послідовно повертати одне ціле ціле число , за умови, що жодна інформація, що використовується в порівнянні з об'єктом, не змінюється. Це ціле число не повинно залишатися послідовним від одного виконання програми до іншого виконання тієї самої програми.

  • Якщо два об'єкти рівні відповідно до equals(Object)методу, то виклик hashCodeметоду на кожному з двох об'єктів повинен давати однаковий цілий результат.

  • Він НЕ вимагає , що якщо два об'єкти неравен в відповідно до equals(java.lang.Object)методом, потім викликаючи hashCodeметод на кожному з двох об'єктів повинні виробляти різні результати цілочисельних. Однак програмісту слід пам’ятати, що отримання чітких цілих результатів для неоднакових об’єктів може покращити продуктивність хештелів.

Наскільки це практично практично, метод хеш-коду, визначений класом Object, повертає окремі цілі числа для різних об'єктів. (Зазвичай це реалізується шляхом перетворення внутрішньої адреси об'єкта в ціле число , однак ця техніка реалізації не потрібна мові програмування Java.)


14

Значення, що повертається, hashCode()- хеш-код об'єкта, який є шістнадцятковою адресою пам'яті об'єкта.

За визначенням, якщо два об'єкти рівні, їх хеш-код також повинен бути рівним. Якщо ви перекриєте equals()метод, ви змінюєте спосіб рівняння двох об'єктів, і реалізація об'єкта hashCode()вже не є дійсною. Тому, якщо ви перекриєте метод equals (), ви також повинні перекрити hashCode()метод.

Ця відповідь отримана з офіційної документації по навчальному посібнику java SE 8


13

hashCode()це функція, яка приймає об'єкт і виводить числове значення. Хеш-код для об'єкта завжди однаковий, якщо об'єкт не змінюється.

Такі функції, як HashMap, HashTableі HashSetт. Д., hashCodeЯким потрібно зберігати об'єкти, будуть використовувати модуль розміром їх внутрішнього масиву, щоб вибрати, в якому "положенні пам'яті" (тобто позиції масиву) зберігати об'єкт.

Є деякі випадки, коли можуть статися зіткнення (два об’єкти закінчуються одним і тим же хеш-кодом), і це, звичайно, потрібно ретельно вирішити.


6

Хоча хеш-код не робить нічого з вашої бізнес-логіки, ми мусимо про це подбати в більшості випадків. Тому що, коли ваш об'єкт поміщений у контейнер на основі хешу (HashSet, HashMap ...), контейнер ставить / отримує хеш-код елемента.


Ні, це не так. Він кладе / отримує ключ. Хеш-код використовується лише для видобутку,
Маркіз Лорн

3

Хеш - код є число , що генерується з будь-якого об'єкта.

Саме це дозволяє швидко зберігати / отримувати об’єкти в Hashtable.

Уявіть наступний простий приклад :

На столі перед вами. у вас дев'ять коробок, кожен з яких позначений цифрами від 1 до 9. У вас також є купа дико різних предметів, які потрібно зберігати в цих скриньках, але, як тільки вони там знаходяться, ви повинні мати можливість їх знайти якнайшвидше.

Що вам потрібно - це спосіб миттєво визначити, у яке поле ви поставили кожен об'єкт. Це працює як індекс. Ви вирішили знайти капусту, щоб ви подивилися, в якій коробці знаходиться капуста, а потім перейдіть прямо до цього поля, щоб отримати її.

Тепер уявіть, що ви не хочете турбуватися з індексом, ви хочете відразу ж дізнатися з об'єкта, у якому вікні він живе.

У прикладі скористаємось дійсно простим способом цього - кількістю літер в назві об’єкта. Отже, капуста йде у вікні 7, горох - у вікні 3, ракета - у коробці 6, банджо - у коробці 5 тощо.

А як із носорогом? Він має 10 символів, тож ми трохи змінимо наш алгоритм і «обернемось», щоб 10-літерні об’єкти переходили в поле 1, 11 букв у графі 2 тощо. Це повинно охоплювати будь-який об’єкт.

Іноді в коробці буде більше одного предмета, але якщо ви шукаєте ракету, все ж набагато швидше порівняти арахіс і ракету, ніж перевірити цілу купу кукурудзи, гороху, банджо і рисоцерозів.

Це хеш-код. Спосіб отримання числа від об'єкта, щоб він міг зберігатися в Hashtable. У Java хеш-кодом може бути будь-яке ціле число, і кожен тип об'єкта відповідає за генерування свого. Пошук методу "hashCode" об'єкта.

Джерело - тут


-1

Одним із застосувань hashCode () є побудова механізму лову . Подивіться на цей приклад:

        class Point
    {
      public int x, y;

      public Point(int x, int y)
      {
        this.x = x;
        this.y = y;
      }

      @Override
      public boolean equals(Object o)
      {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Point point = (Point) o;

        if (x != point.x) return false;
        return y == point.y;
      }

      @Override
      public int hashCode()
      {
        int result = x;
        result = 31 * result + y;
        return result;
      }

class Line
{
  public Point start, end;

  public Line(Point start, Point end)
  {
    this.start = start;
    this.end = end;
  }

  @Override
  public boolean equals(Object o)
  {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Line line = (Line) o;

    if (!start.equals(line.start)) return false;
    return end.equals(line.end);
  }

  @Override
  public int hashCode()
  {
    int result = start.hashCode();
    result = 31 * result + end.hashCode();
    return result;
  }
}
class LineToPointAdapter implements Iterable<Point>
{
  private static int count = 0;
  private static Map<Integer, List<Point>> cache = new HashMap<>();
  private int hash;

  public LineToPointAdapter(Line line)
  {
    hash = line.hashCode();
    if (cache.get(hash) != null) return; // we already have it

    System.out.println(
      String.format("%d: Generating points for line [%d,%d]-[%d,%d] (no caching)",
        ++count, line.start.x, line.start.y, line.end.x, line.end.y));
}

Що означає "побудова механізму лову"? І як цей код це ілюструє?
Маркіз Лорнський

-1

hashCode()це унікальний код, який генерується JVM для кожного створення об'єкта.

Ми використовуємо hashCode()для виконання деякої операції над алгоритмом хешування, наприклад Hashtable, Hashmap тощо.

Переваги hashCode()спрощують операцію пошуку, оскільки, коли ми шукаємо об’єкт, який має унікальний код, це допомагає виявити цей об’єкт.

Але ми не можемо сказати, що hashCode()це адреса об'єкта. Це унікальний код, згенерований JVM для кожного об'єкта.

Ось чому алгоритм хешування на сьогоднішній день є найпопулярнішим алгоритмом пошуку.


4
Хеш-код не унікальний. 2 нерівні об'єкти можуть повернути той же хеш-код.
Раніель Канлас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.