Сравнение строк: == и equals
Строки сравнивают методом equals:
if (answer.equals("да")) {
System.out.println("Согласие получено");
}== у строк проверяет не текст, а то, один ли это объект в памяти. Две строки с одинаковым текстом могут быть разными объектами — тогда == вернёт false.
Почему == иногда «работает»
public class Main {
public static void main(String[] args) {
String a = "Java";
String b = "Java";
String part = "Ja";
String c = part + "va";
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a.equals(c));
System.out.println("JAVA".equalsIgnoreCase(a));
}
}true
false
true
trueОдинаковые строки, записанные прямо в коде в кавычках, Java хранит в одном экземпляре (в так называемом пуле строк). Поэтому a == b — true: это один объект. Строка c собрана во время работы программы — это новый объект, и a == c даёт false, хотя текст тот же. Строки из Scanner, из файла, из substring и replace — тоже новые объекты.
Отсюда коварство ==: в простом примере сравнение срабатывает, а в настоящей программе со вводом — нет. Не полагайтесь на него никогда.
Варианты сравнения
| Задача | Как |
|---|---|
| Тот же текст | a.equals(b) |
| Без учёта больших и маленьких букв | a.equalsIgnoreCase(b) |
Безопасно, если a может быть null | "да".equals(a) или Objects.equals(a, b) |
| По алфавиту | a.compareTo(b) — меньше нуля, ноль или больше нуля |
| Пустая ли строка | s.isEmpty() или s.isBlank() (пробелы тоже считаются пустотой) |
a.equals(b) упадёт с NullPointerException, если a равно null. Поэтому известную строку ставят слева: "да".equals(answer). Objects.equals(a, b) (из java.util) работает, даже если null оба.
А как же switch
switch по строке сравнивает через equals сам, его можно использовать без опаски:
switch (command) {
case "start" -> System.out.println("Запуск");
case "stop" -> System.out.println("Остановка");
default -> System.out.println("Неизвестная команда");
}Если command равна null, такой switch выбросит NullPointerException.
Подводные камни
- Пробелы и регистр.
"да "с пробелом в конце и"Да"с большой буквы не равны"да". Строку из ввода часто сначала чистят:answer.trim().toLowerCase(). - Символы
charсравнивают через==— это числа, не объекты:s.charAt(0) == 'а'. - Сравнение со строкой другого типа.
"5".equals(5)—false: строка не равна числу. Переведите одно в другое (справка Как перевести строку в число). - compareTo сравнивает по кодам символов. Большие буквы идут раньше маленьких, а маленькая
ё— даже послея. Для сортировки по правилам языка естьCollator(справка Как отсортировать массив или список).