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
создается с помощью оператора new
, поэтому они ссылаются на разные объекты.
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()
возвращает значение типа int
и сравнивает две строки
посимвольно лексикографически на основе словаря или естественного порядка.
Этот метод возвращает 0, если две строки
равны или обе имеют значение null,
отрицательное число, если первая строка
идет перед аргументом, и число больше нуля, если первая строка
идет после строки аргумента .
Давайте посмотрим пример:
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()
класса переданного типа аргумента, который в нашем случае является методом 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()
Метод equals()
класса StringUtils
является расширенной версией метода equals() класса
String
, который также обрабатывает нулевые значения: ``
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()
— это String
, а второй — тип 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()
Метод compare()
в классе StringUtils
является нулевой версией метода compareTo()
класса String
и обрабатывает нулевые
значения, рассматривая нулевое
значение как меньшее, чем ненулевое
значение. Два нулевых
значения считаются равными.
Кроме того, этот метод можно использовать для сортировки списка строк
с пустыми
записями:
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
равно
true, и выше, если значение nullIsLess
равно false.
``
Давайте попробуем:
assertThat(StringUtils.compare(null, "abc", true))
.isEqualTo(-1);
assertThat(StringUtils.compare(null, "abc", false))
.isEqualTo(1);
Метод compareIgnoreCase()
с третьим логическим
аргументом работает аналогично, за исключением игнорирования регистра.
5. Вывод
В этом кратком руководстве мы обсудили различные способы сравнения строк.
И, как всегда, исходный код примеров можно найти на GitHub .