String.equalsIgnoreCase: примеры (JAVA)

Метод equalsIgnoreCase в Java: разбор и примеры
Раздел: Строки (String) - поиск и сравнение
String.equalsIgnoreCase(String anotherString): boolean

Описание метода String.equalsIgnoreCase

Метод String.equalsIgnoreCase в Java выполняет сравнение двух строк на равенство без учёта регистра символов. Подходит для ситуаций, когда требуется проверить, эквивалентны ли строки с учётом только буквенного регистра, например при проверке команд, ключей или пользовательского ввода.

Сигнатура метода:

public boolean equalsIgnoreCase(String anotherString)

Параметры:

  • anotherString - строка для сравнения с текущим экземпляром. Может быть null.

Возвращаемое значение:

  • true - если строки имеют одинаковую длину и соответствующие символы равны при игнорировании регистра согласно Unicode-мэппингу, или если ссылки на объекты идентичны.
  • false - в остальных случаях, включая ситуацию, когда anotherString равна null.

Особенности реализации и поведение:

  • Сравнение выполнено без учёта локали и опирается на внутренние операции с символами (реализовано через regionMatches(true, ...)). Это означает использование стандартных Unicode-преобразований регистра, а не локаль-специфичных правил.
  • Если длины строк отличаются, метод сразу вернёт false. Следовательно, пары символов, которые при изменении регистра меняют длину (например, сочетания с лигатурами), не будут считаться равными, если длины различны.
  • Метод не бросает исключение при передаче null в качестве аргумента; он возвращает false. Однако вызов метода на ссылке null приведёт к NullPointerException.
  • Для учёта локали и специальных случаев лучше использовать преобразование регистра с явным указанием локали или использовать Collator для сложных языковых сравнений.

Короткие примеры использования equalsIgnoreCase

Несколько простых сценариев с кодом и результатом.

Обычное сравнение с разным регистром:

String a = "Hello";
String b = "heLLo";
System.out.println(a.equalsIgnoreCase(b));
true

Разная длина возвращает false:

String a = "test";
String b = "tests";
System.out.println(a.equalsIgnoreCase(b));
false

Сравнение с null аргументом:

String a = "abc";
String b = null;
System.out.println(a.equalsIgnoreCase(b));
false

Вызов на null-ссылке вызывает исключение:

String a = null;
String b = "abc";
System.out.println(a.equalsIgnoreCase(b));
Exception in thread "main" java.lang.NullPointerException
    at ...

Похожие методы в Java

Краткое сравнение с похожими способами сравнения строк в Java и когда их выбирать.

  • String.equals - точное сравнение с учётом регистра. Используется, когда регистр важен.
  • String.compareToIgnoreCase - лексикографическое сравнение без учёта регистра, возвращает целое значение для упорядочивания. Подходит для сортировки или сравнения порядков.
  • String.regionMatches(boolean ignoreCase,...) - позволяет сравнивать подстроки с опцией игнорирования регистра. Полезно для сравнения частей строк без выделения новых объектов.
  • Collator (java.text) - учёт локали и языковых правил при сравнении. Предпочтительно для пользовательских интерфейсов и сортировки с языковыми особенностями.

Типичные ошибки при использовании

Распространённые ошибки и примеры с результатами.

Вызов метода на null-ссылке:

String s = null;
System.out.println(s.equalsIgnoreCase("abc"));
Exception in thread "main" java.lang.NullPointerException
    at ...

Ожидание эквивалентности символов разной длины (пример с немецким ß):

System.out.println("ß".equalsIgnoreCase("ss"));
false

Неправильное сравнение с учётом локали (турецкая буква I):

String a = "İ"; // латинская буква I с точкой
String b = "i";
System.out.println(a.equalsIgnoreCase(b));
false

Комментарий: для локаль-специфичных случаев следует применять преобразование регистра с указанием Locale или Collator, а не полагаться на equalsIgnoreCase.

Неоптимальное использование: приведение двух строк к одному регистру создаёт объекты:

System.out.println(a.toLowerCase().equals(b.toLowerCase()));
// Работает, но менее эффективно чем a.equalsIgnoreCase(b)

Изменения и совместимость

Метод существует в Java с очень ранних версий и семантика не менялась. Основные моменты:

  • Никаких функциональных изменений в сигнатуре или поведении в последних релизах Java не вводилось.
  • Поведение относительно Unicode может эволюционировать вместе с обновлениями реализованной версии Unicode в JVM. Это означает, что сопоставления регистра для нововведённых символов могут менять результаты при обновлении Java-версии.
  • Если требуется строгое поведение с учётом текущей локали, рекомендуется использовать локаль-специфичные операции.

Расширенные и редкие варианты применения

Несколько продвинутых приёмов с кодом и пояснениями.

1) Проверка префикса без учёта регистра с помощью regionMatches (без выделения новых строк):

Пример java
String s = "UnImPoRtAnT";
boolean starts = s.regionMatches(true, 0, "unimport", 0, 8);
System.out.println(starts);
true

Пояснение: полезно для поиска префикса без создания временных строк.

2) Поиск подстроки без учёта регистра с использованием регулярных выражений и флагов Unicode:

Пример java
import java.util.regex.*;

Pattern p = Pattern.compile(Pattern.quote("№") + "?test", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Matcher m = p.matcher("This is TEST №test");
while (m.find()) System.out.println(m.group());
TEST
№test

Пояснение: помогает учитывать специальные символы и Unicode-регистр.

3) Сравнение с учётом локали (турецкий пример):

Пример java
String a = "I";
String b = "ı"; // латинская маленькая без точки
System.out.println(a.toLowerCase(Locale.forLanguageTag("tr")).equals(b.toLowerCase(Locale.forLanguageTag("tr"))));
System.out.println(a.equalsIgnoreCase(b));
true
false

Пояснение: equalsIgnoreCase не учитывает локаль, поэтому для турецких I/İ требуется локаль-специфичное приведение регистров.

4) Использование нормализации Unicode перед сравнением для сравнения визуально равных символов:

Пример java
import java.text.Normalizer;

String s1 = "e\u0301"; // e + combining acute
String s2 = "\u00E9"; // precomposed é
boolean eq = Normalizer.normalize(s1, Normalizer.Form.NFC).equalsIgnoreCase(Normalizer.normalize(s2, Normalizer.Form.NFC));
System.out.println(eq);
true

Пояснение: нормализация устраняет различия представления одного и того же графема.

5) Использование при хранении ключей в коллекциях: хранение ключей в нормализованном регистре или применение Case-insensitive Comparator для TreeMap:

Пример java
Map map = new HashMap<>();
map.put("Key", "value");
String lookup = "key";
// Надежнее и эффективнее использовать equalsIgnoreCase при сравнении, но для быстрых запросов лучше нормализовать ключы при вставке
System.out.println(map.get(lookup.toLowerCase()));
// Или поддерживать отдельную структура: Map with lowercased keys
null  // потому что ключи не были нормализованы при вставке

Пояснение: для поиска без учёта регистра рекомендуется нормализовать ключи при вставке или использовать специализированный контейнер.

6) Производительность: при частых операциях сравнения лучше применять equalsIgnoreCase, чтобы избежать создания временных объектов при вызове toLowerCase() или toUpperCase() для обеих строк.

Аналоги в других языках

Короткие примеры и отличия от Java-подхода.

PHP - функция strcasecmp:

var_dump(strcasecmp('Hello', 'heLLo'));
int(0)  // 0 означает равенство без учёта регистра

Замечание: возвращается число, а не boolean.

JavaScript - обычно используют приведение в один регистр:

console.log('Hello'.toLowerCase() === 'heLLo'.toLowerCase());
true

Или localeCompare с опциями:

console.log('Hello'.localeCompare('heLLo', undefined, {sensitivity: 'accent'}) === 0);
true

Python - методы .lower() и .casefold():

print('Hello'.lower() == 'heLLo'.lower())
print('ß'.lower() == 'SS'.lower())
print('ß'.casefold() == 'ss'.casefold())
True
False
True

Замечание: casefold() обеспечивает более агрессивную нормализацию под Unicode и предпочтительнее для безрегистрированных сравнений.

C# - использование String.Equals с параметром сравнения:

Console.WriteLine(string.Equals("Hello", "heLLo", StringComparison.OrdinalIgnoreCase));
True

Go - функцию strings.EqualFold:

package main
import (
  "fmt"
  "strings"
)
func main() {
  fmt.Println(strings.EqualFold("Hello", "heLLo"))
}
true

Kotlin - встроенная опция в equals:

println("Hello".equals("heLLo", ignoreCase = true))
true

Lua - нет встроенного; используют приведение регистра:

print(string.lower('Hello') == string.lower('heLLo'))
true

Отличия от Java: в ряде языков имеются специальные функции с учётом Unicode (Python casefold, Go EqualFold), в других приходится явным образом приводить регистр, что создаёт новые строки. Java-метод встроен и не создаёт промежуточных строк при сравнении.

джава String.equalsIgnoreCase function comments

En
String.equalsIgnoreCase Compares this String to another String, ignoring case considerations