Java 惰性字符串流,包括列表<String>

Java Lazy Stream of Strings including List<String>

我懒惰地为前两个简单项目创建一个字符串流。但是,我的流的一部分是字符串列表。

Stream<String> streamA = Stream.concat(
      Stream.generate(item::getStringA),
      Stream.generate(item::getStringB))

return Stream.concat(streamA, item.getStringList(param).stream())

以上方法有效,但 .getStringList 也需要延迟调用。我不清楚如何获取它并"merge"它与流的其余部分一起。

我认为这一切都不像您认为的那样。 Stream.generate always 生成一个 infinite 流。但最接近你想要的是

StreamSupport.stream(() -> item.getStringList(param).spliterator(), 0, false)

...这将懒惰地调用 item.getStringList(param)。 (您想要的并不是 Stream 的预期用例,因此它没有得到很好的支持。)

你可以做的是 return 来自你的 item.getStringList()

Stream
public static void main(String[] args) throws InterruptedException {
    Item item = new Item();
    Stream<String> a = Stream.concat(Stream.of("A"), Stream.of("B"));

    Stream<String> anotherStream = Stream.concat(a, item.getStringList());


    anotherStream.forEach(System.out::println);
}

private static class Item {

    public Stream<String> getStringList() {
        List<String> l = new ArrayList<>();

        l.add("C");
        l.add("D");
        l.add("E");
        l.add("F");
        final AtomicInteger i = new AtomicInteger(0);
        return Stream.iterate(l.get(i.get()), (f) -> {
            // Proof of laziness
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return l.get(i.getAndIncrement());
        })
        // Iterate is by default unbound
        .limit(l.size());
    }
}

我不确定这种方法会有多大帮助,因为您的列表仍在内存中。

我想,你真正想做的是

return Stream.<Supplier<Stream<String>>>of(
    () -> Stream.of(item.getStringA()),
    () -> Stream.of(item.getStringB()),
    () -> item.getStringList(param).stream())
    .flatMap(Supplier::get);

这会产生一个完全惰性的 Stream<String>,例如.limit(0).count() 不会调用 item 上的任何方法,或者 .findFirst() 只会调用 getStringA(),等等

流的内容将等同于

Stream.concat(
    Stream.of(item.getStringA(), item.getStringB()), item.getStringList(param).stream())