【问题标题】:Sorting array with streams using reversed comparator [duplicate]使用反向比较器对带有流的数组进行排序[重复]
【发布时间】:2016-07-05 04:56:14
【问题描述】:

我想使用第二列上的比较器对具有两列的数组进行排序并反转顺序。

数组是:

String[][] names = {{"a", "1234"}, {"b", "12312"}, {"c", "43"}};

并返回我使用的排序数组:

String[][] out = Arrays.stream(names)
    .sorted(
        Comparator.comparing(x -> x[1])
    )
    .toArray(String[][]::new);

效果很好,但是当我尝试使用 reversed() 反转排序顺序时:

String[][] out = Arrays.stream(names)
    .sorted(
        Comparator.comparing(x -> x[1]).reversed()
    )
    .toArray(String[][]::new);

我得到错误:

Error:(44, 66) java: array required, but java.lang.Object found

我的 IDE 突出显示了 x[1] 部分中的 x。我做错了什么?

【问题讨论】:

  • 排序后反转数组

标签: java sorting java-8 java-stream


【解决方案1】:

当您添加.reversed() 链调用时,编译器无法将泛型类型参数推断为comparing(),因此您必须显式提供它们。

首先,您需要了解comparing()的完整声明:

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

它有两个类型参数:

  • T - 函数 (lambda) 的输入,即在您的情况下为 String[]
  • U - 函数的返回值,即 String 在您的情况下

所以你可以写:

Comparator.<String[], String>comparing(x -> x[1]).reversed()

或者,您可以在 lambda 中指定参数类型(即T),编译器将推断U

Comparator.comparing((String[] x) -> x[1]).reversed()

这可能是您想要的方式。


如果你愿意,你也可以对第一个做任何一个。这些都是一样的,只是越来越明确:

Comparator.comparing(x -> x[1])
Comparator.comparing((String[] x) -> x[1])
Comparator.<String[], String>comparing(x -> x[1])
Comparator.<String[], String>comparing((String[] x) -> x[1])

【讨论】:

  • 是什么导致泛型类型推断丢失?我还发现将reverseOrder() 与链式comparing() 结合使用可以正常工作,而无需指定任何类型。 Ideone Demo
  • 您必须查看 Java 语言规范中推理规则的细则才能回答这个问题。也许他们会在未来的 Java 版本中对其进行改进,以便也能够针对这种情况进行推断,但在那之前,情况就是这样。如果它推断,很好。如果没有,请按此处所示添加显式类型。
  • @4castle: 链接reverseOrder()comparing() 没有意义,因为后者是static 方法,因此前者根本没有影响。起作用的是嵌套,即Collections.reverseOrder(Comparator.comparing(x -&gt; x[1]))。类型推断不能通过链式方法调用起作用,因为语言设计者担心由此产生的复杂性(泛型类型会影响调用哪个重载方法,进而影响推断的泛型类型)。
猜你喜欢
  • 2014-10-21
  • 2022-01-20
  • 1970-01-01
  • 2020-02-19
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多