英文:
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
min
ormax
) at the same time. UseIntSummaryStatistics
for summary computations otherwise as already answered here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论