1

我是 Guava 库的新手,并尝试使用它的一些类来简化我的代码。我遇到了按值对 Map 进行排序的需要。快速搜索发现这篇文章发布了一个接受的答案,如下代码片段:

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

有人可以为我澄清一下这是如何工作的吗?我无法理解某些事情。

排序的定义是Ordering<T>。在这种情况下<T>将是Map.Entry. 此外, 的方法签名onResultOfonResultOf(Function<F,? extends T> function)

在上面的代码中,onResultOf使用以下参数调用:

onResultOf(new Function<Entry<Key, Value>, Value>())

在这种情况下,这意味着:

<F> = Entry<Key, Value>
<? extends T> = Value

这反过来又意味着 thatValue是一种可以扩展 a 的类型Map.Entry

这怎么可能?当入口映射包含 Key、Value 时,如何Value成为可以扩展的类型?Map.Entry

我确信我误读或误解了某些东西,但如果有人能对此有所了解,我希望它能帮助我更好地理解 Guava 和 Ordering() 类。尤其是onResultOf(Function)工作原理。

4

3 回答 3

3

这里创建了三个不同的 Ordering,其中一个的类型与其他的不同。您的代码代码被重写为:

Ordering<Value> valueOrdering = Ordering.from(valueComparator);
Ordering<Map.Entry<Key, Value>> entryOrdering = valueOrdering
     .onResultOf(new Function<Entry<Key, Value>, Value>() {
         public Value apply(Entry<Key, Value> entry) {
            return entry.getValue();
         }
});
Ordering<Map.Entry<Key, Value>> finalOrdering = entryOrdering.reverse();
于 2013-08-08T18:58:12.480 回答
2

的方法签名onResultOf是:

public <F> Ordering<F> onResultOf(Function<F,? extends T> function)

F代替T。_ 为了匹配前面的定义,它应该被重写为

public <T> Ordering<T> onResultOf(Function<T,? extends U> function)

所以参数 toonResultOf实际上是Function< Map.Entry<Key, Value>, ? extends U >,因此,第二个参数不必扩展Map.Entry

于 2013-08-08T19:09:57.853 回答
1

Ordering也许你对这个类被声明为Ordering<T>,但onResultOf方法的返回值是的事实感到困惑Ordering<F>

Function您提供给的第一个onResultOf类型参数是结果的类型参数。

这也意味着, thatValue不会被强制成为Map.Entry.

于 2013-08-08T19:02:56.767 回答