如何使用Java 8中的流查找整数的最大值?

120
我有一个 Integer 类型的列表 list,我想从 list.stream() 中获取最大值。最简单的方法是什么?我需要使用比较器吗?

1
阅读javadoc文档:http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#max-java.util.Comparator-,http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#naturalOrder-- - JB Nizet
20
你可能有使用Stream的理由,但不要忘记Collections.max - Alexis C.
10个回答

260

您可以将流转换为 IntStream

OptionalInt max = list.stream().mapToInt(Integer::intValue).max();

或者指定自然顺序比较器:

Optional<Integer> max = list.stream().max(Comparator.naturalOrder());

或者使用 reduce 操作:

Optional<Integer> max = list.stream().reduce(Integer::max);

或者使用收集器:

Optional<Integer> max = list.stream().collect(Collectors.maxBy(Comparator.naturalOrder()));

或使用IntSummaryStatistics:

int max = list.stream().collect(Collectors.summarizingInt(Integer::intValue)).getMax();

19
很有趣,想知道哪一个更高效。 - Roland
2
请问,Tagir,为什么? - elect
24
@elect,首先拆开所有整数,然后比较这些拆开的值。第二、三、四个解决方案在每次比较时都要进行拆箱操作,实际上会做两倍的拆箱操作。最后一个方案计算了更多的统计信息(如总和和最小值),在这里是不必要的,但肯定需要一些时间。 - Tagir Valeev
如果你只想得到一个 int,那么可以使用 mapToInt(...).max().getAsInt() 或者 reduce(...).get() 方法链。 - Andrejs
1
@Bogdan,这是可以解决的,尽管在问题中似乎没有要求。不过你可以发布自己的答案来涵盖这种情况。 - Tagir Valeev
显示剩余4条评论

13
int max = list.stream().reduce(Integer.MIN_VALUE, (a, b) -> Integer.max(a, b));

9
仅在所有值都为正数时才适用此方法。在reduce()中使用Integer.MIN_VALUE代替0。 - rolika
也可以是 int max = list.stream().reduce(Integer.MIN_VALUE, Integer::max); - Piotr Supel

4
另一种版本可能是:
int maxUsingCollectorsReduce = list.stream().collect(Collectors.reducing(Integer::max)).get();

3

我认为另一种简单的方法是

IntSummaryStatistics statistics = List.of(1, 2, 3).stream()
             .mapToInt(Integer::intValue)
             .summaryStatistics();
int max = statistics.getMax();

 

通过这个,你也可以getMin()和其他一些像平均数之类的东西。可以通过提供适当的参数从其他流创建一个SummaryStatistics对象。


3
int value = list.stream().max(Integer::compareTo).get();
System.out.println("value  :"+value );

4
还有其他回答提供了该提问者的问题,它们是多年前发布的。在回答问题时,请确保您添加一个新的解决方案或者一个明显更好的解释,特别是在回答较旧的问题时。 - help-info.de

3
您还可以使用以下代码片段:
int max = list.stream().max(Comparator.comparing(Integer::valueOf)).get();

另一种选择:

list.sort(Comparator.reverseOrder()); // max value will come first
int max = list.get(0);  

3

正确的代码:

int max = list.stream().reduce(Integer.MIN_VALUE, (a, b) -> Integer.max(a, b));

或者

int max = list.stream().reduce(Integer.MIN_VALUE, Integer::max);

0

使用流和归约

Optional<Integer> max = list.stream().reduce(Math::max);

看起来你发了两次相同的答案并删除了其中一个,但是我已经在另一个答案中评论过了,这个解决方案已经包含在 Tagir 的答案中了(用 Integer::max 但这是完全相同的)。 - Didier L

0

你也可以使用下面的代码在集合中找到最大元素:

List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
Optional<Integer> max = intList.stream().max((a, b) -> a - b);

-2

您可以使用 int max = Stream.of(1, 2, 3, 4, 5).reduce(0, (a, b) -> Math.max(a, b));,适用于正数和负数。


你应该从 Integer.MIN_VALUE 开始,以使其适用于负数。 - Didier L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接