Java 8, Lambda: Sorting within grouped Lists and merging all groups to a list

后端 未结 9 1346
难免孤独
难免孤独 2021-02-09 04:21

Based on the following answer: https://stackoverflow.com/a/30202075/8760211

How to sort each group by stud_id and then return a List with all Students as result of the g

9条回答
  •  庸人自扰
    2021-02-09 04:38

    If I get you right, you want a List (not a map) where students are grouped by their locations and sorted by ids inside groups and where groups are also sorted by ids, not by location names. This is possible, but requires one grouping and two sortings:

    //first, use your function to group students
    Map> studlistGrouped = students.stream()
            .collect(Collectors.groupingBy(Student::getLocation, Collectors.toList()));
    
    //then sort groups by minimum id in each of them
    List sorted = studlistGrouped.entrySet().stream()
            .sorted(Comparator.comparing(e -> e.getValue().stream().map(Student::getId).min(Comparator.naturalOrder()).orElse(0)))
            //and also sort each group before collecting them in one list
            .flatMap(e -> e.getValue().stream().sorted(Comparator.comparing(Student::getId))).collect(Collectors.toList());
    

    This will produce following:

    Student{id='1726', name='John', location='New York'}
    Student{id='3442', name='Mark', location='New York'}
    Student{id='5223', name='Michael', location='New York'}
    Student{id='2234', name='Andrew', location='Los Angeles'}
    Student{id='4321', name='Max', location='California'}
    Student{id='7765', name='Sam', location='California'}
    

    Maybe this can be done more elegantly, suggestions are welcome

    EDIT: At the time this answer was written there was no mention about Grouping based on the order of the Elements in the origin List in the OPs question. So my assumption was to sort both list and groups by ids. For solutions based on the order in the original list see other answers, for example, the Holgers one

提交回复
热议问题