在 Java 8 中使用 IntStream.filter 时如何跳过特定的数组索引
How to skip particular array index when using IntStream.filter in 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);
这对我来说工作正常。
但是我如何修改 filter
以跳过从 numbers
检查的某些数组索引?
例如,
如果我想跳过 numbers[1]
的检查,如果它是均匀的,那么我应该怎么做?
因为过滤器中的 i
是数组元素的值而不是它们的索引。
可以这样做吗?
改为创建数组索引流,并在映射到数组元素之前对其进行过滤:
int[] numbers = ...;
IntStream.range(0, numbers.length).filter(i -> i!=1)
.map(i -> numbers[i]).forEach(System.out::println);
如果您需要先按索引过滤掉一些元素,然后再按值过滤掉一些元素,您可以在映射之前和之后各有一个过滤器。
如果您需要在同一个过滤器中同时检查索引和值,那么我认为最好的方法是创建一个 class 来保存这两个值:
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 ;}
}
然后你可以做
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);
@James_D 答案的变体。
想象一下,如果我们可以避免使用 IndexedValue 等情境 类,因为我们是傻逼什么的。
好吧,不再想象了:
int[] numbers = ... ;
IntStream.range(0, numbers.length)
// an anonymous class is defined at this juncture
// for the sake of discussion, said class is named
// Whatever (FF8 reference).
.mapToObj(i -> new Object() {
final int index = i;
final int value = numbers[i];
})
// IntStream translated to Stream<Whatever>
.filter(v -> v.index != 1)
// Stream<Whatever> with non-1 indices
.filter(v -> v.value % 2 == 0)
// Stream<Whatever> with even values
.mapToInt(v -> v.value)
// Stream<Whatever> to IntStream
.forEach(System.out::println)
;
免责声明:
我知道这一点是因为我曾经感到无聊并自己尝试过。
不保证此代码将适用于非 JavaC 编译器。
(显然,Eclipse 的类型推断不如 javac 的性感。随便。[FF8 参考])
作为替代解决方案,您可以使用迭代器实现相同的结果。
我是 Enumerables 的作者,它用 Stream 中熟悉的功能包装了可迭代集合。它提供了一个具有索引参数的过滤方法。
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
IntStream stream = IntStream.of(numbers);
Enumerable<Integer> enumerable = new Enumerable(() -> stream.iterator());
Enumerable<Integer> evens = enumerable.filter((x, i) -> x % 2 == 0 && i != 1);
return evens.toList().stream();
我正在学习 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);
这对我来说工作正常。
但是我如何修改 filter
以跳过从 numbers
检查的某些数组索引?
例如,
如果我想跳过 numbers[1]
的检查,如果它是均匀的,那么我应该怎么做?
因为过滤器中的 i
是数组元素的值而不是它们的索引。
可以这样做吗?
改为创建数组索引流,并在映射到数组元素之前对其进行过滤:
int[] numbers = ...;
IntStream.range(0, numbers.length).filter(i -> i!=1)
.map(i -> numbers[i]).forEach(System.out::println);
如果您需要先按索引过滤掉一些元素,然后再按值过滤掉一些元素,您可以在映射之前和之后各有一个过滤器。
如果您需要在同一个过滤器中同时检查索引和值,那么我认为最好的方法是创建一个 class 来保存这两个值:
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 ;}
}
然后你可以做
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);
@James_D 答案的变体。
想象一下,如果我们可以避免使用 IndexedValue 等情境 类,因为我们是傻逼什么的。
好吧,不再想象了:
int[] numbers = ... ;
IntStream.range(0, numbers.length)
// an anonymous class is defined at this juncture
// for the sake of discussion, said class is named
// Whatever (FF8 reference).
.mapToObj(i -> new Object() {
final int index = i;
final int value = numbers[i];
})
// IntStream translated to Stream<Whatever>
.filter(v -> v.index != 1)
// Stream<Whatever> with non-1 indices
.filter(v -> v.value % 2 == 0)
// Stream<Whatever> with even values
.mapToInt(v -> v.value)
// Stream<Whatever> to IntStream
.forEach(System.out::println)
;
免责声明: 我知道这一点是因为我曾经感到无聊并自己尝试过。 不保证此代码将适用于非 JavaC 编译器。 (显然,Eclipse 的类型推断不如 javac 的性感。随便。[FF8 参考])
作为替代解决方案,您可以使用迭代器实现相同的结果。
我是 Enumerables 的作者,它用 Stream 中熟悉的功能包装了可迭代集合。它提供了一个具有索引参数的过滤方法。
int[] numbers = {1,2,3,4,5,6,7,8,9,10};
IntStream stream = IntStream.of(numbers);
Enumerable<Integer> enumerable = new Enumerable(() -> stream.iterator());
Enumerable<Integer> evens = enumerable.filter((x, i) -> x % 2 == 0 && i != 1);
return evens.toList().stream();