Ответ
Симметричность (Symmetry) — одно из обязательных свойств корректной реализации метода equals(Object o) в Java. Оно требует, что для любых не-null ссылок x и y, выражение x.equals(y) должно возвращать true тогда и только тогда, когда y.equals(x) возвращает true.
Нарушение симметричности — распространенная ошибка:
class CaseInsensitiveString {
private String s;
public CaseInsensitiveString(String s) { this.s = s; }
// НЕПРАВИЛЬНО: Нарушает симметричность!
@Override
public boolean equals(Object o) {
if (o instanceof CaseInsensitiveString) {
return s.equalsIgnoreCase(((CaseInsensitiveString) o).s);
}
// Опасная попытка быть совместимым с обычной String
if (o instanceof String) {
return s.equalsIgnoreCase((String) o);
}
return false;
}
}
Проблема:
CaseInsensitiveString cis = new CaseInsensitiveString("Java");
String s = "java";
cis.equals(s); // true (наш метод сравнивает без учета регистра)
s.equals(cis); // false (метод String.equals не знает о CaseInsensitiveString)
// Нарушено: cis.equals(s) != s.equals(cis)
Правильная реализация, обеспечивающая симметричность:
@Override
public boolean equals(Object o) {
// Сравниваем только с объектами того же класса
if (o == null || o.getClass() != this.getClass()) {
return false;
}
CaseInsensitiveString other = (CaseInsensitiveString) o;
return this.s.equalsIgnoreCase(other.s);
}
Почему симметричность критична? Ее нарушение приводит к непредсказуемому поведению объектов в коллекциях (HashSet, HashMap), так как эти структуры полагаются на согласованный контракт equals и hashCode.