对java 8中比较器的误解

2022-09-04 22:08:27
public class Test {
    public static void main(String[] args) {
        List<Pair<String, Integer>> list = new ArrayList<>();
        list.add(new Pair<>("1", 8));
        list.add(new Pair<>("3", 2));
        list.add(new Pair<>("2", 15));

        list.stream()
            .sorted(Comparator.comparingInt(p -> p.v))
            .map(p -> p.k)
            .forEach(System.out::println);

    }
}

class Pair<K, V> {
    K k;
    V v;
    public Pair(K k, V v) {
        this.k = k;
        this.v = v;
    }
}

好的,正如你所理解的,这个代码是从最低值到最高值打印我的对键,所以我得到预期的输出:

3 1 2

目前为止,一切都好。现在我想做相反的事情,我想我只需要做

list.stream()
    .sorted(Comparator.comparingInt(p -> p.v).reversed())
    .map(p -> p.k)
    .forEach(System.out::println);

但是我收到一个编译错误:

v cannot be resolved or is not a field

所以它似乎正在返回一个.为什么会这样?它不应该返回一个吗?comparingIntComparator<Object>Comparator<Integer>

这些都是Eclipse Luna版本1和javac的可复制的。

javac -version => 1.8.0
java  -version => java version "1.8.0_25"

哦,也可以随意更改我的问题的标题是你觉得它太笼统了,但我找不到正确的术语


答案 1

我相信只是类型推断失败了,基本上 - 因为调用妨碍了预期的参数类型和lambda表达式。reverse()sorted()

如果将类型显式指定为:comparingInt

list.stream()
    .sorted(Comparator.<Pair<String, Integer>>comparingInt(p -> p.v).reversed())
    .map(p -> p.k)
    .forEach(System.out::println);

或者,如果您只是先声明比较器:

Comparator<Pair<String, Integer>> forward = Comparator.comparingInt(p -> p.v);
list.stream()
    .sorted(forward.reversed())
    .map(p -> p.k)
    .forEach(System.out::println);

在我看来,应该有一个让这种事情变得非常容易,但它看起来并不像:(Stream.reverseSorted


答案 2

推荐