So I have user input that's a list of 2 elements, and the order of the 2 elements might change. If the input is like ["byName", "byAge"], then I'd need to first sort a collection of data based off name, and if there's a tie between 2 elements, then sort by age.
So if input is
["byName", "byAge"]
and data is
[{"John", 81},
{"Bob", 81},
{"David", 47}]
sorted output would be
[{"Bob", 81},
{"David", 47},
{"John", 81}]
Likewise, if the input list is reversed like ["byAge", "byName"]
, then I'd sort the data by age, and use the name as a tiebreaker.
I'm unsure of what's the cleanest way to dynamically choose a comparator (I need comparators because there's other custom comparison logic I need to implement) based off the input? The most obvious way would be to directly perform a check on which element exists at index 0, i.e. in some lambda chain if input.get(0) == "byAge"
then sort like this. But that's not really extensible, is it?
You can create a map of comparators by name:
Map<String, Comparator<Person>> comparators = new HashMap<>();
comparators.put("byName", Comparator.comparing(Person::getName));
comparators.put("byAge", Comparator.comparing(Person::getAge));
Then chain them on the fly:
List<String> input = Arrays.asList("byName", "byAge");
Comparator<Person> comparator = input.stream()
.map(comparators::get)
.reduce(Comparator::thenComparing)
.orElse((a, b) -> 0);