Java流是否等同于具有变量赋值的while

Jan*_*sky 7 java java-8 java-stream

是否存在与以下内容等效的流

List<Integer> ints;
while (!(ints = this.nextInts()).isEmpty()) {
// do work
}
Run Code Online (Sandbox Code Playgroud)

hol*_*ava 8

首先,感谢@OlivierGrégoire的评论.它改变了我对新知识的回答.

编写您自己Spliterator的未知大小nextInts,然后您可以使用StreamSupport#stream创建流nextInts.例如:

generateUntil(this::nextInts, List::isEmpty).forEach(list -> {
    //do works
});

import static java.util.stream.StreamSupport.stream;

<T> Stream<T> generateUntil(final Supplier<T> generator, Predicate<T> stop) {
    long unknownSize = Long.MAX_VALUE;

    return stream(new AbstractSpliterator<T>(unknownSize, Spliterator.ORDERED) {
        @Override
        public boolean tryAdvance(Consumer<? super T> action) {
            T value = generator.get();

            if (stop.test(value)) {
                return false;
            }

            action.accept(value);
            return true;
        }
    }, false);
}
Run Code Online (Sandbox Code Playgroud)

  • @ holi-java不是真的:你仍然给`Spliterator`作为中间用法.只需摆脱它并使用我提供的方法签名.这对最终用户来说真的是最简单的:"嘿,我生成一个流直到我得到一个空列表".在这里,您仍然强制最终用户检查其他方法,并且不直接提供流.另外,使用术语`generate`就像`Stream.generate`一样.它简化了您的方法的作用. (3认同)
  • 您可以做的是直接以单独的方法提供流.像`<T> Stream <T> generateUntilEmpty(Supplier <List <T >>)`.人们知道溪流,人们知道供应商.很少有人知道"Spliterator". (2认同)
  • 更好,更实用.最后得到我的+1.虽然对于命名,我仍然认为`generateUntil ...`更好,因为它类似于`Stream.generate`. (2认同)
  • 这是我的第一个想法,但它很容易搞砸,所以如果你走这条路,确保使用`generateUntil`,它做你现在做的,和`generateWhile`,它具有相反的条件.这样,用户仍然可以仅使用供应商和`List :: isEmpty`来表达他/她想要的任何东西(而不是必须写`list - >!list.isEmpty()`. (2认同)
  • @ holi-java:`NONNULL`从未被要求过; 它只是潜在优化的暗示(无论如何今天都不会发生),但实际上,既然你不能保证元素是非"空"的,你应该删除`NONNULL`特征. (2认同)