Search code examples
javaguava

Comparator and unknow value with IncomparableValueException


I use this custom comparator

List<String> currencies = ImmutableList.of("PLN","EUR","USD","GBP", "CHF");
final Ordering<String> currencyOrdering = Ordering.explicit(currencies);

@Override
public int compare(Account o1, Account o2) {
    return currencyOrdering.compare(o1.getCurrency(),o2.getCurrency());
}

But I have error

IncomparableValueException: Cannot compare value: JPY

I would like these unknown values ​​to be randomly at the end... If possible, how to solve it in standard Java library.


Solution

  • What you can do :

        List<String> currencies = ImmutableList.of("OTHERS", "PLN","EUR","USD","GBP", "CHF");
        final Ordering<String> currencyOrdering = Ordering.explicit(currencies).onResultOf(lang -> currencies.contains(lang) ? lang : "OTHERS");
        System.out.println(currencyOrdering.compare("JPY", "PLN")); # -1
        System.out.println(currencyOrdering.compare("JPY", "TTT")); # 0
        System.out.println(currencyOrdering.compare("CHF", "GBP")); # 1
    

    Basically, I ask Guava to map the languages to their own value if they are in currencies list, otherwise I just give them the value OTHERS which is the first one in the list (so everything not in the list is put at the start of the list)

    Note : you can do it without guava with :

        List<String> currencies = List.of("PLN","EUR","USD","GBP", "CHF");
        Comparator<Object> objectComparator = Comparator.comparingInt(currencies::indexOf);
        System.out.println(objectComparator.compare("JPY", "PLN"));
        System.out.println(objectComparator.compare("JPY", "TTT"));
        System.out.println(objectComparator.compare("CHF", "GBP"));
    

    Basically, I specify that the "rank" on item is its position in the list. OTHERS is not needed since missing element will have the value -1