简体   繁体   English

Java-Stream - 根据 Java 11 中的聚合计数进行分组和排序

[英]Java-Stream - Grouping and Sorting based on aggregate count in Java 11

I have a Stream of custom objects as a parameter to a method.我有一个Stream的自定义对象作为方法的参数。 And obviously I can consume the Stream only once.显然我只能使用 Stream 一次。

My object has a String attribute called category .我的 object 有一个名为categoryString属性。

public class MyType {
    private String category;
    
    // other properties, getters, etc.
}

I need a sorted list of categories List<String> .我需要一个分类列表List<String>

First, I need to sort the data based on the number of occurrences of each category.首先,我需要根据每个类别的出现次数对数据进行排序。 If the number of occurrences is the same, then sort such categories lexicographically.如果出现次数相同,则按字典顺序对此类类别进行排序。

Basically, I need something like this基本上,我需要这样的东西

java8 stream grouping and sorting on aggregate sum java8 stream 对总和进行分组和排序

but I don't have the luxury of consuming the stream more than once.我没有不止一次消费 stream 的奢侈。 So I don't know how to address this problem.所以我不知道如何解决这个问题。

Here's an example:这是一个例子:

Input:输入:

{
    object1 :{category:"category1"},
    object2 :{category:"categoryB"},
    object3 :{category:"categoryA"},
    object4 :{category:"category1"},
    object5 :{category:"categoryB"},
    object6 :{category:"category1"},
    object7 :{category:"categoryA"}
}

Output: Output:

List = {category1, categoryA, categoryB}

You can generate a Map of frequencies for each category of type Map<String,Long> ( count by category ).您可以为类型为Map<String,Long>的每个类别生成 Map 的频率(按类别计数)。

Then create a stream over its entries and sort them ( by Value, ie by count, and Key, ie lexicographically ), extract the category from each entry and store the result into a list.然后在其条目上创建一个 stream 并对它们进行排序(按值,即按计数,和键,即字典顺序),从每个条目中提取类别并将结果存储到列表中。

Assuming that you have the following domain type:假设您具有以下域类型:

public class MyType {
    private String category;
    
    // getters
}

Method generating a sorted list of categories might be implemented like this:生成分类列表的方法可以这样实现:

public static List<String> getSortedCategories(Stream<MyType> stream) {
    
    return stream.collect(Collectors.groupingBy(
            MyType::getCategory,
            Collectors.counting()
        ))
        .entrySet().stream()
        .sorted(
            Map.Entry.<String, Long>comparingByValue()
                .thenComparing(Map.Entry.comparingByKey())
        )
        .map(Map.Entry::getKey)
        .toList();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM