Проверка наличия подстрок из массива в строке: Java

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для проверки, содержит ли строка хотя бы одну из подстрок, заданных в массиве, можно воспользоваться возможностями Stream и метода anyMatch в Java:

Java
Скопировать код
String[] ключевыеСлова = {"foo", "bar", "baz"};
String текст = "В бар заходит фубар...";

boolean содержится = Arrays.stream(ключевыеСлова).anyMatch(текст::contains);

System.out.println(содержится); // Выводит 'true', потому  что есть совпадение!

Мы используем Arrays.stream для превращения нашего массива в поток данных, а anyMatch становится эффективным инструментом для проверки присутствия элементов списка в тексте. Работа метода завершается сразу после нахождения первого совпадения.

Кинга Идем в IT: пошаговый план для смены профессии

Глубокое погружение: подходы и замечания о производительности

Преимущества использования списков вместо массивов

Несмотря на то, что массивы являются базовой структурой данных в Java, их преобразование в список List может предоставить большую гибкость:

Java
Скопировать код
List<String> ключевыеСлова = Arrays.asList("foo", "bar", "baz");
boolean содержится = ключевыеСлова.stream().anyMatch(текст::contains);

Такой список позволяет удобно добавлять и удалять элементы, в отличие от массива, который остаётся неизменным.

Учёт регистра при поиске

Так как регистр символов может быть важен:

Java
Скопировать код
boolean содержится = ключевыеСлова.stream()
                                  .anyMatch(слово -> текст.toLowerCase().contains(слово.toLowerCase()));

Этот код позволяет выполнять поиск, без учёта регистра.

Использование RegEx для более сложного поиска

В случае необходимости поиска по более сложному шаблону уместно использовать регулярные выражения:

Java
Скопировать код
Pattern паттерн = Pattern.compile(String.join("|", ключевыеСлова));
Matcher matcher = паттерн.matcher(текст);

boolean содержится = matcher.find();

При помощи классов Pattern и Matcher возможна работа с более сложными шаблонами.

Использование StringUtils для ускоренной проверки

Для внедрения быстрой проверки можно применить StringUtils из Apache Commons:

Java
Скопировать код
boolean содержится = StringUtils.indexOfAny(текст, ключевыеСлова) != -1;

Метод StringUtils.indexOfAny быстро определяет, есть ли в тексте совпадения, выводя индекс первого из них, либо -1 в случае отсутствия совпадений.

Визуализация

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

Markdown
Скопировать код
Строка: "Почему курица перешла дорогу?"
Массив: ["курица", "дорога", "перешла"]

Проходя по массиву, происходит поиск:

Markdown
Скопировать код
🔦: ["курица", "дорога", "перешла"]

И мы выявляем сигнальные слова, присутствующие в тексте:

Java
Скопировать код
boolean шуткаОбнаружена = Arrays.stream(массив).anyMatch(строка::contains);

Если наш детектор находит совпадение, мы отмечаем это как Успех💡, в противном случае — Шутка не найдена🕯️:

Markdown
Скопировать код
Шутка обнаружена: 💡 (true)
Шутка не найдена: 🕯️ (false)

Давайте сделаем обыденный диалог более изящным, выискивая поводы для острот!

Дальнейшие шаги: улучшаем читабельность и производительность

Простота использования потоков

Для небольших наборов данных использование обычных потоков может быть оптимальным решением с точки зрения производительности, в то время как параллельная обработка может быть излишней.

Повышенная читабельность благодаря статическим методам

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

Java
Скопировать код
public static boolean содержитШутливое(ввод, String... ключевыеСлова) {
    return Arrays.stream(ключевыеСлова).anyMatch(ввод::contains);
}
// Вызывайте метод 'содержитШутливое(ввод, ключевыеСлова)' для поиска шуток.

Обработка больших данных

Для большого набора шутливых слов целесообразно рассмотреть использование parallelStream(), встроенного в Java;

Java
Скопировать код
boolean содержится = Arrays.asList(ключевыеСлова).parallelStream().anyMatch(текст::contains);
// Найдем совпадения быстро, не тратя лишнее время.

Это может значительно ускорить процесс поиска.

Упрощение синтаксиса благодаря ссылкам на методы

С появлением Java 8 ссылки на методы значительно упростили и улучшили читаемость кода:

Java
Скопировать код
boolean содержится = ключевыеСлова.stream().anyMatch(текст::contains);
// 'текст::contains' обозначает – "Содержит ли текст какое-либо из моих ключевых слов?"

Полезные материалы

  1. Класс String (Java SE 11 & JDK 11) — Подробное описание класса String в Java.
  2. StringUtils (Apache Commons Lang 3.14.0 API) — Документация StringUtils от Apache Commons, ваш надёжный спутник при работе со строками.
  3. [Effective Java, 3-е издание [Книга]](https://www.oreilly.com/library/view/effective-java-3rd/9780134686097/) — Лучшие практики программирования на Java с получением возможности получить профессиональные рекомендации.
  4. Регулярные выражения в Java – Руководство — Обстоятельное руководство по использованию регулярных выражений в Java.
  5. Обзор набора коллекций — Описание и особенности Java Collections Framework. Это замечательный ресурс для обучения.
  6. Руководство использования JUnit 5 — Детальное пошаговое руководство по написанию тестов на Java с использованием JUnit 5. Ведь каждую даже лучшую шутку стоит проверить на практике.