JavaRush /Курси /JAVA 25 SELF /Порівняння рядків: equals, equalsIgnoreCase, compareTo

Порівняння рядків: equals, equalsIgnoreCase, compareTo

JAVA 25 SELF
Рівень 9 , Лекція 4
Відкрита

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»
equals()
Так
false
equalsIgnoreCase()
Ні
true

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).

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ