2 回答
TA贡献1895条经验 获得超3个赞
是的,这是可能的,但是您需要一个有状态的谓词来跟踪先前的值以进行比较。这确实意味着它只能用于顺序流:对于并行流,您会遇到竞争条件。
幸运的是,大多数流默认为顺序流,但如果您需要对来自未知来源的流执行此操作,您可能需要检查 usingisParallel()并抛出异常,或使用 将其转换为顺序流sequential()。
一个例子:
public class DistanceFilter implements IntPredicate {
private final int distance;
private int previousValue;
public DistanceFilter(int distance) {
this(distance, 0);
}
public DistanceFilter(int distance, int startValue) {
this.distance = distance;
this.previousValue = startValue;
}
@Override
public boolean test(int value) {
if (Math.abs(previousValue - value) > distance) {
previousValue = value;
return true;
}
return false;
}
// Just for simple demonstration
public static void main(String[] args) {
int[] ints = IntStream.of(2, 20, 18, 17, 4, 11, 13, 6, 3, 19, 4, 10, 13)
.filter(new DistanceFilter(5))
.toArray();
System.out.println(Arrays.toString(ints));
}
}
我IntStream在这里使用,因为它是一个更好的类型,但概念与Stream<Integer>(或其他对象类型)相似。
TA贡献1895条经验 获得超7个赞
流不是为这种任务而设计的。我会使用不同的方式来实现这一点,它不使用流。但是,如果您真的必须使用流,由于流和 lambda 的设计,该解决方案必须规避某些限制,因此看起来很hacky:
int[] previous = new int[1];
previous[0] = firstElement;
... = stream.filter(n -> {
boolean isAllowed = (abs(n - previous[0]) > 5);
if (isAllowed)
previous[0] = n;
return isAllowed;})
请注意,该变量previous是一个单元素数组。这是一个 hack,因为 lambda 不允许修改变量(它可以修改数组的元素,但不能修改数组本身)。
添加回答
举报