Подтвердить что ты не робот

Два неравных объекта с одним и тем же хэш-кодом

Концепция Hashcode() и equals() -

1) Если два объекта равны в соответствии с equal(), то вызов метода hashcode для каждого из этих двух объектов должен выдавать один и тот же хэш-код.

а другой -

2) Не требуется, чтобы, если два объекта не равны в соответствии с равным(), тогда вызов метода hashcode для каждого из двух объектов должен производить различные значения.

Я попробовал и понял первый, и это код для первой точки.

public class Test {
    public static void main(String[] args) {

        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        map.put(1, 11);
        map.put(4, 11);
        System.out.println(map.hashCode());
        Map<Integer, Integer> map1 = new HashMap<Integer, Integer>();
        map1.put(1, 11);
        map1.put(4, 11);
        System.out.println(map1.hashCode());
        if (map.equals(map1)) {
            System.out.println("equal ");
        }
    }
}

указанная выше программа предоставляет тот же хэш-код для двух разных объектов.

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

4b9b3361

Ответ 1

2) Не требуется, чтобы, если два объекта были неравны в соответствии с равным(), то вызов метода хэш-кода для каждого из двух объектов должен давать разные значения.

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

Например, если я хеширую целые числа и моя хеширующая функция просто (n % 10) то число 17 и число 27 приведут к одинаковому результату. Это не значит, что эти цифры одинаковы.

Ответ 2

hashCode() имеет 32-битные возможные значения. Ваши объекты могут иметь гораздо больше, чем это, поэтому у вас будут объекты с одним и тем же хэш-кодом, т.е. Вы не можете гарантировать, что они будут уникальными.

Это делается хуже в коллекции хешей ограниченного размера. Максимальная емкость HashMap равна 1 < 30 или около одного миллиарда. Это означает, что действительно используются только 30 бит, и если ваша коллекция не использует 16+ ГБ и говорит только тысячу ведер (или 1 < 10 технически), то на самом деле у вас есть только 1000 возможных ковшей.

Примечание: в JSM HotSpot по умолчанию Object.hashCode() никогда не является отрицательным, т.е. только 31-битным, хотя я не уверен, почему.

Если вы хотите создать много объектов с одинаковым хэш-кодом, посмотрите на Long.

// from Long
public int hashCode() {
    return (int)(value ^ (value >>> 32));
}

for(long i = Integer.MIN_VALUE; i < Integer.MAX_VALUE;i++) {
    Long l = (i << 32) + i;
    System.out.print(l.hashCode()+" ");
    if (i % 100 == 0)
        System.out.println();
}

Это сгенерирует 4 миллиарда Длинных всех с хэш-кодом 0.

Ответ 3

Пример со строками (все строки ниже имеют хэш-код 0):

public static void main(String[] args) {
    List<String> list = Arrays.asList("pollinating sandboxes",
                                      "amusement & hemophilias",
                                      "schoolworks = perversive",
                                      "electrolysissweeteners.net",
                                      "constitutionalunstableness.net",
                                      "grinnerslaphappier.org",
                                      "BLEACHINGFEMININELY.NET",
                                      "WWW.BUMRACEGOERS.ORG",
                                      "WWW.RACCOONPRUDENTIALS.NET",
                                      "Microcomputers: the unredeemed lollipop...",
                                      "Incentively, my dear, I don't tessellate a derangement.",
                                      "A person who never yodelled an apology, never preened vocalizing transsexuals.");
    for (String s : list) {
        System.out.println(s.hashCode());
    }
}

(украден из этого сообщения).

Ответ 4

Мне очень легко понять, знаете ли вы, как реализуется HashMap, и цель. Hashmap принимает большой набор значений и разбивает их на гораздо меньшие наборы (ведра) для более быстрого извлечения элементов. В основном вам нужно искать только одно ведро, а не полный список для вашего элемента. Ведра находятся в массиве, где индекс является хэш-кодом. Каждое ведро содержит связанный список элементов с тем же хэш-кодом, но не равно(). Я думаю, что в Java 8 они переключились на использование treemap, когда размеры ковша станут большими.

Ответ 5

Цель hashCode - включить следующую аксиому и следствие:

  • Если кто-то знает хэш-коды двух объектов, и эти хеш-коды не совпадают, вам не нужно больше изучать объекты, чтобы знать, что объекты не совпадают. Даже если два произвольно выбранных несовпадающих объекта будут иметь 10% -ный шанс наличия соответствующих хеш-кодов, тестовые хэш-коды позволят устранить 90% сравнений, которые в противном случае потребовались бы. Не такая большая победа, как устранение 99,99%, но, безусловно, стоит того же.

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

Обратите внимание, что hashCode() будет предлагать наибольшую выгоду, если каждый другой элемент возвращает другой хеш, но он может предложить существенную выгоду, даже если многие элементы имеют одно и то же значение хэш-функции. Разница между экономией в 90% и сбережением 99,99% часто намного больше, чем предполагают цифры, и, следовательно, одно, если можно разумно легко улучшить ситуацию до 99%, 99,9% или лучше, это нужно сделать, но разница между ними имеющие нулевые ложные совпадения и имеющие несколько ложных совпадений в коллекции, довольно незначительны.

Ответ 6

Это довольно просто,

Сначала мы должны знать, что такое хэш-код.

В java хэш-код прост - 32-битное целое число со знаком, которое каким-то образом получается из данных. Целочисленные типы обычно являются просто (Int Data) Mod (некоторое разумное большое простое число).

Сделайте простой хэш на целых числах. Определение:

public int hash(int num){ return num % 19 ; } 

В этом случае как 19, так и 38 вернут хеш-значение 0.

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

Учитывая, что существует сколь угодно много строк, и существует ограниченное количество хэш-кодов (2 ^ 32) для строки, принцип пурпурной дыры гласит, что существует по меньшей мере две разные строки, которые приводят к тому же хэш-коду.

Ответ 8

Я верю, что это поможет вам понять...

Хеш-код Java-объекта - это просто число, это 32-разрядное целое число со знаком, которое позволяет управлять объектом с помощью структуры данных на основе хеша. Мы знаем, что хеш-код - это уникальный идентификатор, выделенный объекту JVM. Но на самом деле хэш-код не является уникальным числом для объекта. Если два объекта равны, то эти два объекта должны возвращать один и тот же хэш-код. Таким образом, мы должны реализовать метод hashcode() класса таким образом, что если два объекта равны, то есть сравниваются с помощью метода equal() этого класса, то эти два объекта должны возвращать один и тот же хэш-код. Если вы переопределяете hashCode, вам также необходимо переопределить метод equals.

ссылка: https://www.java2novice.com/java_interview_questions/hashcode/

Ответ 9

Я понимаю, что hashCode представляет собой числовое представление адреса памяти, но не является фактическим адресом. Его можно изменить, не затрагивая фактический адрес. Таким образом, должно быть возможно установить все объекты на один и тот же хэш-код, даже если все они совершенно разные. Подумайте о том, что все на одном блоке внезапно имеют одинаковый адрес. Они действительно разные люди, но теперь все имеют одинаковый адрес. Их дом не сдвинулся с места, другой подросток назвал всех "100 N. Main".

Я новичок в Java, поэтому отвечай мой ответ с некоторой осторожностью.