java - 使用 Java Streams 返回单词出现的句子计数和列表

我一直在试图弄清楚每个单词出现在什么句子中。该条目将是一个句子列表

Question, what kind of wine is best? 
White wine.
A question

输出为

// format would be: word:{count: sentence1, sentence2,...}
a:{1:3} 
wine:{2:1,2} 
best:{1:1} 
is:{1:1} 
kind:{1:1} 
of:{1:1} 
question:{2:1,3} 
what:{1:1}
white:{1:2}

这是我目前得到的:

static void getFrequency(List<String> inputLines) {
  List<String> list = inputLines.stream()
     .map(w -> w.split("[^a-zA-Z0-9]+"))
     .flatMap(Arrays::stream)
     .map(String::toLowerCase)
     .collect(Collectors.toList());

   Map<String, Integer> wordCounter = list.stream()
     .collect(Collectors.toMap(w -> w, w -> 1, Integer::sum));
}

有了这个,我只得到每个单词在所有句子中出现的次数,但我还需要得到单词出现的句子列表。看起来我可以使用 IntStream.range 获取句子的 id,像这样:

 IntStream.range(1, inputLines.size())
          .mapToObj(i -> inputLines.get(i));

但我不确定这是否是最好的方法,我是 Java 新手

最佳答案

您可以使用分组收集器来计算单词到索引列表的映射。这是一个例子:

private static Map<String, List<Integer>> getFrequency(List<String> inputLines) {
    return IntStream.range(0, inputLines.size())
            .mapToObj(line -> Arrays.stream(inputLines.get(line)
                 .split("[^a-zA-Z0-9]+"))
                 .map(word -> new SimpleEntry<>(word.toLowerCase(), line + 1)))
            .flatMap(Function.identity())
            .collect(Collectors.groupingBy(Entry::getKey, 
                  Collectors.mapping(Entry::getValue, Collectors.toList())));
}

有了你的测试数据,我得到了

{a=[3], what=[1], white=[2], question=[1, 3], kind=[1], 
 of=[1], best=[1], is=[1], wine=[1, 2]}

计数很容易从列表大小推断出来,因此不需要额外的类。

https://stackoverflow.com/questions/67024027/

相关文章:

python - 替代全局变量

numpy - 在 Julia 中替代 python 的 np.meshgrid()?

macos - 使用 M1 mac 将 Rust 程序编译为 exe?

flutter - 解决依赖关系 : pub finished with exit code 1

html - 如何在 tailwind-css 中水平对齐图像

java - Java 8 是否提供了一种根据特定条件重复功能的好方法?

c++ - 是否有一种算法可以快速将大量十六进制字符串转换为字节流?汇编/C/C++

angular - 类型 'null' 的参数不可分配给参数 Angular

reactjs - Eslint错误: Do not nest ternary expression

r - 错误延迟加载包 'devtools' 失败