Сравнение строк с возможными null в Java: методы и подходы
Быстрый ответ
Чтобы безопасно сравнивать объекты с возможностью их null значений, можно использовать метод Objects.equals(Object a, Object b)
:
boolean areEqual = Objects.equals(obj1, obj2);
Данный метод считает два null как равные значения (возвращает true
), а null и не-null объекты определяются как неравные (возвращает false
), благодаря чему исключается риск NullPointerException
.
Устаревший код: Обработка сравнения с null
Если в вашем проекте используются версии Java старше чем 7, вам, возможно, понадобится эквивалент для Objects.equals
:
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:
boolean areEqual = StringUtils.equals(str1, str2);
А для Android лучше всего подходит TextUtils.equals
:
boolean areEqual = TextUtils.equals(str1, str2);
Принимайте null значения во время сортировки
При сортировке коллекций, содержащих null
, используйте null
-безопасные компараторы:
Comparator<String> nullSafeComparator = Comparator.nullsFirst(String::compareTo);
И для сложных объектов применяйте цепочку сравнений с thenComparing
:
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 = "Близнецы не обнаружены! [🎴 ≠ 🃏]"
Частые ошибки при сравнении, которые могут вам дорого обойтись
Наиболее распространённые промахи при сравнении объектов:
- Нарушение принципов
equals
: Метод должен быть рефлексивным, симметричным, транзитивным и консистентным. - Игнорирование
hashCode
: Не забывайте о том, что необходим разумный подход к согласованности сequals
. - Сравнение разнотипных объектов: Различные классы объектов всегда возвращают
false
. - Отсортированные коллекции: Уделите пользовательским компараторам особое внимание, это может изменить поведение сортировки и обработку
null
.
Учимся у профессионалов: Исходный код
Взгляните, как в Apache Commons Lang реализован метод StringUtils.equals
:
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);
}
// Дополнительные проверки
}
Полезные материалы
- Object (Java Platform SE 7 )
- ObjectUtils (Apache Commons Lang 3.14.0 API)
- Optional (Java Platform SE 8 )
- Как сравнить два объекта в Java – Stack Overflow
- Objects (Guava: Google Core Libraries for Java 19.0 API)
- DZone – Безопасное сравнение объектов в Java, учитывающее null
- jdk8/jdk8/jdk: 687fd7c7986d src/share/classes/java/util/Objects.java