Sorting of multiple lists of the same size is possible following these steps:
- Create an array/list of indexes according to the sorting rules (first by names, then by birthdays in appropriate YYYYMMDD format, etc.)
List<String> names = Arrays.asList("bbb", "aaa", "bbb", "aaa");
List<String> phones = Arrays.asList("1023456", "1324560", "1227890", "1446752");
List<String> bdays = Arrays.asList("20001122", "19980105", "20010614", "19990507");
int[] indexes = IntStream.range(0, names.size())
.boxed()
.sorted(Comparator.comparing(names::get).thenComparing(bdays::get))
.mapToInt(Integer::intValue)
.toArray(); // -> [1, 3, 0, 2]
- Reorder each of the input lists according to the indexes.
A separate method may be created for this:
private static List<String> sort(List<String> list, int[] indexes) {
return Arrays.stream(indexes).mapToObj(list::get).collect(Collectors.toList());
}
// ...
System.out.println(sort(names, indexes)); -> [aaa, aaa, bbb, bbb]
System.out.println(sort(phones, indexes)); -> [1324560, 1446752, 1023456, 1227890]
System.out.println(sort(bdays, indexes)); -> [19980105, 19990507, 20001122, 20010614]
However, it would be more natural to create a container object to combine the values from the different input lists, which has become quite simple after introducing record
classes in Java 16, and the sort these objects:
record Person(String name, String phone, String bday) {}
List<Person> persons = IntStream.range(0, names.size())
.boxed()
.map(i -> new Person(names.get(i), phones.get(i), bdays.get(i)))
.sorted(Comparator.comparing(Person::name).thenComparing(Person::bday))
.collect(Collectors.toList());
persons.forEach(System.out::println);
Output:
Person[name=aaa, phone=1324560, bday=19980105]
Person[name=aaa, phone=1446752, bday=19990507]
Person[name=bbb, phone=1023456, bday=20001122]
Person[name=bbb, phone=1227890, bday=20010614]