我用简单的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 ???
我的问题:
Integer::max
代替Comparator
?答案 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
。这不适用于int
或Double
。
答案 2 :(得分:1)