1. Огляд
У цій статті ми поговоримо про різні способи порівняння рядків у Java.
Оскільки String є одним із найбільш часто використовуваних типів даних у Java, це, природно, дуже часто використовувана операція.
2. Рядок порівняння З Рядок класу
2.1. Використання оператора порівняння “==”
Використання оператора “==” для порівняння текстових значень є однією з найпоширеніших помилок, які роблять новачки Java. Це неправильно, оскільки “==” перевіряє лише посилальну рівність двох рядків , тобто якщо вони посилаються на той самий об’єкт чи ні.
Подивимось приклад такої поведінки:
String string1 = "using comparison operator"; String string2 = "using comparison operator"; String string3 = new String("using comparison operator"); assertThat(string1 == string2).isTrue(); assertThat(string1 == string3).isFalse();
У наведеному вище прикладі перше твердження відповідає дійсності, оскільки дві змінні вказують на один і той же літерал String .
З іншого боку, друге твердження хибне, оскільки рядок1 створюється з літералом, а рядок3 створюється за допомогою нового оператора - тому вони посилаються на різні об’єкти.
2.2. Використання рівняння ()
Клас String перевизначає equals (), успадкований від Object. Цей метод порівнює два рядки символ за символом, ігноруючи їх адресу.
Він вважає їх рівними, якщо вони однакової довжини і символи мають однаковий порядок:
String string1 = "using equals method"; String string2 = "using equals method"; String string3 = "using EQUALS method"; String string4 = new String("using equals method"); assertThat(string1.equals(string2)).isTrue(); assertThat(string1.equals(string4)).isTrue(); assertThat(string1.equals(null)).isFalse(); assertThat(string1.equals(string3)).isFalse();
У цьому прикладі змінні string1 , string2 і string4 рівні, оскільки вони мають однаковий регістр і значення незалежно від їх адреси.
Для string3 метод повертає false, оскільки чутливий до регістру.
Крім того, якщо будь-який з двох рядків має значення null , тоді метод повертає значення false.
2.3. Використання equalsIgnoreCase ()
Метод equalsIgnoreCase () повертає логічне значення. Як випливає з назви, цей метод ігнорує регістр символів під час порівняння рядків :
String string1 = "using equals ignore case"; String string2 = "USING EQUALS IGNORE CASE"; assertThat(string1.equalsIgnoreCase(string2)).isTrue();
2.4. Використання compareTo ()
Метод compareTo () повертає значення типу int і порівнює два символи рядків за символом лексикографічно на основі словника або природного впорядкування.
Цей метод повертає 0, якщо два рядки рівні або якщо обидва є нульовими, негативне число, якщо перший рядок стоїть перед аргументом, і число більше нуля, якщо перший рядок йде після аргументу String.
Подивимось приклад:
String author = "author"; String book = "book"; String duplicateBook = "book"; assertThat(author.compareTo(book)) .isEqualTo(-1); assertThat(book.compareTo(author)) .isEqualTo(1); assertThat(duplicateBook.compareTo(book)) .isEqualTo(0);
2.5. Використання compareToIgnoreCase ()
Функція compareToIgnoreCase () подібна до попереднього методу, за винятком того, що ігнорує регістр:
String author = "Author"; String book = "book"; String duplicateBook = "BOOK"; assertThat(author.compareToIgnoreCase(book)) .isEqualTo(-1); assertThat(book.compareToIgnoreCase(author)) .isEqualTo(1); assertThat(duplicateBook.compareToIgnoreCase(book)) .isEqualTo(0);
3. Порівняння рядків із класом об’єктів
Objects - це клас утиліти, який містить статичний метод equals () , корисний у цьому сценарії - для порівняння двох рядків.
Метод повертає true, якщо два рядки рівні, попередньо порівнявши їх, використовуючи їх адресу, тобто “ ==” . Отже, якщо обидва аргументи мають значення null , він повертає true, а якщо рівно один аргумент має значення null , він повертає значення false.
В іншому випадку він просто викликає метод equals () класу типу переданого аргументу - що в нашому випадку є методом класу String equals () . Цей метод чутливий до регістру, оскільки внутрішньо викликає метод рівняння () класу String .
Давайте перевіримо це:
String string1 = "using objects equals"; String string2 = "using objects equals"; String string3 = new String("using objects equals"); assertThat(Objects.equals(string1, string2)).isTrue(); assertThat(Objects.equals(string1, string3)).isTrue(); assertThat(Objects.equals(null, null)).isTrue(); assertThat(Objects.equals(null, string1)).isFalse();
4. Порівняння рядків із Apache Commons
Бібліотека Apache Commons містить клас утиліту StringUtils для string- пов'язаних з ними операцій ; це також має кілька дуже корисних методів для порівняння рядків .
4.1. Використання equals () та equalsIgnoreCase ()
В одно () метод StringUtils класу є розширеною версією Струнного методу класу Equals (), який також обробляє нульові значення:
assertThat(StringUtils.equals(null, null)) .isTrue(); assertThat(StringUtils.equals(null, "equals method")) .isFalse(); assertThat(StringUtils.equals("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equals("equals method", "EQUALS METHOD")) .isFalse();
EqualsIgnoreCase () метод StringUtils повертає логічне значення. Це працює подібно до equals (), за винятком того, що ігнорує регістр символів у рядках:
assertThat(StringUtils.equalsIgnoreCase("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equalsIgnoreCase("equals method", "EQUALS METHOD")) .isTrue();
4.2. Використання equalsAny () та equalsAnyIgnoreCase ()
У equalsAny () перший аргумент методу є рядок , а другий є мульти-арг типу CharSequence. Метод повертає true, якщо будь-який з інших заданих рядків чутливо збігається з першим регістром рядка .
В іншому випадку повертається false:
assertThat(StringUtils.equalsAny(null, null, null)) .isTrue(); assertThat(StringUtils.equalsAny("equals any", "equals any", "any")) .isTrue(); assertThat(StringUtils.equalsAny("equals any", null, "equals any")) .isTrue(); assertThat(StringUtils.equalsAny(null, "equals", "any")) .isFalse(); assertThat(StringUtils.equalsAny("equals any", "EQUALS ANY", "ANY")) .isFalse();
Метод equalsAnyIgnoreCase () працює аналогічно методу equalsAny () , але також ігнорує регістр:
assertThat(StringUtils.equalsAnyIgnoreCase("ignore case", "IGNORE CASE", "any")).isTrue();
4.3. За допомогою порівняння () та compareIgnoreCase ()
Порівняти () метод в StringUtils класі є нуль-безпечної версією CompareTo () методом Струнного класу і ручка обнулити значення, враховуючи нульовий значення менше , ніж нульове значення. Два нульові значення вважаються рівними.
Крім того, за допомогою цього методу можна сортувати список рядків із нульовими записами:
assertThat(StringUtils.compare(null, null)) .isEqualTo(0); assertThat(StringUtils.compare(null, "abc")) .isEqualTo(-1); assertThat(StringUtils.compare("abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compare("bbc", "abc")) .isEqualTo(1);
Метод compareIgnoreCase () поводиться аналогічно, за винятком того, що ігнорує кожух:
assertThat(StringUtils.compareIgnoreCase("Abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compareIgnoreCase("bbc", "ABC")) .isEqualTo(1); assertThat(StringUtils.compareIgnoreCase("abc", "ABC")) .isEqualTo(0);
Два методи також можна використовувати з параметром nullIsLess . Це третій логічний аргумент, який вирішує, чи слід вважати нульові значення меншими чи ні .
Нульове значення менше , ніж інша рядок , якщо nullIsLess вірно і вище , якщо nullIsLess помилково.
Давайте спробуємо:
assertThat(StringUtils.compare(null, "abc", true)) .isEqualTo(-1); assertThat(StringUtils.compare(null, "abc", false)) .isEqualTo(1);
Метод compareIgnoreCase () з третім логічним аргументом працює аналогічно, за винятком ігнорування регістру.
5. Висновок
У цьому короткому підручнику ми обговорили різні способи порівняння рядків.
І, як завжди, вихідний код для прикладів можна знайти на GitHub.