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?
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.
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.
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.
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()))));
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With