mle*_*ski 3 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());
}
Run Code Online (Sandbox Code Playgroud)
输出:
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 ???
Run Code Online (Sandbox Code Playgroud)
我的问题:
Integer::max代替Comparator?你是在误解事物.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());
}
Run Code Online (Sandbox Code Playgroud)
即调用Integer.compare而不是max,这正是这样做:
比较它的两个参数的顺序.返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数.
对于问题的第二部分,请参阅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());
Run Code Online (Sandbox Code Playgroud)
其原因Integer.max,不幸的是,编译代替比较的是,它的返回类型适合什么是流的预期max方法:比较的结果是int,并比较两者的结果ints是一个int为好.但是,返回的结果Integer.max与流的max预期不一致,这解释了不正确的结果:例如,如果传递(5, 8)给Integer.max它返回8,则为正数; max然而,流将所有正数解释为第一个参数大于第二个参数的指示,这在这种情况下是不正确的.
这个编译的唯一原因是你的比较器返回一个int.这不适用于Double或BigInteger.
因为您创建的比较器总是返回最大的第一个元素。
如果你比较A和B,你应该返回-1ifA更小。您返回Integer.maxofA和B,在您的情况下,它始终是>0。
(a,b) -> {
if (a>b) return 1; // <-- you return a positive value always, so stream.max() thinks 5>8 :)
if (a<b) return -1;
if (a==b) return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2354 次 |
| 最近记录: |