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())
我懒惰地为前两个简单项目创建一个字符串流。但是,我的流的一部分是字符串列表。
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())