通过谓词限制流 [英] Limit a stream by a predicate

查看:87
本文介绍了通过谓词限制流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在限制(可能是无限的) Stream 的Java 8流操作,直到第一个元素与谓词不匹配为止?

Is there a Java 8 stream operation that limits a (potentially infinite) Stream until the first element fails to match a predicate?

在Java 9中,我们可以使用 takeWhile ,如下例所示,打印所有小于10的数字。

In Java 9 we can use takeWhile as in the example below to print all the numbers less than 10.

IntStream
    .iterate(1, n -> n + 1)
    .takeWhile(n -> n < 10)
    .forEach(System.out::println);

由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么?

As there is no such operation in Java 8, what's the best way of implementing it in a general way?

推荐答案

这样的操作应该可能与Java 8 ,但它不一定能有效地完成 - 例如,你不一定能并行化这样的操作,因为你必须按顺序查看元素。

Such an operation ought to be possible with a Java 8 Stream, but it can't necessarily be done efficiently -- for example, you can't necessarily parallelize such an operation, as you have to look at elements in order.

API没有提供一种简单的方法,但最简单的方法是采用 Stream.iterator(),包装 Iterator 有一个take-while实现,然后回到 Spliterator 然后再回到。或者 - 也许 - 包装 Spliterator ,虽然在这个实现中它不能再被拆分了。

The API doesn't provide an easy way to do it, but what's probably the simplest way is to take Stream.iterator(), wrap the Iterator to have a "take-while" implementation, and then go back to a Spliterator and then a Stream. Or -- maybe -- wrap the Spliterator, though it can't really be split anymore in this implementation.

这是在 Spliterator takeWhile 的未经测试的实现:

Here's an untested implementation of takeWhile on a Spliterator:

static <T> Spliterator<T> takeWhile(
    Spliterator<T> splitr, Predicate<? super T> predicate) {
  return new Spliterators.AbstractSpliterator<T>(splitr.estimateSize(), 0) {
    boolean stillGoing = true;
    @Override public boolean tryAdvance(Consumer<? super T> consumer) {
      if (stillGoing) {
        boolean hadNext = splitr.tryAdvance(elem -> {
          if (predicate.test(elem)) {
            consumer.accept(elem);
          } else {
            stillGoing = false;
          }
        });
        return hadNext && stillGoing;
      }
      return false;
    }
  };
}

static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> predicate) {
   return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
}

这篇关于通过谓词限制流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆