Reputation: 18521
I am trying to group by a collection by a value that appears in my object as a list.
This is the model that I have
public class Student {
String stud_id;
String stud_name;
List<String> stud_location = new ArrayList<>();
public Student(String stud_id, String stud_name, String... stud_location) {
this.stud_id = stud_id;
this.stud_name = stud_name;
this.stud_location.addAll(Arrays.asList(stud_location));
}
}
When I initialize it with the following :
List<Student> studlist = new ArrayList<Student>();
studlist.add(new Student("1726", "John", "New York","California"));
studlist.add(new Student("4321", "Max", "California"));
studlist.add(new Student("2234", "Andrew", "Los Angeles","California"));
studlist.add(new Student("5223", "Michael", "New York"));
studlist.add(new Student("7765", "Sam", "California"));
studlist.add(new Student("3442", "Mark", "New York"));
I want to get the following :
California -> Student(1726),Student(4321),Student(2234),Student(7765)
New York -> Student(1726),Student(5223),Student(3442)
Los Angeles => Student(2234)
I try to write the following
Map<Student, List<String>> x = studlist.stream()
.flatMap(student -> student.getStud_location().stream().map(loc -> new Tuple(loc, student)))
.collect(Collectors.groupingBy(y->y.getLocation(), mapping(Entry::getValue, toList())));
But I am having trouble completing it - how do I keep the original student after the mapping?
Upvotes: 2
Views: 405
Reputation: 6471
Summing up the comments above, the collected wisdom would suggest:
Map<String, List<Student>> x = studlist.stream()
.flatMap(student -> student.getStud_location().stream().map(loc -> new AbstractMap.SimpleEntry<>(loc, student)))
.collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, toList())));
As an alternate approach, if you don't mind the Students in each list containing only that location, you might consider flattening the Student list to Students with only one location:
Map<String, List<Student>> x = studlist.stream()
.flatMap( student ->
student.stud_location.stream().map( loc ->
new Student(student.stud_id, student.stud_name, loc))
).collect(Collectors.groupingBy( student -> student.stud_location.get(0)));
Upvotes: 1