【发布时间】:2016-05-11 19:25:18
【问题描述】:
最近在我的工作中,我不得不按顺序处理一堆 xml 文件。在这种情况下,我编写了一种树遍历,因此每个 xml 文件都变成了一个 Iterator
后来程序不关心哪个 SomeXmlElement 对象来自哪个文件,所以我想将所有 Iterator 连接成一个。
这大致是如何完成连接的(使用 String 而不是 SomeXmlElement):
Stream<String> s = Stream.empty();
for (int i = 0; i < 100000; i++) {
s = Stream.concat(s, Arrays.asList("1", "2", "3").stream());
}
s.findFirst().ifPresent(System.out::println);
事实证明,这从不打印任何东西,它只是挂了一段时间,最终你会得到堆错误或堆栈溢出。所以我又试了一次,这次用的是番石榴:
Iterable<String> s = Collections.emptyList();
for (int i = 0; i < 100000; i++) {
s = Iterables.concat(s, Arrays.asList("1", "2", "3"));
}
System.out.println(Iterables.getFirst(s, null));
有点令人惊讶的是,这也会引发 StackOverflow。最后,我不得不通过实现 Iterator 手动进行连接,最终按预期工作。
为什么当有足够的数据时,这些标准库的连接方法会失败?毕竟,Streams 和 Iterables 旨在处理无限的输入。除了实现迭代器的“硬方式”之外,还有其他简单的选择吗?
【问题讨论】:
-
请注意,documentation of
Stream.concat明确警告了这一点…… -
确实如此,尽管警告有点模糊。它也不会给你一个线索,而不是做什么。 Guava 根本没有警告。
标签: java guava java-stream