在 Java 中使用 Lambda 表达式求最大值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24378646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:52:10  来源:igfitidea点击:

Finding Max with Lambda Expression in Java

javalambdamaxjava-8

提问by Kick Buttowski

This is my code

这是我的代码

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

output:

输出:

Maximum number in the set is 5

I cannot make distingues between two iin below section of my code

我无法区分i以下代码部分中的两个

Comparator.comparing(i -> i)

can anyone be kind and explain the difference between two i?

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

采纳答案by Holger

The method Comparator.comparing(…)is intended to create a Comparatorwhich uses an order based on a property of the objects to compare. When using the lambda expression i -> i, which is a short writing for (int i) -> { return i; }here, as a property provider function, the resulting Comparatorwill compare the values itself. This works when the objects to compare have a natural orderas Integerhas.

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

So

所以

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

does the same as

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

though the latter is more efficient as it is implemented as singleton for all types which have a natural order (and implement Comparable).

尽管后者效率更高,因为它对于具有自然顺序(和实施Comparable)的所有类型都实现为单例。

The reason why maxrequires a Comparatorat all, is because you are using the generic class Streamwhich might contain arbitrary objects.

完全max需要 a的原因Comparator是因为您正在使用Stream可能包含任意对象的泛型类。

This allows, e.g. to use it like streamOfPoints.max(Comparator.comparing(p->p.x))to find the point with the largest xvalue while Pointitself does not have a natural order. Or do something like streamOfPersons.sorted(Comparator.comparing(Person::getAge)).

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

When using the specialized IntStreamyou can use the natural order directly which is likely to be more efficient:

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

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


To illustrate the difference between “natural order” and a property based order:

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

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

this will print

这将打印

Maximum string in the set is z

集合中的最大字符串是 z

as the natural order of Strings is the lexicographical order where zis greater than bwhich is greater than a

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

On the other hand

另一方面

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

will print

将打印

Maximum string in the set is aaa

集合中的最大字符串是 aaa

as aaahas the maximum lengthof all Strings in the stream. This is the intended use case for Comparator.comparingwhich can be made even more readable when using method references, i.e. Comparator.comparing(String::length)which almost speaks for itself…

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

回答by Peter Lawrey

This function (note ->is for closures and not to be confused with =>which is for comparison)

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

i -> i

just means you need to compare the entire object as it is. i.e. if I have an iyou need to compare i

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

A less trivial example might be

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

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

which will give you the minimum or

这会给你最低或

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

gives you a value which is farthest from 100.

给你一个离 100 最远的值。

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

which will give you the maximum comparing as a String i.e. "9" > "10" as a string.

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

回答by Smutje

Comparator.comparingexpects a function which maps the source object to the value which actually gets compared - in your case, as you don't want to pre-process the value to be compared, iis simply mapped to itself.

Comparator.comparing期望一个函数将源对象映射到实际比较的值 - 在你的情况下,因为你不想预处理要比较的值,i它只是映射到自身。