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

Тестирование равенства строк с использованием hashCode()

Есть ли причина, почему строка Java не может быть проверена на равенство, используя метод hashCode? Так что в основном, а не....

"hello".equals("hello")

Вы можете использовать...

"hello".hashCode() == "hello".hashCode()

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

4b9b3361

Ответ 1

потому что: hashCodes из двух объектов должны быть равны, если объекты равны, однако, если два объекта неравны, хэш-код все равно может быть равен.

(изменено после комментария)

Ответ 2

Позвольте мне привести встречный пример. Попробуйте это,

public static void main(String[] args) {
    String str1 = "0-42L";
    String str2 = "0-43-";

    System.out.println("String equality: " + str1.equals(str2));
    System.out.println("HashCode eqauality: " + (str1.hashCode() == str2.hashCode()));
}

Результат на моей Java,

String equality: false
HashCode eqauality: true

Ответ 3

поскольку многие хэш-коды не гарантируют уникальность. на самом деле, он не может сделать это по очень простой причине.

hashCode возвращает int, что означает, что существует 2 ^ 32 возможных значения (около 4 000 000 000), но, вероятно, более 2 ^ 32 возможных строк, что означает, что по крайней мере две строки имеют одинаковое значение хэш-кода.

это называется принцип Pigeonhole.

Ответ 4

Другие указали, почему это не сработает. Поэтому я просто добавлю добавление, что коэффициент усиления будет минимальным.

Когда вы сравниваете две строки в Java, функция String equals сначала проверяет, являются ли они двумя ссылками на один и тот же объект. Если это так, он немедленно возвращает true. Затем он проверяет, равны ли длины. Если нет, он возвращает false. Только тогда он начинает сравнивать характер за символом.

Если вы манипулируете данными в памяти, сравнение с теми же объектами может быстро справиться с "одним и тем же" случаем и что быстрое, umm, 4-байтное целое сравнение, я думаю. (Кто-то исправит меня, если у меня неправильная длина дескриптора объекта.)

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

В худшем случае для производительности будут две длинные, идентичные, но не одни и те же строковые строки. Затем он должен выполнить сравнение дескриптора объекта, false, продолжить проверку. Сравнение длины, правда, продолжайте проверять. Затем символ по символу по всей длине строки, чтобы убедиться, что да, действительно, они равны вплоть до конца.

Ответ 5

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

Вы можете сравнить возвращаемые значения intern() с помощью оператора ==. Если они ссылаются на одну и ту же строку, исходные строки эквивалентны (т.е. equals() вернул бы true), и для этого требуется только сравнение указателей (которое имеет такую ​​же стоимость, как сравнение int).

String a = "Hello";
String b = "Hel" + "lo";

System.out.println(a.equals(b));
System.out.println(a == b);

String a2 = a.intern();
String b2 = b.intern();

System.out.println(a2.equals(b2));
System.out.println(a2 == b2);

Вывод:

true
false
true
true

Ответ 6

Значение hashCode не уникально, что означает, что строки могут не совпадать. Чтобы повысить производительность, часто реализация equals будет выполнять проверку hashCode перед выполнением более трудоемких проверок.

Ответ 7

Очень простая причина: риск столкновений... Хэш-код будет иметь гораздо меньшие значения, чем строка. Это зависит от того, какой тип хэша вы создаете, но пусть возьмет очень простой пример, где вы добавите порядковые значения букв, умноженные на его позицию: a = 1, b = 2 и т.д. Таким образом, "привет" будет перевести на: h: 8x1 = 8, e: 5x2 = 10, l: 12x3 = 36, l: 12x4 = 48, o: 15x5 = 75. 8 + 10 + 36 + 48 + 75 = 177.

Существуют ли другие строковые значения, которые могут заканчиваться как 177 хешированных? Конечно! Множество вариантов. Не стесняйтесь рассчитать несколько.

Тем не менее, этот метод хэширования использовал простой метод. Java и .NET используют более сложный алгоритм хеширования с гораздо меньшим шансом на такие столкновения. Но все же существует вероятность того, что две разные строки приведут к одному и тому же значению хэша, таким образом, этот метод менее надежный.

Ответ 8

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

Ответ 9

Нет причин не использовать hashCode при описании.

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