有序流的状态过滤器

我有一个问题,我想知道是否有使用 Streams 的解决方案。


想象一下,你有一个有序的对象流;让我们假设一个整数流。


 Stream<Integer> stream = Stream.of(2,20,18,17,4,11,13,6,3,19,4,10,13....)

现在我想过滤所有值与该值之前的前一个数字的差大于n 的值。


stream.filter(magicalVoodoo(5))

// 2, 20, 4, 11, 3, 19, 4, 10 ...

我有没有可能做到这一点?


长风秋雁
浏览 125回答 2
2回答

蛊毒传说

是的,这是可能的,但是您需要一个有状态的谓词来跟踪先前的值以进行比较。这确实意味着它只能用于顺序流:对于并行流,您会遇到竞争条件。幸运的是,大多数流默认为顺序流,但如果您需要对来自未知来源的流执行此操作,您可能需要检查 usingisParallel()并抛出异常,或使用 将其转换为顺序流sequential()。一个例子:public class DistanceFilter implements IntPredicate {&nbsp; &nbsp; private final int distance;&nbsp; &nbsp; private int previousValue;&nbsp; &nbsp; public DistanceFilter(int distance) {&nbsp; &nbsp; &nbsp; &nbsp; this(distance, 0);&nbsp; &nbsp; }&nbsp; &nbsp; public DistanceFilter(int distance, int startValue) {&nbsp; &nbsp; &nbsp; &nbsp; this.distance = distance;&nbsp; &nbsp; &nbsp; &nbsp; this.previousValue = startValue;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean test(int value) {&nbsp; &nbsp; &nbsp; &nbsp; if (Math.abs(previousValue - value) > distance) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; previousValue = value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }&nbsp; &nbsp; // Just for simple demonstration&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; int[] ints = IntStream.of(2, 20, 18, 17, 4, 11, 13, 6, 3, 19, 4, 10, 13)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .filter(new DistanceFilter(5))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .toArray();&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(Arrays.toString(ints));&nbsp; &nbsp; }}我IntStream在这里使用,因为它是一个更好的类型,但概念与Stream<Integer>(或其他对象类型)相似。

人到中年有点甜

流不是为这种任务而设计的。我会使用不同的方式来实现这一点,它不使用流。但是,如果您真的必须使用流,由于流和 lambda 的设计,该解决方案必须规避某些限制,因此看起来很hacky:int[] previous = new int[1];previous[0] = firstElement;... = stream.filter(n -> {&nbsp; &nbsp; &nbsp; &nbsp; boolean isAllowed = (abs(n - previous[0]) > 5);&nbsp; &nbsp; &nbsp; &nbsp; if (isAllowed)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; previous[0] = n;&nbsp; &nbsp; &nbsp; &nbsp; return isAllowed;})请注意,该变量previous是一个单元素数组。这是一个 hack,因为 lambda 不允许修改变量(它可以修改数组的元素,但不能修改数组本身)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java