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("Пароль невірний.");
}
Важливо!
Якщо обʼєкт, на якому викликається equals(), дорівнює null, це призведе до NullPointerException. Безпечний шаблон:
if ("щось".equals(someString)) { ... }
3. equalsIgnoreCase(): порівняння без урахування регістру
Коли потрібно ігнорувати регістр (наприклад, під час введення користувачем), використовуйте equalsIgnoreCase().
String name1 = "Ivan";
String name2 = "ivan";
System.out.println(name1.equalsIgnoreCase(name2)); // true
Приклад: порівняння адрес електронної пошти
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
Особливості:
- Роздільник — це регулярний вираз (regex). Спецсимволи потрібно екранувати (наприклад, крапка: "\\.").
- Метод завжди повертає масив, навіть якщо результат — один елемент.
9. Практика: порівнюємо рядки в реальному застосунку
String registeredEmail = "user@example.com";
String registeredPassword = "Secret123";
Scanner console = new Scanner(System.in);
System.out.print("Введіть адресу електронної пошти: ");
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("Невірна адреса електронної пошти або пароль.");
}
Коментар: для адреси електронної пошти використовуйте 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).
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ