使用Integer.max作为比较器的Java 8 Lambdas max()

时间:2016-03-17 12:29:32

标签: java lambda java-8

我用简单的List编写了示例值,我希望流从Stream返回最大值。我知道max()函数需要Comparator但事实证明,我也可以通过Integer::max(任何人都可以解释我的,为什么?)。

此外,程序打印出奇怪的结果,我在“内部”检查它看起来没问题,但在我得到最终结果后 - 它们不准确。

示例:

@Test
public void testHowIntegerMaxWorksInStream() {
    List<Integer> list = Arrays.asList(5,3,8);
    Optional<Integer> op = list.stream().max((a, b) -> {
        System.out.println("Input arguments a=" + a + ", b=" + b);

        int max = Integer.max(a, b);
        System.out.println("Returning max(a,b)=" + max);
        return max;
    });
    System.out.println("Optional result=" + op.get());
}

输出:

Input arguments a=5, b=3
Returning max(a,b)=5
Input arguments a=5, b=8
Returning max(a,b)=8 // OK, Integer::max got 8.. but then ...
Optional result=5 // .. I got 5. WHY ???

我的问题:

  1. 为什么我可以通过Integer::max代替Comparator
  2. 为什么我的函数返回5作为结果,而在其中8?

3 个答案:

答案 0 :(得分:6)

你误解了事情。 max(comparator)使用比较整数的比较器。你正在做的不是比较整数,即告诉a是否大于b。你拿走了他们的最大值并将其归还。所以你说a总是大于b,因为你总是返回一个正数(你的列表只包含正数)。 Comparator返回:

  

负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数。

您需要做的是

public void testHowIntegerMaxWorksInStream() {
    List<Integer> list = Arrays.asList(5,3,8);
    Optional<Integer> op = list.stream().max((a, b) -> {
        int compare = Integer.compare(a, b);
        return compare;
    });
    System.out.println("Optional result=" + op.get());
}

即。调用Integer.compare而不是max,这正是这样做的:

  

比较其订单的两个参数。当第一个参数小于,等于或大于第二个参数时,返回负整数,零或正整数。

关于问题的第二部分,请参阅:: (double colon) operator in Java 8。它被称为方法 - 反射。所以另一种写作方式是:

List<Integer> list = Arrays.asList(5,3,8);
Optional<Integer> op = list.stream().max(Integer::compare);
System.out.println("Optional result=" + op.get());

答案 1 :(得分:5)

遗憾的是,Integer.max代替比较器编译的原因是它的返回类型符合stream max方法的预期:比较的结果是{ {1}},比较两个int s的结果也是int。但是,int返回的结果与流Integer.max所期望的结果不一致,这解释了错误的结果:例如,如果您将max传递给(5, 8)它返回Integer.max,一个正数;然而,流的8将所有正数解释为第一个参数大于第二个参数的指示,这在这种情况下是不正确的。

此编译的唯一原因是比较器返回max。这不适用于intDouble

答案 2 :(得分:1)

因为您创建的Comparator总是返回第一个元素。

如果您比较AB,如果-1较小,则应返回A。您返回Integer.maxA的{​​{1}},在您的情况下,始终为B

>0