Java 8 从对象创建流';s法

Java 8 从对象创建流';s法,java-8,java-stream,Java 8,Java Stream,使用和对象的方法初始化流的最佳方法是什么 Foo foo1 = new Foo(); Foo foo2 = foo1.getNext(); Foo foo3 = foo2.getNext(); 我想要一个食物流,食物1,食物2,。。。通过getNext()方法 我试过了 Stream.iterate Stream.generate 但是这些方法返回无限的流。首先想到的可能是使用限制截断流: Stream.iterate(foo1, Foo::getNext) .limit(siz

使用和对象的方法初始化流的最佳方法是什么

Foo foo1 = new Foo();
Foo foo2 = foo1.getNext();
Foo foo3 = foo2.getNext();
我想要一个食物流,食物1,食物2,。。。通过getNext()方法

我试过了

Stream.iterate
Stream.generate

但是这些方法返回无限的流。

首先想到的可能是使用
限制截断流:

Stream.iterate(foo1, Foo::getNext)
      .limit(size)....
但显然,如果大小未知,这是没有用的

如果大小未知,那么肯定会有某种类型的条件来表示“停止,不再”

或:


如果你不能使用JDK-9,那么你唯一的选择就是创建你自己的helper方法来执行你所追求的逻辑。

问题中没有指定它,但是我相信当
getNext()
返回
null
时,你应该停止迭代(这似乎最有意义)

如果是,至少有三种方法:

  • 如果在JDK 9+上,请执行建议的操作:

    Stream.iterate(foo1, Objects::nonNull, Foo::getNext)
    
  • 如果在JDK 8上,并且您不介意引入额外的依赖项,请使用及其方法:

  • 如果在JDK 8上,您不想引入额外的依赖项,请使用自定义的
    拆分器编写一个方法,例如(请注意,这不是最有效的实现,因为它急切地调用
    生成器
    ):


  • .limit(….)大小未知,并且无法急切地检索所有的foo,因为这是一种非常耗费资源的方法。您可以使用
    Stream.of()
    如何知道何时停止?请注意,流并不急切,它们只会在被消耗时生成元素。您可能对以下内容感兴趣:
    Stream.iterate(foo1,Foo::getNext)
    没有任何问题。你没有告诉我在什么情况下应该停止。
    Stream.iterate(foo1, f -> someCondition, Foo::getNext)
          .... // further intermediate or a terminal operation
    
    Stream.iterate(foo1, Objects::nonNull, Foo::getNext)
    
    Seq.iterateWhilePresent(foo1, foo -> Optional.ofNullable(foo.getNext))
    
    public static <T> Stream<T> iterateUntilNull(T seed, UnaryOperator<T> generator) {
        Spliterator<T> spliterator = new Spliterator<T>() {
            private T next = seed;
    
            @Override
            public boolean tryAdvance(Consumer<? super T> action) {
                if (next == null) {
                    return false;
                }
                action.accept(next);
                next = generator.apply(next);
                return true;
            }
    
            @Override
            public Spliterator<T> trySplit() {
                return null;
            }
    
            @Override
            public long estimateSize() {
                return Long.MAX_VALUE;
            }
    
            @Override
            public int characteristics() {
                return Spliterator.NONNULL;
            }
        };
        return StreamSupport.stream(spliterator, false);
    }
    
    iterateUntilNull(foo1, Foo::getNext)