С гуавой есть даже более чистый путь, чем у ответа Лоис Вассермана - использование порядка в сочетании с Functions.forMap
:
Ordering.natural().reverse().nullsLast().onResultOf(Functions.forMap(map, null))
или если значения не Comparable
:
Ordering.fromComparator(yourComparator).reverse().nullsLast().onResultOf(Functions.forMap(map, null))
Пример (с первым вариантом - естественный порядок):
final Map<String, String> map = ImmutableMap.of(
"key 1", "value 1",
"key 2", "value 2",
"key 3", "another value",
"key 4", "zero value");
final Ordering<String> naturalReverseValueOrdering =
Ordering.natural().reverse().nullsLast().onResultOf(Functions.forMap(map, null));
System.out.println(ImmutableSortedMap.copyOf(map, naturalReverseValueOrdering));
выходы:
{key 4=zero value, key 2=value 2, key 1=value 1, key 3=another value}
(здесь я использую ImmutableSortedMap , но TreeMap также можно использовать, если требуется изменчивость.)
EDIT :
Если есть идентичные значения (точнее, если есть два значения, для которых Comparator.compare(String v1, String v2)
возвращает 0), ImmutableSortedMap выдает исключение. Порядок не должен возвращаться, то есть вы должны упорядочить карту сначала по значениям, а затем ключи, если оба значения равны (ключи не должны быть равными), используя Ordering.compound
:
final Map<String, String> map = ImmutableMap.of(
"key 1", "value 1",
"key 2", "value 2",
"key 3", "zero value",
"key 4", "zero value");
final Ordering<String> reverseValuesAndNaturalKeysOrdering =
Ordering.natural().reverse().nullsLast().onResultOf(Functions.forMap(map, null)) // natural for values
.compound(Ordering.natural()); // secondary - natural ordering of keys
System.out.println(ImmutableSortedMap.copyOf(map, reverseValuesAndNaturalKeysOrdering));
печать:
{key 3=zero value, key 4=zero value, key 2=value 2, key 1=value 1}