gpt4 book ai didi

java - 如何使用 Java 8 lambda 从流中获取一系列项目?

转载 作者:IT老高 更新时间:2023-10-28 20:27:02 26 4
gpt4 key购买 nike

在上一个问题 [ How to dynamically do filtering in Java 8? ] Stuart Marks 给出了一个精彩的答案,并提供了几个有用的实用程序来处理从流中选择 topN 和 topPercent。

我将从他的原始答案中将它们包括在此处:

@FunctionalInterface
public interface Criterion {
Stream<Widget> apply(Stream<Widget> s);
}

Criterion topN(Comparator<Widget> cmp, long n) {
return stream -> stream.sorted(cmp).limit(n);
}

Criterion topPercent(Comparator<Widget> cmp, double pct) {
return stream -> {
List<Widget> temp =
stream.sorted(cmp).collect(toList());
return temp.stream()
.limit((long)(temp.size() * pct));
};
}

我的问题是:

[1] 如何从具有一定数量项目的流中获取从 3 到 7 的顶级项目,因此如果流中有来自 A1、A2 .. A10 的项目,则调用

topNFromRange(Comparator<Widget> cmp, long from, long to) = topNFromRange(comparing(Widget::length), 3L, 7L)

将返回 { A3, A4, A5, A6, A7 }

我能想到的最简单的方法是从 original 中获取前 7 [ T7 ],从 original 中获取前 3 [ T3 ],然后得到 T7 - T3。

[2] 如何从具有一定数量项目的流中获取前 10% 到前 30% 的顶级项目,因此如果流具有来自 X1、X2 .. X100 的项目,则调用

topPercentFromRange(Comparator<Widget> cmp, double from, double to) = topNFromRange(comparing(Widget::length), 0.10, 0.30)

将返回 { X10, X11, X12, ..., X29, X30 }

我能想到的最简单的方法是从 original 中获取前 30% [ TP30 ],从 original 中获取前 10% [ TP10 ],然后得到 TP30 - TP10。

使用Java 8 Lambda简洁表达上述情况有哪些更好的方法?

最佳答案

Stream<T> 中获取范围, 你可以使用 skip(long n)首先跳过一组元素,然后你可以调用limit(long n)只取特定数量的元素。

考虑一个有 10 个元素的流,然后要获取第 3 到 7 个元素,您通常会从 List 调用:

list.subList(3, 7);

现在使用 Stream ,需要先跳过3项,然后取7 - 3 = 4项,这样就变成了:

stream.skip(3).limit(4);

作为@StuartMarks 对第二个答案的解决方案的一种变体,我将为您提供以下解决方案,它可以保持完整的链接,它的工作方式类似于@StuartMarks 的做法:

private <T> Collector<T, ?, Stream<T>> topPercentFromRangeCollector(Comparator<T> comparator, double from, double to) {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> list.stream()
.sorted(comparator)
.skip((long)(list.size() * from))
.limit((long)(list.size() * (to - from)))
);
}

IntStream.range(0, 100)
.boxed()
.collect(topPercentFromRangeCollector(Comparator.comparingInt(i -> i), 0.1d, 0.3d))
.forEach(System.out::println);

这将打印元素 10 到 29。

它通过使用 Collector<T, ?, Stream<T>> 来工作从流中获取元素,将它们转换为 List<T> , 然后得到一个 Stream<T> ,对其进行排序并对其应用(正确的)边界。

关于java - 如何使用 Java 8 lambda 从流中获取一系列项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22917270/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com