使用Java 8 Stream API进行计数和排序 [英] Counting and order with Java 8 Stream API
本文介绍了使用Java 8 Stream API进行计数和排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想知道如何通过COUNT然后ASC订购。
I wonder how could this be ordered by COUNT then ASC.
Stream<String> fruits = Stream.of("apple", "orange", "ananas");
Map<String, Long> letters =
fruits.map(w -> w.split(""))
.flatMap(Arrays::stream)
.collect(groupingBy(identity(), counting()));
输出:
{p=2, a=5, r=1, s=1, e=2, g=1, l=1, n=3, o=1}`
所需的输出:
{a=5, n=3, e=2, p=2, g=1, l=1, r=1, s=1, o=1}
推荐答案
在您根据计数进行排序之前,首先需要计数,这是不可避免的两个映射步骤:
It’s unavoidable to do it in two mapping steps as you need the counts first, before you can sort according to the counts:
Map<String, Long> letters = fruits
.flatMap(Pattern.compile("")::splitAsStream)
.collect(groupingBy(identity(), counting()))
.entrySet().stream().sorted(Map.Entry.comparingByValue(reverseOrder()))
.collect(LinkedHashMap::new, (m,e) -> m.put(e.getKey(), e.getValue()), Map::putAll);
如果您认为只有ASCII小写字母(或任何其他小的固定大小的字母组)你可以尝试一种可能更有效的替代方法。它将处理字符并计为原始值,存储在固定大小的数组中。对象仅为最终排序生成,地图
生成:
If you assume that there are only ASCII lower case letters (or any other small fixed-size set of characters), you can try an alternative approach which might be more efficient. It will process the characters and counts as primitive values, being stored in a fixed size array. Objects are only generated for the final sorting and Map
generation:
long[] histogram=fruits.flatMapToInt(String::chars)
.filter(c -> c>='a' && c<='z')// just to be sure, remove if you prefer exceptions
.collect(()->new long[26],(a,c)->a[c-'a']++, (a,b)->Arrays.setAll(a, ix->a[ix]+b[ix]));
Map<String, Long> letters=IntStream.range(0, 26).filter(i->histogram[i]!=0)
.boxed().sorted(comparingLong(i -> -histogram[i]))
.collect(LinkedHashMap::new, (m,i)->m.put(""+(char)(i+'a'),histogram[i]), Map::putAll);
这篇关于使用Java 8 Stream API进行计数和排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文