在Java中使用Lambda表达式查找Max

Kic*_*ski 13 java lambda max java-8

这是我的代码

    List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
    Integer maxInt = ints.stream()
                              .max(Comparator.comparing(i -> i))
                              .get();

    System.out.println("Maximum number in the set is " + maxInt);
Run Code Online (Sandbox Code Playgroud)

输出:

Maximum number in the set is 5
Run Code Online (Sandbox Code Playgroud)

我不能i在我的代码的下面两部分之间进行distingues

Comparator.comparing(i -> i)
Run Code Online (Sandbox Code Playgroud)

任何人都可以善待并解释两者之间的区别i吗?

Hol*_*ger 21

该方法Comparator.comparing(…)旨在创建一个Comparator使用基于对象属性进行比较的订单.当使用lambda表达式i -> i(这是一个简短的写法)(int i) -> { return i; }作为属性提供者函数时,结果Comparator将比较值本身.这工作时,要比较的对象有一个自然秩序Integer了.

所以

Stream.of(1,2,4,3,5).max(Comparator.comparing(i -> i))
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));
Run Code Online (Sandbox Code Playgroud)

做同样的事

Stream.of(1,2,4,3,5).max(Comparator.naturalOrder())
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));
Run Code Online (Sandbox Code Playgroud)

虽然后者更有效,因为它被实现为具有自然顺序(和实现Comparable)的所有类型的单例.

之所以max需要a Comparator,是因为你使用的泛型类Stream可能包含任意对象.

这允许,例如使用它streamOfPoints.max(Comparator.comparing(p->p.x))来找到具有最大值的点,xPoint其本身不具有自然顺序.或者做类似的事情streamOfPersons.sorted(Comparator.comparing(Person::getAge)).

使用专业版时,IntStream您可以直接使用自然顺序,这可能更有效:

IntStream.of(1,2,4,3,5).max()
.ifPresent(maxInt->System.out.println("Maximum number in the set is " + maxInt));
Run Code Online (Sandbox Code Playgroud)

为了说明"自然顺序"和基于属性的顺序之间的区别:

Stream.of("a","bb","aaa","z","b").max(Comparator.naturalOrder())
.ifPresent(max->System.out.println("Maximum string in the set is " + max));
Run Code Online (Sandbox Code Playgroud)

这将打印

集合中的最大字符串是z

因为Strings 的自然顺序是字典顺序,其中z大于的字典顺序b大于a

另一方面

Stream.of("a","bb","aaa","z","b").max(Comparator.comparing(s->s.length()))
.ifPresent(max->System.out.println("Maximum string in the set is " + max));
Run Code Online (Sandbox Code Playgroud)

将打印

集合中的最大字符串是aaa

作为aaa具有最大长度的所有的StringS中的信息流中.这是一个预期的用例,Comparator.comparing在使用方法引用时可以使其更具可读性,即Comparator.comparing(String::length)几乎可以说明自己...


Pet*_*rey 5

此函数(注意->用于闭包,不要与=>用于比较的哪个混淆)

i -> i
Run Code Online (Sandbox Code Playgroud)

只是意味着您需要按原样比较整个对象。即如果我有一个i你需要比较i

一个不太简单的例子可能是

max(Comparator.comparing(i -> -i))
Run Code Online (Sandbox Code Playgroud)

这会给你最低或

max(Comparator.comparing(i -> Math.abs(100-i))
Run Code Online (Sandbox Code Playgroud)

给你一个离 100 最远的值。

max(Comparator.comparing(i -> i.toString()))
Run Code Online (Sandbox Code Playgroud)

这会给你最大的比较作为一个字符串,即“9”>“10”作为一个字符串。

  • 回想一下 `i -&gt; i` 是 `(int i) -&gt; { return i; }`。通过查看较长的表格,应该清楚会发生什么...... (3认同)
  • @KickButtowski 你是说我链接到一些评论的关于 Lambdas 的 oracle 教程吗?;) 说这些话“`-&gt;` 不是比较”。我已经说过两次了。 (2认同)