Как вычисляется hashCode () в Java

Какое значение возвращает метод hashCode() в java?

Я читал, что это ссылка на память объекта … Когда я печатаю hash-значение для new Integer(1) оно равно 1; для String("a") равно 97.

Я смущен: это ASCII или какой тип ценности?

8 Solutions collect form web for “Как вычисляется hashCode () в Java”

Хеш-код представляет собой целочисленное значение, представляющее состояние объекта, на котором он был вызван. Вот почему Integer , установленный в 1, вернет hash-код «1», потому Integer's hash-код Integer's и его значение – одно и то же. Хэш-код символа равен ASCII-символьному коду. Если вы пишете настраиваемый тип, вы несете ответственность за создание хорошей hashCode , которая лучше всего будет представлять состояние текущего экземпляра.

Значение, возвращаемое hashCode() , никоим образом не гарантируется как адрес памяти объекта. Я не уверен в реализации в classе Object , но имейте в виду, что большинство classов переопределяют hashCode() таким образом, что два экземпляра, семантически эквивалентные (но не одинаковые экземпляры), будут иметь хеш с тем же значением. Это особенно важно, если classы могут использоваться в другой структуре данных, например Set, которая полагается на hashCode , согласующейся с equals .

Нет hashCode() который однозначно идентифицирует экземпляр объекта независимо от того, что. Если вам нужен hash-код, основанный на базовом указателе (например, в реализации Sun), используйте System.identityHashCode() – это будет делегировать метод hashCode по умолчанию, независимо от того, был ли он переопределен.

Тем не менее даже System.identityHashCode() может возвращать один и тот же hash для нескольких объектов. См. Комментарии для объяснения, но вот примерная программа, которая непрерывно генерирует объекты, пока не найдет два с тем же System.identityHashCode() . Когда я запускаю его, он быстро обнаруживает два значения System.identityHashCode() которые совпадают, в среднем после добавления к карте около 86 000 объектов с длинной оболочкой (и обертки Integer для ключа).

 public static void main(String[] args) { Map map = new HashMap<>(); Random generator = new Random(); Collection counts = new LinkedList<>(); Long object = generator.nextLong(); // We use the identityHashCode as the key into the map // This makes it easier to check if any other objects // have the same key. int hash = System.identityHashCode(object); while (!map.containsKey(hash)) { map.put(hash, object); object = generator.nextLong(); hash = System.identityHashCode(object); } System.out.println("Identical maps for size: " + map.size()); System.out.println("First object value: " + object); System.out.println("Second object value: " + map.get(hash)); System.out.println("First object identityHash: " + System.identityHashCode(object)); System.out.println("Second object identityHash: " + System.identityHashCode(map.get(hash))); } 

Пример вывода:

 Identical maps for size: 105822 First object value: 7446391633043190962 Second object value: -8143651927768852586 First object identityHash: 2134400190 Second object identityHash: 2134400190 

Если вы хотите знать, как они имплантированы, я предлагаю вам прочитать источник. Если вы используете IDE, вы можете просто + на интересующем вас методе и посмотреть, как реализуется метод. Если вы не можете этого сделать, вы можете использовать Google для источника.

Например, Integer.hashCode () реализуется как

  public int hashCode() { return value; } 

и String.hashCode ()

  public int hashCode() { int h = hash; if (h == 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; } hash = h; } return h; } 

Метод hashCode() часто используется для идентификации объекта. Я думаю, что реализация Object возвращает указатель (а не реальный указатель, но уникальный идентификатор или что-то в этом роде) объекта. Но большинство classов переопределяют метод. Как class String . Два объекта String имеют не тот же указатель, но они равны:

 new String("a").hashCode() == new String("a").hashCode() 

Я думаю, что наиболее распространенное использование для hashCode() – в Hashtable , HashSet и т. Д.

Объект Java API Object hashCode ()

Изменить: (из-за недавнего downvote и на основе статьи я читал о параметрах JVM)

С помощью параметра JVM -XX:hashCode вы можете изменить способ вычисления hash-кода (см. Выпуск 222 бюллетеня специалистов по Java).

HashCode == 0: просто возвращает случайные числа без отношения к тому, где в памяти находится объект. Насколько я могу судить, глобальное чтение-запись семян не оптимально для систем с большим количеством процессоров.

HashCode == 1: подсчитывает значения хеш-кода, не уверен, с какого значения они начинаются, но он кажется довольно высоким.

HashCode == 2: всегда возвращает тот же самый hash-код идентификатора 1. Это можно использовать для проверки кода, который использует идентификатор объекта. Причина, по которой JavaChampionTest вернула URL Kirk в приведенном выше примере, заключается в том, что все объекты возвращали один и тот же hash-код.

HashCode == 3: подсчитывает значения hash-кода, начиная с нуля. Он не выглядит streamобезопасным, поэтому несколько streamов могут генерировать объекты с одним и тем же hash-кодом.

HashCode == 4: Это, похоже, имеет некоторое отношение к местоположению памяти, в котором был создан объект.

HashCode> = 5: Это алгоритм по умолчанию для Java 8 и имеет семя для каждой нити. Он использует схему Xor-shift Marsaglia для получения псевдослучайных чисел.

Я читал, что это ссылка на память объекта.

Нет. Object.hashCode() используется для возврата адреса памяти около 14 лет назад. Не с.

какой тип ценности

Все зависит от того, на каком classе вы говорите, и не имеет ли он переопределенного `Object.hashCode ().

Object.hashCode (), если память правильно работает (проверьте JavaDoc для java.lang.Object), зависит от реализации и будет меняться в зависимости от объекта (Sun JVM получает значение из значения ссылки на объект ).

Обратите внимание: если вы реализуете какой-либо нетривиальный объект и хотите правильно хранить его в HashMap или HashSet, вы ДОЛЖНЫ переопределить hashCode () и equals (). hashCode () может делать все, что вам нравится (это вполне легально, но субоптимально, чтобы он возвращался 1.), но очень важно, чтобы ваш метод equals () возвращал true, тогда значение, возвращаемое hashCode () для обоих объектов, равно.

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

 public static int murmur3_32(int paramInt1, char[] paramArrayOfChar, int paramInt2, int paramInt3) { /* 121 */ int i = paramInt1; /* */ /* 123 */ int j = paramInt2; /* 124 */ int k = paramInt3; /* */ /* */ int m; /* 127 */ while (k >= 2) { /* 128 */ m = paramArrayOfChar[(j++)] & 0xFFFF | paramArrayOfChar[(j++)] < < '\020'; /* */ /* 130 */ k -= 2; /* */ /* 132 */ m *= -862048943; /* 133 */ m = Integer.rotateLeft(m, 15); /* 134 */ m *= 461845907; /* */ /* 136 */ i ^= m; /* 137 */ i = Integer.rotateLeft(i, 13); /* 138 */ i = i * 5 + -430675100; /* */ } /* */ /* */ /* */ /* 143 */ if (k > 0) { /* 144 */ m = paramArrayOfChar[j]; /* */ /* 146 */ m *= -862048943; /* 147 */ m = Integer.rotateLeft(m, 15); /* 148 */ m *= 461845907; /* 149 */ i ^= m; /* */ } /* */ /* */ /* */ /* 154 */ i ^= paramInt3 * 2; /* */ /* */ /* 157 */ i ^= i >>> 16; /* 158 */ i *= -2048144789; /* 159 */ i ^= i >>> 13; /* 160 */ i *= -1028477387; /* 161 */ i ^= i >>> 16; /* */ /* 163 */ return i; /* */ } 

Если вам действительно интересно узнать, прочитайте этот код в Hashing.class;

Здесь первый параметр HASHING_SEED рассчитывается на основе кода ниже

  { long nanos = System.nanoTime(); long now = System.currentTimeMillis(); int SEED_MATERIAL[] = { System.identityHashCode(String.class), System.identityHashCode(System.class), (int) (nanos >>> 32), (int) nanos, (int) (now >>> 32), (int) now, (int) (System.nanoTime() >>> 2) }; // Use murmur3 to scramble the seeding material. // Inline implementation to avoid loading classes int h1 = 0; // body for (int k1 : SEED_MATERIAL) { k1 *= 0xcc9e2d51; k1 = (k1 < < 15) | (k1 >>> 17); k1 *= 0x1b873593; h1 ^= k1; h1 = (h1 < < 13) | (h1 >>> 19); h1 = h1 * 5 + 0xe6546b64; } // tail (always empty, as body is always 32-bit chunks) // finalization h1 ^= SEED_MATERIAL.length * 4; // finalization mix force all bits of a hash block to avalanche h1 ^= h1 >>> 16; h1 *= 0x85ebca6b; h1 ^= h1 >>> 13; h1 *= 0xc2b2ae35; h1 ^= h1 >>> 16; HASHING_SEED = h1; } 

второй параметр – это char-массив из String, третий всегда ‘0’, а четвертый – длина массива символов.

И приведенный выше расчет предназначен только для хеш-кода String.

Для всего целого его хеш-код будет его целочисленным значением. Для char (до двух букв) это будет ASCII-код.

Насколько это разумно практично, метод hashCode, определенный classом Object, возвращает разные целые числа для разных объектов. (Обычно это осуществляется путем преобразования внутреннего адреса объекта в целое число, но этот способ реализации не требуется языком программирования Java ™).

https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#hashCode–

  • Конструкция JTable для синхронизации с внутренней структурой данных
  • запустить exe, который упакован внутри банки
  • Прочитать файл по строкам в обратном порядке
  • сервер tomcat не запускает сервер и приложение в STS
  • Java String array: существует ли размер метода?
  • Является ли null объектом?
  • Как применить двойную к int в Java, округляя ее?
  • SwingPropertyChangeSupport для динамического обновления JTextArea
  • Поиск значения max / min в массиве примитивов с использованием Java
  • Как отправить PUT, DELETE HTTP-запрос в HttpURLConnection?
  • Как я могу объединить два массива в Java?
  • Давайте будем гением компьютера.