Вирішено Як порівнювати рядки в Java?

Alex Alex · 37 · 1

У своїй програмі я використовував оператор == для порівняння рядків. Але я натрапив на баг, і при заміні == на equals він пропав.

Слід уникати оператора ==? Коли його можна використовувати, а коли ні? В чому різниця?

Відповіді на питання

Оператор == порівнює посилання.

Метод equals порівнює значення.

Отже, якщо ви хочете порівняти рядки на рівність, слід використовувати equals.

Однак в деяких випадках рядки гарантовано представлені одним і тим же об'єктом завдяки пулу рядків (string interning). Ці випадки явно описані в специфікації мови Java .

Оператор == використовується для перевірки, що два рядки вказують на один і той же об'єкт.

// Ці рядки мають одне і те саме значення
new String("test").equals("test") // --> true 

// ...але це різні об'єкти
new String("test") == "test" // --> false 

// ...ці рядки також різні об'єкти
new String("test") == new String("test") // --> false 

// ...але ці рядки вказують а один і той самий об'єкт
// дому що компілятор додає всі літерали в пул
"test" == "test" // --> true 

// Об'єднання літералів токож відбувається на стадії компіляції
// тому вони вказують на один об'єкт
"test" == "te" + "st" // --> true

// але виклик substring() відбувається під час виконання,
// в результаті виходять різні об'єкти
"test" == "!test".substring(1) // --> false

// Рядки з пулу можуть буди отримані за допомогою виклику intern().
"test" == "!test".substring(1).intern() // --> true

Треба відзначити, що == помітно швидше, ніж equals (порівняння посилання замість виклику методу і посимвольного порівняння, якщо рядки різної довжини), тому, якщо ви працюєте з рядками з пулу (або системного, або свого), заміна equals на == може привести до помітного прискорення. Але це трапляється дуже рідко.

Остерігайтеся виклику equals на null! Оператор == прекрасно порівнює рядки, якщо один або більше з них дорівнює null, але виклик методу equals на рядок, що дорівнює null, призведе до виключення.

Для порівняння рядків, які можуть бути рівні null, ви можете скористатися наступним методом:

public static boolean equals(String str1, String str2) {
    return str1 == null ? str2 == null : str1.equals(str2);
}

Він присутній в деяких сторонніх бібліотеках, наприклад, в Apache Commons.

Якщо ви користуєтеся сучасними середовищами розробки, то вони попередять, якщо ви спробуєте порівняти рядки за допомогою оператора ==. Завжди звертайте увагу на подібні попередження.


Для відповіді на запитання необхідно авторизуватись

Війти / Зареєструватися