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 g
Since the result is supposed to be a list, you‘re not grouping but simply sorting (in the sense of changing the order according to a defined rule). The main obstacle is that you want the locations to be ordered after their first encounter in the original list.
The straight-forward approach is to fix this location order first, followed by a single sort operation:
Map locationOrder = studlist.stream()
.collect(HashMap::new,
(m,s)->m.putIfAbsent(s.stud_location, m.size()),
(m1,m2)->m2.keySet().forEach(l->m1.putIfAbsent(l, m1.size())));
studlist.sort(Comparator.comparingInt((Student s) -> locationOrder.get(s.stud_location))
.thenComparing(s -> s.stud_id));
If you can not or do not want to modify the original list, you can simply use a copy:
List result = new ArrayList<>(studlist);
result.sort(Comparator.comparingInt((Student s) -> locationOrder.get(s.stud_location))
.thenComparing(s -> s.stud_id));
It’s also possible to solve this with a grouping operation, but that’s not easier:
List result = studlist.stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(s -> s.stud_location,
LinkedHashMap::new, Collectors.toList()),
m -> m.values().stream()
.flatMap(l -> l.stream().sorted(Comparator.comparing(s->s.stud_id)))
.collect(Collectors.toList())));
Note that you have to collect into a LinkedHashMap
to ensure that the order of the groups is retained.