可以按值的顺序迭代的映射

Raj*_*pta 16 java collections map apache-commons guava

我需要一个可以按其值的递减顺序迭代的Map .是否有像Apache Commons或Guava这样的标准库提供这种地图?

Lou*_*man 13

我会用番石榴做这件事,如下:

Ordering<Map.Entry<Key, Value>> entryOrdering = Ordering.from(valueComparator)
  .onResultOf(new Function<Entry<Key, Value>, Value>() {
    public Value apply(Entry<Key, Value> entry) {
      return entry.getValue();
    }
  }).reverse();
// Desired entries in desired order.  Put them in an ImmutableMap in this order.
ImmutableMap.Builder<Key, Value> builder = ImmutableMap.builder();
for (Entry<Key, Value> entry : 
    entryOrdering.sortedCopy(map.entrySet())) {
  builder.put(entry.getKey(), entry.getValue());
}
return builder.build();
// ImmutableMap iterates over the entries in the desired order
Run Code Online (Sandbox Code Playgroud)

  • 不要使用Ordering.from(Ordering.natural()),只需直接使用Ordering.natural(). (3认同)

Xae*_*ess 11

使用番石榴,甚至比@ LoisWasserman的anwer更清洁 - 使用Ordering结合Functions.forMap:

Ordering.natural().reverse().nullsLast().onResultOf(Functions.forMap(map, null))
Run Code Online (Sandbox Code Playgroud)

或者如果值不是Comparable:

Ordering.fromComparator(yourComparator).reverse().nullsLast().onResultOf(Functions.forMap(map, null))
Run Code Online (Sandbox Code Playgroud)

一个例子(第一个选项 - 自然排序):

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));
Run Code Online (Sandbox Code Playgroud)

输出:

{key 4=zero value, key 2=value 2, key 1=value 1, key 3=another value}
Run Code Online (Sandbox Code Playgroud)

(我在这里使用ImmutableSortedMap,但如果需要可变性,也可以使用TreeMap.)

编辑:

如果存在相同的值(更确切地说,如果有两个值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));
Run Code Online (Sandbox Code Playgroud)

打印:

{key 3=zero value, key 4=zero value, key 2=value 2, key 1=value 1}
Run Code Online (Sandbox Code Playgroud)

  • 我_think_修改后的答案是正确的,但作为一般规则,如果你可以避免编写可能以许多微妙的方式出错的代码,你应该总是这样做. (2认同)