Да, это возможно, но для сравнения вам понадобится предикат с отслеживанием состояния, который отслеживает предыдущее значение.Это означает, что его можно использовать только для последовательных потоков: с параллельными потоками вы столкнетесь с условиями гонки.
К счастью, большинство потоков по умолчанию являются последовательными, но если вам нужно сделать это для потоков из неизвестного источника, вы можете проверить с помощью 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>
(или другие типы объектов).