что такое equals в java
Метод equals() в Java
Метод equals() проверяет, равны ли два объекта (например, две строки). Метод прописан для основных классов Java.
Синтаксис метода:
Вызов:
Пример:
Если Вы запустите данный код на своем компьютере, в консоли Вы увидите следующее:
Комментарии к коду:
У нас есть три строки. Первые две имеют одинаковое содержание («Good morning»), а третья отличается («Good evening»). Соответственно, сравнивая первые две сроки с помощью метода equals(), мы получаем в консоли true. Но когда мы сравниваем «Good morning» и «Good evening», получаем false.
Данная статья написана Vertex Academy. Можно пройти наши курсы Java с нуля. Детальнее на сайте.
Java / Отличия equals() от ==
Автор: elvisjagger ← к списку ← →
Метод equals() обозначает отношение эквивалентности объектов. Эквивалентным называется отношение, которое является симметричным, транзитивным и рефлексивным. Рефлексивность: для любого ненулевого x, x.equals(x) вернет true;
Транзитивность: для любого ненулевого x, y и z, если x.equals(y) и y.equals(z) вернет true, тогда и x.equals(z) вернет true;
Симметричность: для любого ненулевого x и y, x.equals(y) должно вернуть true, тогда и только тогда, когда y.equals(x) вернет true.
Также для любого ненулевого x, x.equals(null) должно вернуть false.
Отличия equals() от операции == в классе Object нет. Это видно, если взглянуть исходный код метода equals класса Object:
Однако, нужно не забывать, что, если объект ни на что не ссылается(null), то вызов метода equals этого объекта приведет к NullPointerException. Также нужно помнить, что при сравнении объектов оба они могут быть null и операция obj1 == obj2 в данном случае будет true, а вызов equals приведет к исключению NullPointerException.
Как мы видим, при помощи операции == сравниваются ссылки на объекты. Но мы можем переопределять метод equals, тем самым задавая логику сравнения двух объектов. Например, рассмотрим сравнение двух одинаковых чисел, созданных при помощи класса Integer: Если взглянуть внутрь метода equals класса Integer, то мы увидим: Понятно, что тут уже нет сравнения ссылок, а сравниваются int значения.
Если Вам понравился вопрос, проголосуйте за него
Голосов: 68 Голосовать
В общем случае в Java используются операторы equals () и «==» для сравнения объектов с целью проверки равенства, но здесь есть некоторые различия между ними:
// Java-программа для понимания
// понятие оператора ==
public static void main(String[] args)
String s1 = new String( «HELLO» );
String s2 = new String( «HELLO» );
Выход:
Объяснение: Здесь мы создаем два объекта, а именно s1 и s2.
Давайте разберемся с обоими операторами в деталях:
Оператор равенства (==)
Мы можем применять операторы равенства для всех примитивных типов, включая булевы. мы также можем применять операторы равенства для типов объектов.
// Java-программа для иллюстрации
// == оператор для совместимых данных
// типы
public static void main(String[] args)
System.out.println( 10 == 20 );
System.out.println( ‘a’ == ‘b’ );
System.out.println( ‘a’ == 97.0 );
System.out.println( true == true );
Выход:
Если мы применяем == для типов объектов, то должна быть совместимость между типами аргументов (либо потомок к родителю, либо родитель к потомку, либо того же типа). В противном случае мы получим ошибку времени компиляции.
// Java-программа для иллюстрации
// == оператор для несовместимых типов данных
public static void main(String[] args)
Thread t = new Thread();
Object o = new Object();
String s = new String( «GEEKS» );
// Раскомментируйте, чтобы увидеть ошибку
Выход:
.equals ()
В Java метод string equals () сравнивает две заданные строки на основе данных / содержимого строки. Если все содержимое обеих строк одинаково, возвращается значение true. Если все символы не совпадают, возвращается false.
public static void main(String[] args)
Thread t1 = new Thread();
Thread t2 = new Thread();
String s1 = new String( «GEEKS» );
String s2 = new String( «GEEKS» );
Выход:
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
В предыдущей части, если не читали вот она, мы подробно рассмотрели работу метода equals(), его контракт, ошибки и их исправления. Теперь настала очередь второго попугая-неразлучника – метода hashCode().
При переопределении метода equals() мы всегда должны переопределять метод hashCode(). Метод hashCode() – вычисляет целочисленное значение для конкретного элемента класса, чтобы использовать его для быстрого поиска и доступа к этому элементу в hash-структурах данных, например, HashMap, HashSet и прочих. Почему важно переопределять hashCode() всегда вместе с методом equals()? Развернуто ответим на этот вопрос. Пожалуй, необходимо и достаточно знать два важных аспекта, чтобы понять, почему необходимо делать переопределение методов вместе:
Что такое хеш-таблицы (Hash Tables)?
Хэш – таблицы – это своего рода ассоциативный массив, хранящий значения в виде “ключ-значение”. Рассмотрим работу вставки элемента в хеш-таблицу:
На деле все просто, но если еще раз перечитать контракт hashCode() и equals(), то все становиться немного труднее: возможны коллизии – два разных объекта имеют одинаковый hash-код. Что делать? Эта проблема и ее решение отражены на рисунке выше. Два объекта John Smith и Sandra Dee имеют один и тот же hash-код. Для разрешения это коллизии мы просто берем за структуру bucket направленный список. И сохраняем два значения по одному hash-коду.
Как сломать хеш – таблицу?
При неверной реализации метода hashCode() мы можем легко сломать hash-таблицу. Вернее даже сказать не сломать, а сделать ее вырожденной. Например, переопределив метод hashCode() следующим образом
Что такое equals в java
Сравнение доменных объектов по их физическому адресу может вызывать интересный эффект: два абсолютно одинаковых объекта оказываются не равны.
Чтобы продемонстрировать проблему воспользуемся сравнением двух точек:
Программа выведет на консоль сообщение:
1. Рефлексивность
Для каждого экземпляра x должно выполнятся условие:
2. Симметричность
Для каждого экземпляра x и y x.equals(y) должен возвращать true только тогда, когда y.equals(x) возвращает true:
3. Переносимость
Для каждого экземпляра x, y и z должно выполнятся условие: если x.equals(y) возвращает true и y.equals(z) возращает true, тогда x.equals(z) должно возращать true
4. Консистентность
Для каждого экземпляра x и y повторное выполнение x.equals(y) должно возвращать одинаковый результат:
5. Сравнение с null
Для каждого экземпляра x x.equals(null) должно возвращать false:
Переопределение equals
Исправим исходный код программы в соответсвии с контрактами:
и запустим ещё раз:
С помощью переопределения equals шанс появления фантомных объектов исключён.
Переопределяя equals не забывайте о hashCode
Переопределение equals всегда сопровождается изменением hashCode. Некоторые контейнеры, такие как java.util.Set, перед проверкой схожести объектов сверяют их хэш.
Переопределение hashCode также сопровождается рядом правил (контрактов):
1. Консистентность
Для каждого экземпляра x повторное выполнение x.hashCode() должно возвращать одинаковый хэш:
2. Схожие объекты имеют одинаковый хэш
Если два экземпляра схожи друг с другом, то вызов hashCode() у каждого из них должен возвращать одинаковый результат:
Однако у разных объектов хэш может не совпадать.
Переопределение hashCode
Подсчет хэша объекта базируется на атрибутах используемых при проверке «схожести»:
запуск программы выведет на консоль:
Выводы
Переопределение equals нельзя делать на скорую руку. Несоблюдение одного из контрактов неочевидны и могут повлечь серъезные последствия.
Например, расширяя класс Point в ColorPoint нарушается контракт симметричности. Поэтому в методе Point.equals проверку instanceof следует заменить на obj.getClass().equals(Point.class).
С другой стороны проверяя схожесть объектов необходимость в поиске фантомов снижается. Исходный код становится более читаемым.