Сравнение строк с возможными null в Java: методы и подходы

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы безопасно сравнивать объекты с возможностью их null значений, можно использовать метод Objects.equals(Object a, Object b):

Java
Скопировать код
boolean areEqual = Objects.equals(obj1, obj2);

Данный метод считает два null как равные значения (возвращает true), а null и не-null объекты определяются как неравные (возвращает false), благодаря чему исключается риск NullPointerException.

Кинга Идем в IT: пошаговый план для смены профессии

Устаревший код: Обработка сравнения с null

Если в вашем проекте используются версии Java старше чем 7, вам, возможно, понадобится эквивалент для Objects.equals:

Java
Скопировать код
public static boolean equals(Object a, Object b) {
    if (a == b) return true;
    if (a == null || b == null) return false;
    return a.equals(b);
}

Таким образом, вы обеспечите себя функционалом, аналогичным Objects.equals, с защитой от null.

Остерегайтесь подводных камней при сравнении строк!

Для сравнения строк с учетом null рекомендуется использовать специализированные методы, такие как StringUtils.equals из Apache Commons Lang:

Java
Скопировать код
boolean areEqual = StringUtils.equals(str1, str2);

А для Android лучше всего подходит TextUtils.equals:

Java
Скопировать код
boolean areEqual = TextUtils.equals(str1, str2);

Принимайте null значения во время сортировки

При сортировке коллекций, содержащих null, используйте null-безопасные компараторы:

Java
Скопировать код
Comparator<String> nullSafeComparator = Comparator.nullsFirst(String::compareTo);

И для сложных объектов применяйте цепочку сравнений с thenComparing:

Java
Скопировать код
Comparator<Person> comparator = Comparator
    .comparing(Person::getName, Comparator.nullsFirst(String::compareTo))
    .thenComparing(Person::getAge);

Будьте настороже: Случаи, требующие пристального внимания

Objects.equals очень удобен, но не забывайте про исключительные моменты:

  • Пользовательские объекты: Удостоверьтесь, что метод equals был корректно переопределен.
  • Примитивные типы: В этом случае Objects.equals не подойдет, используйте обёртки или сравнение напрямую.
  • Большие коллекции: Контролируйте производительность, избегая ненужных сравнений.

Визуализация

Рассмотрим примеры с появлением null в контексте карточной игры:

Сравнение:

- Объект А       – Объект B
- [ 🎴 | null ]  – [ 🎴 | 🃏 ]

Совпадение: [🎴 = 🎴] – Близнецы! 
Не совпадение: [null ≠ 🃏] – Отличия есть, близнецов нет!

Особое правило справедливо как для игр, так и для программного сравнения:

Если ОБА null = "Близнецы найдены! [🃏 = 🃏]"
Если ОДИН null = "Близнецы не обнаружены! [🎴 ≠ 🃏]"

Частые ошибки при сравнении, которые могут вам дорого обойтись

Наиболее распространённые промахи при сравнении объектов:

  1. Нарушение принципов equals: Метод должен быть рефлексивным, симметричным, транзитивным и консистентным.
  2. Игнорирование hashCode: Не забывайте о том, что необходим разумный подход к согласованности с equals.
  3. Сравнение разнотипных объектов: Различные классы объектов всегда возвращают false.
  4. Отсортированные коллекции: Уделите пользовательским компараторам особое внимание, это может изменить поведение сортировки и обработку null.

Учимся у профессионалов: Исходный код

Взгляните, как в Apache Commons Lang реализован метод StringUtils.equals:

Java
Скопировать код
public static boolean equals(final CharSequence cs1, final CharSequence cs2) {
    if (cs1 == cs2) {
        return true;
    }
    if (cs1 == null || cs2 == null) {
        return false;
    }
    if (cs1.length() != cs2.length()) {
        return false;
    }
    if (cs1 instanceof String && cs2 instanceof String) {
        return cs1.equals(cs2);
    }
    // Дополнительные проверки
}

Полезные материалы

  1. Object (Java Platform SE 7 )
  2. ObjectUtils (Apache Commons Lang 3.14.0 API)
  3. Optional (Java Platform SE 8 )
  4. Как сравнить два объекта в Java – Stack Overflow
  5. Objects (Guava: Google Core Libraries for Java 19.0 API)
  6. DZone – Безопасное сравнение объектов в Java, учитывающее null
  7. jdk8/jdk8/jdk: 687fd7c7986d src/share/classes/java/util/Objects.java