首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Java 8中使用IntStream.filter时如何跳过特定的数组索引

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

Stack Overflow用户
提问于 2015-02-13 18:19:00
回答 3查看 5.1K关注 0票数 6

我正在学习和学习Java 8流API,

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

代码语言:javascript
运行
复制
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是数组元素的值,而不是它们的索引。

是否可以这样做呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-13 18:25:12

相反,在映射到数组元素之前,创建数组索引的流并对其进行筛选:

代码语言:javascript
运行
复制
int[] numbers = ...;
IntStream.range(0, numbers.length).filter(i -> i!=1)
    .map(i -> numbers[i]).forEach(System.out::println);

如果您需要首先按索引筛选出一些元素,然后按值筛选出一些元素,则可以在映射之前和之后分别进行一个筛选。

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

代码语言:javascript
运行
复制
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 ;}
}

然后你就可以

代码语言:javascript
运行
复制
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);
票数 10
EN

Stack Overflow用户

发布于 2015-02-13 18:42:53

@James_D的答案的变体。

想象一下,如果我们可以避免使用情景类(如IndexedValue ),因为我们是愚蠢的欺骗或其他什么的。

好吧,别再想了:

代码语言:javascript
运行
复制
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参考)

票数 3
EN

Stack Overflow用户

发布于 2015-02-14 22:25:53

作为另一种解决方案,您可以使用迭代器实现相同的结果。

我是可计数的作者,它用熟悉于Stream的功能包装可迭代集合。它提供具有索引参数的筛选方法。

代码语言:javascript
运行
复制
    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();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28506111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档