Проверка наличия подстрок из массива в строке: Java
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Для проверки, содержит ли строка хотя бы одну из подстрок, заданных в массиве, можно воспользоваться возможностями Stream
и метода anyMatch
в Java:
String[] ключевыеСлова = {"foo", "bar", "baz"};
String текст = "В бар заходит фубар...";
boolean содержится = Arrays.stream(ключевыеСлова).anyMatch(текст::contains);
System.out.println(содержится); // Выводит 'true', потому что есть совпадение!
Мы используем Arrays.stream
для превращения нашего массива в поток данных, а anyMatch
становится эффективным инструментом для проверки присутствия элементов списка в тексте. Работа метода завершается сразу после нахождения первого совпадения.
Глубокое погружение: подходы и замечания о производительности
Преимущества использования списков вместо массивов
Несмотря на то, что массивы являются базовой структурой данных в Java, их преобразование в список List
может предоставить большую гибкость:
List<String> ключевыеСлова = Arrays.asList("foo", "bar", "baz");
boolean содержится = ключевыеСлова.stream().anyMatch(текст::contains);
Такой список позволяет удобно добавлять и удалять элементы, в отличие от массива, который остаётся неизменным.
Учёт регистра при поиске
Так как регистр символов может быть важен:
boolean содержится = ключевыеСлова.stream()
.anyMatch(слово -> текст.toLowerCase().contains(слово.toLowerCase()));
Этот код позволяет выполнять поиск, без учёта регистра.
Использование RegEx для более сложного поиска
В случае необходимости поиска по более сложному шаблону уместно использовать регулярные выражения:
Pattern паттерн = Pattern.compile(String.join("|", ключевыеСлова));
Matcher matcher = паттерн.matcher(текст);
boolean содержится = matcher.find();
При помощи классов Pattern
и Matcher
возможна работа с более сложными шаблонами.
Использование StringUtils для ускоренной проверки
Для внедрения быстрой проверки можно применить StringUtils
из Apache Commons:
boolean содержится = StringUtils.indexOfAny(текст, ключевыеСлова) != -1;
Метод StringUtils.indexOfAny
быстро определяет, есть ли в тексте совпадения, выводя индекс первого из них, либо -1
в случае отсутствия совпадений.
Визуализация
Представьте себе некую текстовую строку, где ключевые слова, фигурально выступают в роли маяков, готовых вызвать реакцию:
Строка: "Почему курица перешла дорогу?"
Массив: ["курица", "дорога", "перешла"]
Проходя по массиву, происходит поиск:
🔦: ["курица", "дорога", "перешла"]
И мы выявляем сигнальные слова, присутствующие в тексте:
boolean шуткаОбнаружена = Arrays.stream(массив).anyMatch(строка::contains);
Если наш детектор находит совпадение, мы отмечаем это как Успех💡, в противном случае — Шутка не найдена🕯️:
Шутка обнаружена: 💡 (true)
Шутка не найдена: 🕯️ (false)
Давайте сделаем обыденный диалог более изящным, выискивая поводы для острот!
Дальнейшие шаги: улучшаем читабельность и производительность
Простота использования потоков
Для небольших наборов данных использование обычных потоков может быть оптимальным решением с точки зрения производительности, в то время как параллельная обработка может быть излишней.
Повышенная читабельность благодаря статическим методам
Выделение процесса поиска в статический вспомогательный метод улучшает читабельность и позволяет повторно использовать код:
public static boolean содержитШутливое(ввод, String... ключевыеСлова) {
return Arrays.stream(ключевыеСлова).anyMatch(ввод::contains);
}
// Вызывайте метод 'содержитШутливое(ввод, ключевыеСлова)' для поиска шуток.
Обработка больших данных
Для большого набора шутливых слов целесообразно рассмотреть использование parallelStream(), встроенного в Java;
boolean содержится = Arrays.asList(ключевыеСлова).parallelStream().anyMatch(текст::contains);
// Найдем совпадения быстро, не тратя лишнее время.
Это может значительно ускорить процесс поиска.
Упрощение синтаксиса благодаря ссылкам на методы
С появлением Java 8 ссылки на методы значительно упростили и улучшили читаемость кода:
boolean содержится = ключевыеСлова.stream().anyMatch(текст::contains);
// 'текст::contains' обозначает – "Содержит ли текст какое-либо из моих ключевых слов?"
Полезные материалы
- Класс String (Java SE 11 & JDK 11) — Подробное описание класса String в Java.
- StringUtils (Apache Commons Lang 3.14.0 API) — Документация StringUtils от Apache Commons, ваш надёжный спутник при работе со строками.
- [Effective Java, 3-е издание [Книга]](https://www.oreilly.com/library/view/effective-java-3rd/9780134686097/) — Лучшие практики программирования на Java с получением возможности получить профессиональные рекомендации.
- Регулярные выражения в Java – Руководство — Обстоятельное руководство по использованию регулярных выражений в Java.
- Обзор набора коллекций — Описание и особенности Java Collections Framework. Это замечательный ресурс для обучения.
- Руководство использования JUnit 5 — Детальное пошаговое руководство по написанию тестов на Java с использованием JUnit 5. Ведь каждую даже лучшую шутку стоит проверить на практике.