对于我的任务,我必须用循环来替换for循环,这些循环计算文本文档中单词的频率,并且我无法计算出TODO部分.
String filename = "SophieSallyJack.txt";
if (args.length == 1) {
filename = args[0];
}
Map<String, Integer> wordFrequency = new TreeMap<>();
List<String> incoming = Utilities.readAFile(filename);
wordFrequency = incoming.stream()
.map(String::toLowerCase)
.filter(word -> !word.trim().isEmpty())
.collect(Collectors.toMap(word -> word, word -> 1, (a, b) -> a + b, TreeMap::new));
int maxCnt = 0;
// TODO add a single statement that uses streams to determine maxCnt
for (String word : incoming) {
Integer cnt = wordFrequency.get(word);
if (cnt != null) {
if (cnt > maxCnt) {
maxCnt = cnt;
}
}
}
System.out.print("Words that appear " + maxCnt + " times:");
Run Code Online (Sandbox Code Playgroud)
我试过这个:
wordFrequency = incoming.parallelStream().
collect(Collectors.toConcurrentMap(w -> w, w -> 1, Integer::sum));
Run Code Online (Sandbox Code Playgroud)
但这不对,我不确定如何将maxCnt合并到流中.
假设您从文件中提取了所有单词,List<String>可以使用这种方法计算每个单词的单词计数,
Map<String, Long> wordToCountMap = words.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)
然后可以使用上面的方法计算最常用的单词,map如下所示,
Entry<String, Long> mostFreequentWord = wordToCountMap.entrySet().stream()
.max(Map.Entry.comparingByValue())
.orElse(new AbstractMap.SimpleEntry<>("Invalid", 0l));
Run Code Online (Sandbox Code Playgroud)
如果您愿意,您可以将上述两个管道一起更改,
Entry<String, Long> mostFreequentWord = words.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.max(Map.Entry.comparingByValue())
.orElse(new AbstractMap.SimpleEntry<>("Invalid", 0l));
Run Code Online (Sandbox Code Playgroud)
更新
Optional根据以下讨论,从计算中返回 an 总是好的,如下所示,
Optional<Entry<String, Long>> mostFreequentWord = words.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.max(Map.Entry.comparingByValue());
Run Code Online (Sandbox Code Playgroud)