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

这是我的代码

List 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); 

输出:

 Maximum number in the set is 5 

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

 Comparator.comparing(i -> i) 

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

方法Comparator.comparing(…)旨在创建一个Comparator ,它使用基于对象属性的顺序进行比较。 当使用lambda表达式i -> i ,这是(int i) -> { return 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)); 

做同样的事

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

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

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

这允许,例如像streamOfPoints.max(Comparator.comparing(p->px))一样使用它来查找具有最大x值的点,而Point本身没有自然顺序。 或者做一些像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)); 

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

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

这将打印

集合中的最大字符串是z

因为String s的自然顺序是字典顺序,其中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)); 

将打印

集合中的最大字符串是aaa

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

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

 i -> i 

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

一个不太重要的例子可能是

 max(Comparator.comparing(i -> -i)) 

这将给你最小或

 max(Comparator.comparing(i -> Math.abs(100-i)) 

给你一个距离100最远的值。

 max(Comparator.comparing(i -> i.toString())) 

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

Comparator.comparing需要一个将源对象映射到实际得到的值的函数 – 在您的情况下,因为您不想预处理要比较的值,所以i只是映射到自身。