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

2022-09-03 00:46:19

这是我的代码

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

输出:

Maximum number in the set is 5

我无法在代码的以下部分中的两个之间进行区分i

Comparator.comparing(i -> i)

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


答案 1

该方法旨在创建一个,它使用基于对象属性的顺序进行比较。当使用 lambda 表达式时,这是此处的简短编写,作为属性提供程序函数,结果将比较值本身。当要比较的对象具有自然顺序时,这有效。Comparator.comparing(…)Comparatori -> i(int i) -> { return i; }ComparatorInteger

所以

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

之所以需要 a,是因为您正在使用可能包含任意对象的泛型类。maxComparatorStream

例如,这允许使用它,例如找到具有最大值的点,而本身没有自然顺序。或者执行类似 .streamOfPoints.max(Comparator.comparing(p->p.x))xPointstreamOfPersons.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

因为 s 的自然顺序是词典顺序,其中 大于 哪个大于Stringzba

另一方面

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

作为流中所有 s 的最大长度。这是预期的用例,在使用方法引用时可以使其更具可读性,即 这几乎不言自明...aaaStringComparator.comparingComparator.comparing(String::length)


答案 2

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

i -> i

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

一个不那么微不足道的例子可能是

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

这将给你最低限度或

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

为您提供一个距离 100 最远的值。

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

这将为您提供字符串的最大比较,即“9”>“10”作为字符串。


推荐