I have a list of objects and would like to get the person object with the lowest score. I'm relatively new to the streaming subject and was thinking what would be the best way to handle it.
public class Person {
private String id;
private List<Rating> ratingList;
}
public class Rating {
private String rating;
private LocalDate ratingDate;
}
I have a service that gets a list of Person objects with ratings from the DB.
Firstly I grouped the List to have a list of persons with ratings
Map<String, List<Rating>> groupedList
Then I mapped it to have a List of Person Objects with a latest rating only
groupedList.entrySet().stream.map(element -> new Person(element.getKey(), element.getValue().stream().max(Comparator.comparing(Rating::getRatingDate)).stream().collect(Collectors.toList())))
And here is the question when I already have a list of Persons with the latest rating what would be the best way to only have a one Person returned that has the lowest rating of all. I was thinking to use the .reduce() method but I always ended up with a List having all persons from the initial list
CodePudding user response:
Here is fully functional example on how you could do it. The difference is that I changed rating to int
for easier comparing. However it shouldn't be to hard to adapt it to String
type.
The important part of this code is
persons.stream().min((e1, e2) -> e1.ratingList.stream().min((o1, o2) -> o1.rating - o2.rating).get().rating
- e2.ratingList.stream().min((o1, o2) -> o1.rating - o2.rating).get().rating).get()
What it does, is to compare persons by their lowest ratings, to find the person with the lowest rating.
Another approach requires an additional field which you can map the lowest rating to. This approach looks cleaner and is also probably more performant:
persons.stream()
.map(e -> t.new Person(e.id, e.ratingList.stream().min((o1, o2) -> o1.rating - o2.rating).get().rating))
.min((e1, e2) -> e1.lowestRating - e2.lowestRating).get()
The classes I adapted are:
class Person {
private String id;
private List<Rating> ratingList;
private int lowestRating;
public Person() {
}
public Person(String id2, int rating) {
id = id2;
lowestRating = rating;
}
}
class Rating {
private int rating;
private LocalDate ratingDate;
Rating(int rating, LocalDate date) {
this.rating = rating;
ratingDate = date;
}
}