tgoop.com/physics_lib/14619
Create:
Last Update:
Last Update:
В Java существует важное правило (контракт):
1. Если две строки равны по equals(), то их hashCode() ДОЛЖЕН быть одинаковым
2. Обратное не обязательно верно: одинаковый hashCode() не гарантирует равенства строк
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1.equals(s2)); // true
System.out.println(s1.hashCode() == s2.hashCode()); // true
System.out.println(s1.equals(s3)); // true
System.out.println(s1.hashCode() == s3.hashCode()); // true
Метод hashCode() в классе String вычисляется на основе содержимого строки:
public int hashCode() {
int h = hash; // кэшированное значение
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}➖ Вычисляется по формуле:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]➖ Результат кэшируется в поле hash для производительности
➖ Для одинакового содержимого всегда одинаковый hashCode, независимо от того, как была создана строка
➖ value и hash — являются полями класса String и уже существуют в объекте, когда вызывается метод hashCode().
value — массив символов, который хранит собственно содержимое строки. Он инициализируется при создании объекта.
String s = "Hello"; // value = {'H', 'e', 'l', 'l', 'o'}hash — поле для кэширования вычисленного хэш-кода. Оно инициализируется по умолчанию значением 0.
Практическое применение в коллекциях: Связь hashCode и equals критически важна для работы хэш-коллекций:
🔸 HashMap/HashSet
Map<String, Integer> map = new HashMap<>();
map.put("Hello", 1);
map.put(new String("Hello"), 2); // Затрет предыдущее значение!
System.out.println(map.size()); // 1 - потому что ключи равны по equals()
1. Сначала сравниваются hashCode() — если разные, объекты точно разные
2. Если hashCode одинаковые, тогда вызывается equals() для точной проверки
🔸 Оптимизация сравнения
String s1 = "very long string ...";
String s2 = "another very long string ...";
// Сначала проверяется hashCode - быстрая операция
if (s1.hashCode() == s2.hashCode() && s1.equals(s2)) {
// Строки точно равны
}
▪️ 1. Коллизии хэшей — Разные строки могут иметь одинаковый hashCode (хэш-коллизия)
String a = "Aa";
String b = "BB";
System.out.println(a.hashCode()); // 2112
System.out.println(b.hashCode()); // 2112
System.out.println(a.equals(b)); // false
▪️ 2. Производительность
// Медленно - создается новый объект и вычисляется hashCode
String s1 = new String("Hello");
// Быстро - используется кэшированный hashCode из String Pool
String s2 = "Hello";
3. String Pool и hashCode
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
// Все три имеют одинаковый hashCode, но разные способы создания
System.out.println(s1.hashCode()); // одинаковый
System.out.println(s2.hashCode()); // одинаковый
System.out.println(s3.hashCode()); // одинаковый
🔍 Важные моменты. HashCode тесно связан со сравнением строк через:
1. Контракт Java — равные строки по equals() должны иметь одинаковый hashCode
2.. Оптимизацию сравнения — хэш используется для быстрой предварительной проверки
3. Работу коллекций — HashMap, HashSet и другие используют эту связь для эффективного хранения и поиска
#java #задачи #программирование #собеседования #IT #структуры_данных
💡 Physics.Math.Code // @physics_lib

