I use Guava’s Ordering class to perfom sorting to pick the ‘best’ from a given list. It looks something like this:
// Create the Ordering, with a list of Comparators
Ordering<String> ranker = Ordering.compound(ImmutableList.of(
STRING_LENGTH,
PERCENTAGE_UPPERCASE,
NUMBER_OF_VOWELS));
// Use the ordering to find the 'best' from a list of Strings
String best = ranker.max(asList("foo", "fooz", "Bar", "AEro"));
With this Ordering, the String “AEro” is the best because it’s the longest, joint-best with “fooz”, but tiebreaks with a higher percentage of uppercase characters.
I am looking for a way to tell which Comparator ‘broke the tie’, which in this silly contrived example would be the comparator PERCENTAGE_UPPERCASE.
I have a workable solution, but it’s not particularly elegant, and means duplicating the list of Comparators. It is to use the Ordering to provide a sorted list (Ordering.sortedCopy), pulling the first two elements (range checking of course), iterating through a List of the same Comparators, comparing those two elements, breaking when the compareTo method returns non-zero result.
Is there a neater way?
Guava contributor here.
Your solution seems like it’s nearly as good as you’re going to get, but instead of doing a sorted copy and pulling the first two elements, you should do the more efficient
and then, indeed, iterate through the comparators, though you can probably refactor so you’re reusing the list of comparators from
Ordering.compound, not recreating it.