Вопрос проверяет понимание работы метода contains в Java коллекциях, особенно важное для корректной работы с коллекциями объектов.
Метод contains в коллекциях Java (таких как ArrayList, HashSet, HashMap) использует методы equals и hashCode для определения наличия объекта. Ситуация, когда объект физически присутствует в коллекции, но contains возвращает false, возникает, если состояние объекта изменилось так, что нарушились контракты этих методов.
HashSet или HashMap изменяется после добавления, его хэш-код может измениться. Поиск в хэш-таблице происходит по новому хэш-коду, который ведёт в другую корзину (bucket), где объект отсутствует.equals и hashCode не согласованы (например, equals сравнивает по одному полю, а hashCode вычисляется по другому), то объект может быть найден по одному критерию, но не по другому.import java.util.HashSet;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Геттеры и сеттеры
public void setAge(int age) { this.age = age; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && name.equals(person.name);
}
@Override
public int hashCode() {
return 31 * name.hashCode() + age;
}
}
public class Main {
public static void main(String[] args) {
HashSet set = new HashSet<>();
Person john = new Person("John", 25);
set.add(john);
System.out.println(set.contains(john)); // true
// Меняем поле, влияющее на hashCode и equals
john.setAge(30);
System.out.println(set.contains(john)); // false! Объект всё ещё в set, но contains не находит.
}
}В этом примере после изменения возраста хэш-код объекта john изменился. HashSet ищет объект в корзине, соответствующей новому хэш-коду, но объект остался в корзине для старого хэш-кода, поэтому contains возвращает false.
Эта проблема критична при использовании пользовательских объектов в качестве ключей в HashMap, HashSet, ConcurrentHashMap или элементах в HashSet. Чтобы избежать этого:
equals и hashCode, не изменяются после добавления объекта в коллекцию.Вывод: Ситуация возможна при изменении mutable объектов в хэш-коллекциях, что нарушает механизм поиска. Используйте immutable объекты для ключей или строго контролируйте их изменение, чтобы избежать ошибок.