1. Сравнение ссылок и содержимого
В Java строки — это объекты, а не примитивы. Когда вы пишете переменные a и b, они могут указывать на одну и ту же строку в пуле строк. А вот c, созданная через конструктор, — это уже другой объект. Оператор == сравнивает именно ссылки, а не текст.
String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a == b); // true (скорее всего, интернированная строка)
System.out.println(a == c); // false (разные объекты)
Демонстрация ошибки
String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1 == s2); // false
Хотя строки выглядят одинаково, это разные объекты в памяти.
2. equals(): сравнение содержимого строк
Чтобы сравнить именно содержимое, используйте метод equals() — он сравнивает строки посимвольно (с учётом регистра).
String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1.equals(s2)); // true
Пример: сравнение паролей
String inputPassword = "Secret123";
String realPassword = "Secret123";
if (inputPassword.equals(realPassword))
{
System.out.println("Доступ разрешён!");
}
else
{
System.out.println("Пароль неверен.");
}
Важно!
Если хотя бы один объект равен null, вызов equals() приведёт к NullPointerException. Безопасный шаблон:
if ("что-то".equals(someString)) { ... }
3. equalsIgnoreCase(): сравнение без учёта регистра
Когда важно игнорировать регистр (например, ввод пользователя), используйте equalsIgnoreCase().
String name1 = "Ivan";
String name2 = "ivan";
System.out.println(name1.equalsIgnoreCase(name2)); // true
Пример: сравнение email-адресов
String email1 = "User@Example.com";
String email2 = "user@example.com";
if (email1.equalsIgnoreCase(email2))
{
System.out.println("Почты совпадают!");
}
Коротко: equals vs equalsIgnoreCase
| Метод | Учитывает регистр? | Пример "Java" vs "java" |
|---|---|---|
|
Да | |
|
Нет | |
4. compareTo(): лексикографическое сравнение строк
Метод compareTo() выполняет лексикографическое сравнение (словари). Возвращает отрицательное число, если первая строка «меньше», 0 — равны, положительное — если «больше».
System.out.println("apple".compareTo("banana")); // < 0
System.out.println("apple".compareTo("apple")); // 0
System.out.println("banana".compareTo("apple")); // > 0
a.compareTo(b) →
< 0 — если a идёт раньше b
0 — если равны
> 0 — если a идёт после b
compareTo()
Как это работает?
- Сравнение идёт слева направо по Unicode-кодам символов.
- При первом различии возвращается разница кодов символов.
- Если одна строка — префикс другой, более короткая «меньше».
System.out.println("cat".compareTo("catalog")); // < 0 ("cat" короче)
System.out.println("catalog".compareTo("cat")); // > 0
Пример: сортировка массива строк
String[] fruits = {"banana", "apple", "pear"};
Arrays.sort(fruits); // внутри используется compareTo()
System.out.println(Arrays.toString(fruits)); // [apple, banana, pear]
compareToIgnoreCase()
System.out.println("Java".compareToIgnoreCase("java")); // 0
5. Методы startsWith() и endsWith()
Методы startsWith() и endsWith() проверяют начало и конец строки, возвращая true/false.
String fileName = "document.pdf";
String url = "https://www.google.com";
System.out.println(fileName.startsWith("doc")); // true
System.out.println(fileName.endsWith(".txt")); // false
System.out.println(url.startsWith("https://")); // true
Зачем это нужно: валидация форматов (имён файлов, URL) и фильтрация по префиксам/суффиксам (например, все ".jpg").
6. Метод contains(): ищем подстроку
contains(CharSequence s) — простой способ проверить наличие подстроки. Чувствителен к регистру.
String text = "Добро пожаловать в мир Java!";
System.out.println(text.contains("мир")); // true
System.out.println(text.contains("C++")); // false
Чтобы игнорировать регистр, приведите обе строки к одному регистру: toLowerCase()/toUpperCase().
7. Методы toLowerCase() и toUpperCase()
Возвращают новую строку, преобразованную в нижний или верхний регистр. Полезно для регистронезависимого сравнения и форматирования.
String title = "Java Programming";
String lower = title.toLowerCase();
String upper = title.toUpperCase();
System.out.println(lower); // java programming
System.out.println(upper); // JAVA PROGRAMMING
8. Метод split(): разбиваем строку на части
split(String regex) разбивает строку по разделителю (регулярное выражение) и возвращает массив String[].
Пример 1: по запятым
String names = "Alex,Maria,Ivan,Elena";
String[] nameArray = names.split(",");
for (String name : nameArray)
{
System.out.println(name.trim()); // trim() убирает возможные пробелы
}
// Вывод:
// Alex
// Maria
// Ivan
// Elena
Пример 2: по пробелам
String sentence = "Я изучаю Java";
String[] words = sentence.split(" ");
for (String word : words)
{
System.out.println(word);
}
// Вывод:
// Я
// изучаю
// Java
Особенности:
- Разделитель — это регэксп. Спецсимволы нужно экранировать (например, точка: "\\.").
- Метод всегда возвращает массив, даже из одного элемента.
9. Практика: сравниваем строки в реальном приложении
String registeredEmail = "user@example.com";
String registeredPassword = "Secret123";
Scanner console = new Scanner(System.in);
System.out.print("Введите email: ");
String email = console.nextLine();
System.out.print("Введите пароль: ");
String password = console.nextLine();
// Сравниваем email без учета регистра, а пароль — с учетом
if (email.equalsIgnoreCase(registeredEmail) && password.equals(registeredPassword))
{
System.out.println("Добро пожаловать!");
}
else
{
System.out.println("Неверный email или пароль.");
}
Комментарии: для почты используем equalsIgnoreCase(), а для пароля — строго equals(). Оператор == для строк использовать нельзя — он сравнивает ссылки.
10. Типичные ошибки при сравнении строк
Ошибка №1: Сравнение строк через == вместо equals()
Оператор == сравнивает ссылки, а не содержимое, поэтому результат может быть неожиданным.
Ошибка №2: Вызов equals() на объекте, который может быть null
Вызывайте метод на заведомо не-null объекте или используйте Objects.equals(a, b).
Ошибка №3: Игнорирование регистра, когда это важно
Например, пароли должны сравниваться с учётом регистра. Уточняйте требования.
Ошибка №4: Сравнение строк с объектами других типов
"123" и 123 — не одно и то же. equals() не приводит типы автоматически.
Ошибка №5: Сортировка строк с разным регистром
Прописные буквы идут раньше строчных. Для сортировки без учёта регистра используйте Arrays.sort(array, String.CASE_INSENSITIVE_ORDER).
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ