Stream.max(Integer :: max):意外的结果

Yas*_*jaj 8 java compare max java-8 java-stream

我正在学习1z0-809:Java SE 8 Programmer II使用Enthuware的模拟测试.

遇到这个问题.

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   
Run Code Online (Sandbox Code Playgroud)

以上哪个陈述将打印9?

答案是

1和3

但还有别的东西.我不明白为什么

System.out.println(ls.stream().max(Integer::max).get()); // PRINTS 3
Run Code Online (Sandbox Code Playgroud)

我尝试使用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]
Run Code Online (Sandbox Code Playgroud)

当然,我得到的事实Integer::max不是比较器,因此它具有相同的签名.对我来说,max应该是7第一种情况,因为它是我排序时的最后一个元素Ìnteger::compare

有人可以把它分解成简单的东西吗?

Tun*_*aki 11

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被认为是最大值,等等.

  • 实际上这个案子的结果没有说明.你用破碎的比较器给`.max`喂食,这样你就可以得到任何结果.没有具体说明`.max`将如何比较输入. (2认同)

Nam*_*man 11

您需要更换

.max(Integer::max)
Run Code Online (Sandbox Code Playgroud)

.max(Integer::compare)
Run Code Online (Sandbox Code Playgroud)

这里的问题是,抽象方法compare被声明为返回一个int值,也由签字纳Integer.max与方法一起Integer.compareInteger类,因此表示Integer::max推断为有效Comparator。尽管可以像这样实现compare方法:

当第一个参数小于,等于或大于第二个参数时,返回负整数,零或正整数。

In your current scenario, the code always ends up returning a positive value (given the input) and therefore the first element in comparison is considered to be greater always and thus returned accordingly.


Sto*_*ica 6

比较方法的合同(上参数first,second)为:

  • 如果first等于则返回0second
  • 如果返回负值 first < second
  • 如果返回正值 first > second

max仅具有正值的方法将始终返回正值.当根据比较器合同解释返回值时,正值表示first > second.因此,项目的顺序不会改变,它们似乎是"有序的".


Pau*_*ton 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是最大的.

  • @fge这很重要,因为`max`不符合`compare`的合同.想象一下,你尝试排序[a,b].如果你比较(a,b)并获得肯定答案,则意味着a> b所以你需要交换.如果你比较(b,a)并得到肯定答案,则意味着b> a所以你不需要交换.我可以向你保证我是对的. (3认同)