英文:
How to get the min/max element of nested collections without redundant code using streams?
问题
例如:
给定一个 Set<Set<Integer>>,我已经尝试使用
int min = nestedSets.stream().map(s->s.stream().min(Comparator.naturalOrder()).get()).min(Comparator.naturalOrder()).get();
我的初始想法是使用 flatMap,然而它并没有返回所期望的结果。
英文:
For example:
Given a Set<Set<Integer>>, I have tried to use
int min = nestedSets.stream().map(s->s.stream().min(Comparator.naturalOrder()).get()).min(Comparator.naturalOrder()).get();
My initial idea was to use flatMap, however it doesn't returns the desired result.
答案1
得分: 2
你可以将元素收集到 IntSummaryStatistics 中,它是:
> 用于收集统计信息,如计数、最小值、最大值、总和和平均值的状态对象。
例如:
Set<Set<Integer>> set = ...;
IntSummaryStatistics stats =
set.stream() // Stream<Set<Integer>>
.flatMap(Set::stream) // Stream<Integer>
.mapToInt(Integer::intValue) // IntStream
.summaryStatistics(); // IntSummaryStatistics
int min = stats.getMin();
int max = stats.getMax();
如果没有记录任何值,#getMin() 返回 Integer.MAX_VALUE,#getMax() 返回 Integer.MIN_VALUE。
英文:
You can collect the elements into an IntSummaryStatistics, which is:
>A state object for collecting statistics such as count, min, max, sum, and average.
For example:
Set<Set<Integer>> set = ...;
IntSummaryStatistics stats =
set.stream() // Stream<Set<Integer>>
.flatMap(Set::stream) // Stream<Integer>
.mapToInt(Integer::intValue) // IntStream
.summaryStatistics(); // IntSummaryStatistics
int min = stats.getMin();
int max = stats.getMax();
If no values were recorded then #getMin() returns Integer.MAX_VALUE and #getMax() returns Integer.MIN_VALUE.
答案2
得分: 2
Sure, here's the translated code:
Set<Set<Integer>> nestedSets = ...;
IntSummaryStatistics stats = nestedSets.stream()
.flatMap(Set::stream)
.mapToInt(Integer::intValue)
.summaryStatistics();
stats.getMax();
stats.getMin();
英文:
Set<Set<Integer>> nestedSets = ...
IntSummaryStatistics stats = nestedSets.stream()
.flatMap(Set::stream)
.mapToInt(Integer::intValue)
.summaryStatistics();
stats.getMax();
stats.getMin();
答案3
得分: 1
返回类型应为OptionalInt,因为您不知道是否找到了最小值。您可以执行以下操作:
OptionalInt min = nestedSets.stream()
.flatMap(Set::stream)
.mapToInt(Integer::intValue)
.min();
或者,您可以在Stream::min中使用具有相同映射函数(Integer::intValue)的Comparator,这会导致装箱的Optional<Integer>:
Optional<Integer> min = nestedSets.stream()
.flatMap(Set::stream)
.min(Comparator.comparingInt(Integer::intValue));
这取决于您是否需要所有这些值,或者只需要min或max之一。
-
优点: 我认为这些解决方案易于阅读,没有冗余代码,是计算最小值/最大值/平均值等的最佳方法。
-
缺点: 您一次只能计算一个值(
min或max)。否则,如前面已经在此处回答的那样,用IntSummaryStatistics进行汇总计算。
英文:
The returned type should be OptionalInt since you don't know it the minimum value is found. You can do:
OptionalInt min = nestedSets.stream()
.flatMap(Set::stream)
.mapToInt(Integer::intValue)
.min();
Alternatively, you can use Comparator with the very same mapping function (Integer::intValue) inside Stream::min which results in boxed Optional<Integer> instead:
Optional<Integer> min = nestedSets.stream()
.flatMap(Set::stream)
.min(Comparator.comparingInt(Integer::intValue));
It depends if you need all these values or just either min or max.
-
Pros: I find these solutions easy to read, with no redundant code and the best way to compute min/max/avg or more.
-
Cons: You can compute only one value (either
minormax) at the same time. UseIntSummaryStatisticsfor summary computations otherwise as already answered here.
专注分享java语言的经验与见解,让所有开发者获益!

评论