Сравнение строк в Java

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();

В приведенном выше примере первое утверждение истинно, потому что две переменные указывают на один и тот же строковый литерал.

С другой стороны, второе утверждение ложно, потому что строка1 создается с помощью литерала, а строка3 создается с использованием оператора new - поэтому они ссылаются на разные объекты.

2.2. Использование equals ()

Класс 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 и сравнивает два символа Strings символ за символом лексикографически на основе словаря или естественного порядка.

Этот метод возвращает 0, если две строки равны или обе равны нулю, отрицательное число, если первая строка идет перед аргументом, и число больше нуля, если первая строка идет после строки аргумента .

Посмотрим на пример:

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 () , полезный в этом сценарии - для сравнения двух строк.

Метод возвращает истину, если две строки равны, сначала сравнивая их с использованием их адреса, то есть « ==» . Следовательно, если оба аргумента равны нулю , он возвращает истину, а если ровно один аргумент равен нулю , он возвращает ложь.

В противном случае он просто вызывает метод equals () класса типа переданного аргумента, который в нашем случае является методом 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 для операций, связанных со строками ; у этого также есть несколько очень полезных методов для сравнения строк .

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. Использование compare () и 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.