Java 流筛选器中的ContainsIgnoreCase用于计算字符串列表中出现的一个特定单词

Java 流筛选器中的ContainsIgnoreCase用于计算字符串列表中出现的一个特定单词,java,java-8,functional-programming,java-stream,Java,Java 8,Functional Programming,Java Stream,我想计算java中字符串列表中单个单词的出现次数。看起来这项任务很简单,但我遇到了一个问题,即以大写字母开头的单词或在单词末尾包含、或。 我的方法如下所示: public static Long countWordOccurence(List<String> wordList, String word) { return wordList.stream() .filter(s -> word.contains(s)) .collect(

我想计算java中字符串列表中单个单词的出现次数。看起来这项任务很简单,但我遇到了一个问题,即以大写字母开头的单词或在单词末尾包含
。 我的方法如下所示:

public static Long countWordOccurence(List<String> wordList, String word) {

    return wordList.stream()
        .filter(s -> word.contains(s))
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
        .values()
        .stream()
        .findFirst()
        .orElse((long) -1);
  }
如果可能的话,我会很感激避免额外的依赖,但如果有必要,我不会轻视


如果有人建议如何修复流中的filter子句以正确计算字符串,我将不胜感激

您的代码有几个基本问题

  • .filter->word.contains()
    执行子字符串搜索。与你问题的标题相反,它并没有忽略案例。尽管如此,仍可能有不同内容的字符串通过过滤器

  • .collect(Collectors.groupingBy(Function.identity(),Collectors.counting())
    根据字符串的实际内容创建组。因此,当多个不同的字符串通过前一个筛选器时,可能存在多个组

  • .values().stream().findFirst()
    :由于
    groupingBy
    创建了具有未指定顺序的映射,因此这将拾取任意组。除此之外,仅请求
    count()

  • .orElse((long)-1)
    -1
    对于计数来说是一个非常奇怪的倒退,因为当没有匹配项时,最自然的答案是“零”

因此,一个直接的解决方案是

public static long countWordOccurence(List<String> wordList, String word) {
    return Collections.frequency(wordList, word);
}
获取区分大小写的匹配项计数,以及

public static long countWordOccurence(String sentence, String word) {
    if(!word.codePoints().allMatch(Character::isLetter))
        throw new IllegalArgumentException(word+" is not a word");
    Pattern p = Pattern.compile("\\b"+word+"\\b", Pattern.CASE_INSENSITIVE);
    return p.matcher(sentence).results().count();
}
对于不区分大小写的匹配。
\b
模式表示单词边界,仅当搜索字符串实际上是一个单词时才有意义。因此,上面的方法对此进行了预测试,这也确保了单词中不包含可能被误解为正则表达式模式的字符

Java 9中引入了
results()
方法。显示了在Java 8下创建此类流的解决方案,但是,对于计数事件这样的简单任务,替代方法是在此处不使用流:

public static long countWordOccurence(String sentence, String word) {
    if(!word.codePoints().allMatch(Character::isLetter))
        throw new IllegalArgumentException(word+" is not a word");
    Pattern p = Pattern.compile("\\b"+word+"\\b", Pattern.CASE_INSENSITIVE);
    int count = 0;
    for(Matcher m = p.matcher(sentence); m.find(); count++) {}
    return count;
}

删除我的答案,你的封面more@Holger令人印象深刻的回答,非常感谢您的承诺。@AndrewTobilko您的回答也很有用。你可以离开它。非常感谢你的承诺。@Martin没关系。我很高兴霍尔格回答了你的问题:)
public static long countWordOccurence(String sentence, String word) {
    if(!word.codePoints().allMatch(Character::isLetter))
        throw new IllegalArgumentException(word+" is not a word");
    Pattern p = Pattern.compile("\\b"+word+"\\b");
    return p.matcher(sentence).results().count();
}
public static long countWordOccurence(String sentence, String word) {
    if(!word.codePoints().allMatch(Character::isLetter))
        throw new IllegalArgumentException(word+" is not a word");
    Pattern p = Pattern.compile("\\b"+word+"\\b", Pattern.CASE_INSENSITIVE);
    return p.matcher(sentence).results().count();
}
public static long countWordOccurence(String sentence, String word) {
    if(!word.codePoints().allMatch(Character::isLetter))
        throw new IllegalArgumentException(word+" is not a word");
    Pattern p = Pattern.compile("\\b"+word+"\\b", Pattern.CASE_INSENSITIVE);
    int count = 0;
    for(Matcher m = p.matcher(sentence); m.find(); count++) {}
    return count;
}