Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Java8/11 stream grouping and sorting on aggregate count

I have an stream of objects as a parameter to a function(I can only consume the stream once).

Object has an string attribute called category.

I need a sorted list of categories.
I need to sort it based on number of occurences of each category.
If number of occurences are same, then lexicographically order the categories.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

java8 stream grouping and sorting on aggregate sum

I basically need something like this but I don’t have the luxury of consuming the stream more than once.

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

Output 
List = {category1, categoryA, categoryB}

>Solution :

You can generate a Map of frequencies for each category of type Map<String,Long> (count by category).

Then create a stream over its entries and sort them (by Value, i.e. by count, and Key, i.e. lexicographically), extract the category from each entry and store the result into a list.

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();
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading