使用Java 8 Stream API进行计数和排序 [英] Counting and order with Java 8 Stream API

查看:1525
本文介绍了使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆