我正在使用Enthuware的模拟测试来学习1z0-809 : Java SE 8 Programmer II。
遇到这个问题。
List<Integer> ls = Arrays.asList(3,4,6,9,2,5,7); System.out.println(ls.stream().reduce(Integer.MIN_VALUE, (a, b)->a>b?a:b)); //1 System.out.println(ls.stream().max(Integer::max).get()); //2 System.out.println(ls.stream().max(Integer::compare).get()); //3 System.out.println(ls.stream().max((a, b)->a>b?a:b)); //4
以上哪个陈述会打印9?
答案是
1和3
但还有别的东西。我不明白为什么
System.out.println(ls.stream().max(Integer::max).get()); // PRINTS 3
我尝试使用peek
进行调试,但它并不能帮助我理解。
我尝试使用ls
和Integer::max
Integer::compare
进行排序
ls.sort(Integer::max); // [3, 4, 6, 9, 2, 5, 7]
ls.sort(Integer::compare); // [2, 3, 4, 5, 6, 7, 9]
当然,我认为Integer::max
不是比较器,因此它具有相同的签名。
对我来说,max
在第一种情况下应为7
,因为它是最后一个元素,就像我使用Ìnteger::compare
有人可以把它分解成简单的东西吗?
答案 0 :(得分:11)
您需要更换
.max(Integer::max)
与
.max(Integer::compare)
这里的问题是抽象方法compare
被声明返回一个int
值,并且Integer.max
的签名和方法中的方法Integer.compare
也被满足。 Integer
类,因此表示Integer::max
被推断为有效的Comparator
。尽管可以像这样实现比较方法:
返回负整数,零或正整数作为第一个 参数小于,等于或大于第二个。
在您当前的情况下,代码总是以返回正值(给定输入)而结束,因此,比较中的第一个元素总是被认为更大,因此相应地返回。
答案 1 :(得分:10)
Integer.max(a, b)
将返回给定a
和b
的更大值。如果您以某种方式将该结果用作比较器,则返回的正值将被视为a > b
所以a
将被保留。
前两个元素是3和4.两者都是正数。 Integer.max(3, 4) = 4 > 0
。所以你用这样的比较器有效地说3 > 4
,所以保留3。然后,其余部分也是如此:Integer.max(3, 6) = 6 > 0
,因此3被认为是最大等等。
答案 2 :(得分:6)
比较方法的合同(关于参数first
,second
)是:
first
等于second
,则first < second
first > second
仅具有正值的max
方法将始终返回正值。根据比较器合同解释返回值时,正值表示first > second
。因此,项目的顺序不会改变,它们似乎是“有序的”。
答案 3 :(得分:6)
这令人难以置信地令人困惑。
我们正在尝试使用Integer::max
作为比较器。由于问题中的所有数字都是正数,因此答案总是被解释为compare(a, b)
的第一个参数比第二个参数“更大”。
Collections.sort
的一个怪癖是当你有一个列表[a, b]
时,该方法的编程方式是compare(b, a)
被调用,而不是compare(a, b)
(这似乎更明智)。因此,如果compare
返回正数,则它看起来像b > a
,因此列表不需要排序。
这就是list.sort
什么都不做的原因。
然而恰好Stream.max
被编程反过来,即第一次比较是compare(3, 4)
,所以看起来3
是最大值。
答案 4 :(得分:0)
尽管这不能回答问题,但可能的解决方案是:
try{
int i = map.values().stream().mapToInt(e -> e).max().getAsInt();
}catch(NoSuchElementException e)
e.printStackTrace();
}
mapToInt(e -> e)
方法使用lambda表达式将流中的每个元素转换为整数值,然后返回IntStream
,然后可以调用max()
方法。
请注意,max()
返回一个OptionalInteger
,因此需要一个getAsInt()
或一个orElse(0)
方法调用。
您可以查看文档以获取更深入的答案:IntStream,OptionalInt