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

Примеры применения contains в Java
Раздел: Строки (String) - поиск и сравнение
String.contains(CharSequence s): boolean

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

Метод String.contains в Java проверяет, содержит ли строка указанную последовательность символов. Сигнатура метода: public boolean contains(CharSequence s). Возвращается булево значение: true, если указанная последовательность встречается в строке как подстрока, и false в противном случае.

Аргументы и поведение:

  • Аргумент: объект, реализующий интерфейс CharSequence. Часто это String, StringBuilder или StringBuffer. Передача null приводит к NullPointerException.
  • Сравнение: чувствительное к регистру и основано на точном совпадении последовательности char. Метод не выполняет привязки к локали.
  • Пустая подстрока: вызов с пустой строкой ("") всегда возвращает true согласно соглашению о подстроках.
  • Юникод и суррогатные пары: метод проверяет char-последовательность, а не логические code point; поиск суррогатных пар работает корректно при точном совпадении последовательностей UTF-16.
  • Производительность: реализация вызывает indexOf, сложность в худшем случае близка к O(n*m), где n - длина строки, m - длина искомой последовательности.
  • Потокобезопасность: класс String неизменяемый, поэтому вызов безопасен для чтения из разных потоков.

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

  • true - если последовательность найдена.
  • false - если последовательность не найдена.
  • NullPointerException - при передаче null в качестве аргумента.

Короткие примеры работы contains

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

Пример 1. Простая проверка подстроки

String s = "hello world";
System.out.println(s.contains("world"));
true

Пример 2. Регистр имеет значение

String s = "Hello";
System.out.println(s.contains("hello"));
false

Пример 3. Пустая подстрока

String s = "abc";
System.out.println(s.contains(""));
true

Пример 4. CharSequence отличный от String

String base = "buffer test";
StringBuilder sb = new StringBuilder("buffer");
System.out.println(base.contains(sb));
true

Пример 5. Null в аргументе - исключение

String s = "x";
try {
    System.out.println(s.contains(null));
} catch (Exception e) {
    System.out.println(e.getClass().getSimpleName());
}
NullPointerException

Пример 6. Поиск с помощью регулярного выражения (contains не использует regex)

String s = "a1b2";
System.out.println(s.contains("\\d")); // ищется буквальное "\\d"
System.out.println(java.util.regex.Pattern.compile("\\d").matcher(s).find());
false
true

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

  • indexOf(CharSequence): возвращает индекс первого вхождения или -1. Полезен при необходимости позиции подстроки или для проверки наличия (indexOf(...) >= 0 эквивалент contains).
  • startsWith/endsWith: проверка начала или конца строки, быстрее при такой конкретной задаче.
  • matches: проверка на соответствие регулярному выражению для всей строки, не подходит для простого contains без regex.
  • Pattern/Matcher: поиск по регулярным выражениям с флагами (например, CASE_INSENSITIVE), предпочтительнее для сложных шаблонов или при многократных поисках (компиляция шаблона один раз).
  • regionMatches: сравнение участка строки с другой строкой с опцией игнорирования регистра без создания новых строк в некоторых сценариях.

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

  • PHP (str_contains): с PHP 8.0 доступна функция str_contains(string $haystack, string $needle): bool. По умолчанию чувствительна к регистру. Пример:
    var_dump(str_contains('hello','lo'));
    bool(true)
  • JavaScript (includes / indexOf): str.includes(sub) возвращает boolean, чувствителен к регистру. Альтернатива str.indexOf(sub) !== -1.
    console.log('abc'.includes('b'));
    true
  • Python ('in' / find): оператор sub in s возвращает булево. Метод s.find(sub) возвращает индекс или -1.
    print('lo' in 'hello')
    print('hello'.find('x'))
    True
    -1
  • SQL (LIKE, POSITION, INSTR): в SQL поиск подстроки выполняется через LIKE '%sub%' или POSITION('sub' IN col). Регистрозависимость зависит от СУБД и колlation.
  • C# (String.Contains): есть перегрузка с StringComparison для контроля регистра и культуры: str.Contains(sub, StringComparison.OrdinalIgnoreCase) доступна в новых версиях .NET. Пример:
    Console.WriteLine("Hello".Contains("he", StringComparison.OrdinalIgnoreCase));
    True
  • Lua (string.find): string.find(s, sub) возвращает позицию или nil. По умолчанию использует шаблоны Lua, для буквального поиска используется plain=true.
  • Go (strings.Contains): функция strings.Contains(s, substr) возвращает bool, работает с байтами/руннами в соответствии с UTF-8, чувствительна к регистру.
    fmt.Println(strings.Contains("hello","ll"))
    true
  • Kotlin (String.contains): есть перегрузка с параметром ignoreCase: Boolean, что делает проверку регистронезависимой без дополнительной нормализации: str.contains(sub, ignoreCase = true).

Типичные ошибки при применении contains

  • NullPointerException: передача null в метод.
    String s = "a";
    System.out.println(s.contains(null));
    // Бросается исключение
    NullPointerException
  • Ожидание регулярного поиска: метод не интерпретирует аргумент как regex. Частая ошибка - попытка найти цифровой символ через "\\d".
    String s = "1";
    System.out.println(s.contains("\\d"));
    false
  • Путаница с регистром: проверка чувствительна к регистру. Для регистронезависимого сравнения создаются нормализованные строки или применяются Pattern/regionMatches.
    System.out.println("Test".contains("t"));
    false
  • Производительность: многократные вызовы с компиляцией regex в цикле или создание вспомогательных строк в горячих путях может замедлить приложение. Предпочтительнее компилировать Pattern один раз при необходимости сложного поиска.
  • Путаница с массивами и коллекциями: contains у строки проверяет подстроку, а не элемент в массиве. Закомментированные попытки использовать его для проверки наличия объекта в массиве приводят к логическим ошибкам.

Изменения и история метода

Метод String.contains(CharSequence) введён в Java 5 (JDK 1.5). С тех пор его поведение оставалось стабильным и не претерпевало существенных изменений в следующих релизах. В более поздних релизах платформа получила другие пригодные для поиска инструменты (новые методы в String, улучшения в API Pattern и классы для нормализации Unicode), однако сама реализация contains осталась прежней.

Расширенные и редкие сценарии использования

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

Пример 1. Поиск без учета регистра с минимальными аллокациями через Pattern

Пример java
String text = "Пример Текст";
java.util.regex.Pattern p = java.util.regex.Pattern.compile(java.util.regex.Pattern.quote("пример"), java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.UNICODE_CASE);
System.out.println(p.matcher(text).find());
true

Комментарий: компиляция шаблона один раз выгодна при многократных проверках.

Пример 2. Игнорирование диакритики через нормализацию

Пример java
String a = "café";
String b = "cafe";
String na = java.text.Normalizer.normalize(a, java.text.Normalizer.Form.NFD).replaceAll("\\p{M}+", "");
String nb = java.text.Normalizer.normalize(b, java.text.Normalizer.Form.NFD).replaceAll("\\p{M}+", "");
System.out.println(na.contains(nb));
true

Комментарий: нормализация удаляет диакритические метки и позволяет сравнивать текст, независимо от способа кодирования символов.

Пример 3. Поиск emoji с учетом суррогатных пар

Пример java
String s = "A \uD83D\uDE00 B"; // смайл в виде суррогатной пары
String emoji = new StringBuilder().appendCodePoint(0x1F600).toString();
System.out.println(s.contains(emoji));
true

Комментарий: создание строки из code point обеспечивает корректное представление суррогатной пары.

Пример 4. Фильтрация коллекции с contains

Пример java
java.util.List list = java.util.Arrays.asList("alpha","beta","gamma");
list.stream().filter(s -> s.contains("a")).forEach(System.out::println);
alpha
gamma
beta

Комментарий: стрим использует лямбда-выражение; порядок вывода соответствует исходной коллекции.

Пример 5. Быстрая проверка наличия подстроки с индексом

Пример java
String s = "search in a long text";
// contains вызывает indexOf внутри, но явный indexOf пригоден, когда нужна позиция
int pos = s.indexOf("long");
System.out.println(pos >= 0 ? ("found at " + pos) : "not found");
found at 12

Комментарий: indexOf возвращает позицию, что бывает необходимо для дальнейшей обработки.

джава String.contains function comments

En
String.contains Returns true if and only if this string contains the specified sequence of char values