【问题标题】:Stream sorted method with comparator带比较器的流排序方法
【发布时间】:2017-10-27 09:17:14
【问题描述】:

我不明白为什么 code1 有效但 code2 无法编译。请解释一下。

//Code1:
    Stream<String> s = Stream.of("AA", "BB");
    s.sorted(Comparator.reverseOrder())
            .forEach(System.out::print);

//Code2:
    Stream<String> s = Stream.of("AA", "BB");
    s.sorted(Comparator::reverseOrder)
            .forEach(System.out::print);

两者的区别在于code1使用Comparator.reverseOrder()code2使用Comparator::reverseOrder

【问题讨论】:

    标签: java java-stream method-reference


    【解决方案1】:

    因为第一个示例是 factory-method,所以当您检查它时,您会看到返回了一个比较器。

    但第二个是method-reference,你可以这样写:

    Stream<String> s = Stream.of("AA", "BB");
    s.sorted(() -> Comparator.reverseOrder()) // no semantic difference!
        .forEach(System.out::print);
    

    但它有一个完全不同的含义,因为这次给你Stream#sorted()一个Supplier&lt;Comparator&lt;?&gt;&gt;,但它只需要一个Comparator&lt;?&gt;

    小旁注:不要将流存储在变量中,直接使用它们。所以我建议你写:

    Stream.of("AA", "BB")
        .sorted(Comparator.reverseOrder())
        .forEach(System.out::print);
    

    【讨论】:

      【解决方案2】:

      编译器的错误信息应该告诉你。

      sorted() 需要一个 Comparator 实例。 Comparator.reverseOrder()返回一个 Comparator 实例。所以效果很好。

      Comparator::reverseOrder 是对 Comparator 的 reverseOrder() 方法的方法引用。所以你的代码基本上说:每次你需要比较两个字符串时,将它们作为参数传递给Comparator.reverseOrder 来比较它们。但这不可能奏效。此方法不接受任何参数,并返回一个比较器。所以它与Comparator&lt;String&gt; 的签名不匹配,Comparator&lt;String&gt; 应该接受两个字符串作为参数,并返回一个整数。

      如果你有这样的方法

      class Foo
          public static int compareStrings(String s1, String s2) {
              ...
          }
      }
      

      那么你可以使用

      sorted((s1, s2) -> Foo.compareStrings(s1, s2))
      

      您可以使用方法引用将其转换为

      sorted(Foo::compareStrings)
      

      因为 compareStrings 就像 Comparator&lt;String&gt; 的唯一抽象方法一样,接受两个字符串作为参数并返回一个 int。

      【讨论】:

        猜你喜欢
        • 2021-02-22
        • 1970-01-01
        • 1970-01-01
        • 2021-09-04
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多