Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting and sub listing from lambda expression

I have an array list with the following elements:

List<Record> list = new ArrayList<>();
list.add(new Record(3, "32"));
list.add(new Record(4, "42"));
list.add(new Record(1, "12"));
list.add(new Record(1, "11"));
list.add(new Record(2, "22"));
list.add(new Record(5, "52"));
list.add(new Record(5, "53"));
list.add(new Record(5, "51"));

Record is a simple POJO that has id and name

I want to do those to the list.

  • Create a map like Map<Integer, List<Record>> that has a key is id and slimier key add as a list.I have done it as bellow.

    Map<Integer, List<Record>> map = list.stream()
        .collect(Collectors.groupingBy(Record::getId, HashMap::new, Collectors.toList()));
    
  • Now i want to sort the list by name and sub list to provided limit inside map

    map.forEach((k, v) -> v.stream().sorted(Comparator.comparing(Record::getName)));    
    map.forEach((k, v) -> map.put(k, v.subList(0, Math.min(**limit**, v.size()))));
    

I have tried like above and looks like this is not a good way. Can anyone suggest a better way?

like image 712
Prabhath Avatar asked Feb 16 '18 13:02

Prabhath


People also ask

How do you sort a list in Lambda Python?

The list. sort() method key parameter is set to lambda. The arguement x is the iterable element ( tuple ) to be sorted by the second element, the number. The lambda expression sorts the list by the second element of the tuple value and updates the original.

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 do you sort a list using comparator in Java 8?

sort(Comparator. comparing(Movie::getStarred, (star1, star2) -> { if(star1 == star2){ return 0; } return star1 ? -1 : 1; })); In the last example, Comparator. comparing() takes the function to extract the key to use for sorting as the first parameter, and a Comparator as the second parameter.


2 Answers

You can use Java 8 Collectors.collectingAndThen() method:

Map<Integer, List<Record>> map = list.stream()
    .collect(Collectors.groupingBy(
        Record::getId,
        Collectors.collectingAndThen(
            Collectors.toList(),
            records -> records.stream()
                              .sorted(Comparator.comparing(Record::getName))
                              .limit(limit)
                              .collect(Collectors.toList()))));
like image 160
Oleksandr Pyrohov Avatar answered Sep 18 '22 14:09

Oleksandr Pyrohov


You could use Collectors.collectingAndThen:

Map<Integer, List<Record>> result = list.stream()
    .collect(Collectors.groupingBy(
         Record::getId,
         Collectors.collectingAndThen(
             Collectors.toCollection(ArrayList::new),
             v -> {
                 v.sort(Comparator.comparing(Record::getName));
                 return v.subList(0, Math.min(LIMIT, v.size()));
             })));

This solution avoids creating a new stream for each list group.

As pointed out in this answer, by using Collectors.toCollection(ArrayList::new) we ensure that the list is mutable, so that we can later sort it in place.

like image 37
fps Avatar answered Sep 20 '22 14:09

fps