在Java 8中使用IntStream.filter时如何跳过特定的数组索引

Joe*_*Joe 5 java java-8

我正在学习Java 8 Stream API的新手,

我想编写一个程序来查找整数数组中的偶数IntStream,所以我想出了这个解决方案,

int[] numbers = {1,2,3,4,5,6,7,8,9,10};

IntStream.of(numbers).filter(i -> i%2 == 0).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

这对我来说是正常的.

但是如何修改filter以跳过某些数组索引numbers

例如,

如果我想跳过numbers[1]检查,如果它是否均匀,那么我该怎么办?

因为i在过滤器中是数组元素的值而不是它们的索引.

有可能这样做吗?

Jam*_*s_D 8

改为创建数组索引流,并在映射到数组元素之前对其进行过滤:

int[] numbers = ...;
IntStream.range(0, numbers.length).filter(i -> i!=1)
    .map(i -> numbers[i]).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

如果您首先需要按索引过滤掉一些元素,而某些元素按值过滤,则可以在地图之前有一个过滤器,之后有一个过滤器.

如果你需要检查同一过滤器中的索引和值,那么我认为最好的方法是创建一个类来保存两个值:

class IndexedValue {
    private int index, value;
    IndexedValue(int index, int value) {
        this.index = index ;
        this.value = value ;
    }
    int getIndex() { return index ;}
    int getValue() { return value ;}
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以做到

int[] numbers = ... ;
IntStream.range(0, numbers.length).map(i -> new IndexedValue(i, numbers[i]))
    .filter(v -> v.getIndex() == 1 || v.getValue() % 2 == 0)
    .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,使用`filter`会使流大小不可预测,这可能会影响性能.并行处理大型数组时.因此,如果你想跳过像这种情况一样的位置元素,使用`IntStream.concat(IntStream.of(0),IntStream.range(2,numbers.length))`可能比`IntStream.range(0, numbers.length).filter(i - > i!= 1)`. (4认同)
  • 如果你可以独立编写过滤器,那么这是最好的方法(在地图之前的索引上有一个过滤器,在之后的值上有一个过滤器).如果您需要一次检查索引和值,那么我认为您必须映射到存储它们的数据结构.查看更新的答案. (2认同)