Вопрос

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

"hello".equals("hello")

Вы могли бы использовать...

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

это называется Принцип разделения по ячейкам.

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

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

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

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

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

Вы можете получить желаемый эффект, используя 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

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

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

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

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

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

Нет никаких причин не использовать хэш-код, как вы описываете.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top