Таким образом, первый и самый простой вариант - использовать ваш фактический метод findTheWord()
и создать новый метод, который его использует:
public Map<String, Integer> findTheWords(String stringToCheck, List<String> words) {
return words.stream().distinct()
.collect(Collectors.toMap(Function.identity(), word -> findTheWord(stringToCheck, word)));
}
public Integer findTheWord(String stringToCheck, String regexString) {
Pattern regexp = Pattern.compile("\\b" + regexString + "\\b");
Matcher matcher = regexp.matcher(stringToCheck);
int count = 0;
while (matcher.find()) {
count++;
}
return count;
}
Проблема в том, что вы используете большое количествослова для поиска и большой текст, потому что он перебирает заданную строку для каждого слова.Таким образом, другой подход заключается в создании регулярного выражения для всех слов и увеличении следующего найденного слова в вашей получившейся карте:
public Map<String, Integer> findTheWords(String stringToCheck, List<String> words) {
Pattern regexp = Pattern.compile(words.stream().distinct().map(word -> "\\b" + word + "\\b").collect(Collectors.joining("|")));
// creates a pattern like this: "\ba\b|\bb\b|\bc\b|\bd\b|\be\b"
Matcher matcher = regexp.matcher(stringToCheck);
Map<String, Integer> result = new HashMap<>();
while (matcher.find()) {
String word = matcher.group();
result.put(word, result.getOrDefault(word, 0) + 1);
}
return result;
}
Кроме того, что вы, возможно, рассматриваете возможность использования Set
для слов вместо List
, поскольку значения уникальны, поэтому нет необходимости вызывать .distinct()
в потоке.