大家好,在使用流时,都有这样一个问题。我有一张要根据其中出现字符的频率排序的工作表:
List<String> frequency = new ArrayList<>();
Collections.addAll(frequency, "gg", "ss", "gg", "boy", "girls", "girls", "gg", "boy", "aa", "aa");
我写了这个方法:
return words.stream().limit(limit).map(String::toLowerCase)
.collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
.entrySet().stream()
.map(entry -> new Pair<>(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
但是已经显示的答案不正确,字符串a完全丢失,字符串gg是一个元素,男孩是一个元素
ss=1
gg=2
girls=2
boy=1
我不知道如何按照出现的频率对它们进行排序。 结果应该是这样的:
gg=3
aa=2
boy=2
girls=2
ss=1
如何改善?
答案 0 :(得分:4)
您可以这样做
Map<String, Long> wordCount = frequency.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue(Comparator.reverseOrder())
.thenComparing(Map.Entry.comparingByKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(e1, e2) -> e2, LinkedHashMap::new));
输出:{gg=3, aa=2, boy=2, girls=2, ss=1}
请注意,由于没有键冲突,因此此处未使用mergeFunction。
答案 1 :(得分:1)
删除.limit(limit)
,因为它使Stream
管道仅处理前limit
个元素(根据您的输出,limit
为6
)。
return
frequency.stream()
.map(String::toLowerCase)
.collect(Collectors.groupingBy(Function.identity(),Collectors.counting()))
.entrySet().stream()
.map(entry -> new SimpleEntry<>(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
输出:
[aa=2, ss=1, gg=3, girls=2, boy=2]