Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 grouping by stud_location and then sorting by stud_id)?

It would be great to have this as extension to the existing Lambda Expression:

Map<String, List<Student>> studlistGrouped =
    studlist.stream().collect(Collectors.groupingBy(w -> w.stud_location));

I need the Grouping based on the order of the Elements in the origin List.

First group: "New York"
Second group: "California"
Third group: "Los Angeles"

1726, "John", "New York"
4321, "Max", "California"
2234, "Andrew", "Los Angeles"
5223, "Michael", "New York"
7765, "Sam", "California"
3442, "Mark", "New York"

The result would then look like the following:

List<Student> groupedAndSorted = ....

    1726, "John", "New York"
    3442, "Mark", "New York"
    5223, "Michael", "New York"
    4321, "Max", "California"
    7765, "Sam", "California"
    2234, "Andrew", "Los Angeles"

I have tried the following:

studlistGrouped.entrySet().stream().sorted(Comparator.compar‌​ing(Map.Entry::getVa‌​lue))

But this doesn't work.

like image 789
ThomasMuller Avatar asked Dec 06 '17 16:12

ThomasMuller


People also ask

What is the use of groupingBy in Java 8?

The groupingBy() method of Collectors class in Java are used for grouping objects by some property and storing results in a Map instance.

How do you sort a list of objects based on an attribute of the objects in Java 8?

Java 8 introduced a sort method in the List interface which can use a comparator. The Comparator. comparing() method accepts a method reference which serves as the basis of the comparison. So we pass User::getCreatedOn to sort by the createdOn field.

How does Collector groupingBy work?

groupingBy. Returns a Collector implementing a cascaded "group by" operation on input elements of type T , grouping elements according to a classification function, and then performing a reduction operation on the values associated with a given key using the specified downstream Collector .

What is the best way to sort list in Java?

Collections class sort() method is used to sort a list in Java. We can sort a list in natural ordering where the list elements must implement Comparable interface. We can also pass a Comparator implementation to define the sorting rules.


1 Answers

not 100% clear whether you're expected a Map<String, List<Student>> or just a List<Student>, nevertheless here are both solutions:

imports:

import static java.util.stream.Collectors.*;
import java.util.*;
import java.util.function.Function;

retrieving a Map<String, List<Student>> where each List<Student> contains students sorted by their ids.

Map<String, List<Student>> resultSet = studlist.stream()
      .collect(groupingBy(Student::getLocation,
             mapping(Function.identity(),
                  collectingAndThen(toList(),
                      e -> e.stream().sorted(Comparator.comparingInt(Student::getId))
                                            .collect(toList())))));

on the other hand, if you want to retrieve just a list of Student objects sorted by a given property then it would be a waste of resources to perform a groupingBy, sorted, collect and somehow reduce the map values into a single list. Rather just sort the Student objects within the list providing a sort key i.e.

studlist.sort(Comparator.comparingInt(Student::getId));

or

studlist.sort(Comparator.comparing(Student::getLocation));

or depending on whether you want to sort by more than one property then you could do something like shmosel's answer.

like image 85
Ousmane D. Avatar answered Sep 23 '22 20:09

Ousmane D.