[英]does stateful map operation of ordered stream process elements in deterministic way?
[英]Stateful filter for ordered stream
我有一個問題,我想知道是否有使用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 ...
我有可能這樣做嗎?
是的,這是可能的,但您需要一個有狀態謂詞來跟蹤進行比較的先前值。 這意味着它只能用於順序流:對於並行流,您將遇到競爭條件。
幸運的是,大多數流默認為順序,但如果您需要在來自未知源的流上執行此操作,您可能需要使用isParallel()
進行檢查並拋出異常,或使用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>
(或其他對象類型)的概念類似。
流不是為此類任務而設計的。 我會使用不同的方法來實現這一點,它不使用流。 但是,如果你真的必須使用流,那么解決方案必須避免由於流和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不允許修改變量(它可以修改數組的元素,但不能修改數組本身)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.