我想知道我是否可以做这样的事情。假设我有一个数字 1 - 20 的流。我想利用诸如 drop 3 之类的功能(我猜是 Java 术语中的限制或跳过?)并生成一个数字流:
1 - 20、4 - 20、7-20 等
然后可能将这些全部平面映射到一个流中。我尝试了使用 Stream.iterate 的各种组合,主要是从流生成流,但我不断收到 IllegalStateException,表示流已运行或关闭。
例如,人们可能期望这样的代码:
Stream.iterate(Stream.of(1,2,3,4,5), x -> x.skip(1).collect(Collectors.toList()).stream()).limit(5).flatMap(x -> x).forEach(x -> System.out.println(x));
生成:1,2,3,4,5,2,3,4,5,3,4,5,4,5,5
但事实并非如此,它会抛出异常。我在这里遗漏了一些明显的东西吗?我知道 takeWhile 操作,但我认为它要到 Java 9 才会出现。
编辑:我已经设法使用以下方法获得了一个丑陋的解决方案来实现我想要实现的目标:
List<Integer> list = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());
Stream.iterate(list, x -> x.stream().skip(3).collect(Collectors.toList())).limit(7).map(x -> x.stream().limit(3).collect(Collectors.toList())).flatMap(List::stream).forEach(System.out::println);
所以我有一个列表 1..20,然后最终得到列表流 1..20、4..20、7..20 等。如果我然后取出每个列表的前 3 个元素我最终得到 1..3、4..6、7..9 等。如果我对其进行平面映射,我将返回到 1..20。
我的问题是,A. 有没有办法让我不必对上面的 limit(7) 进行硬编码,这样当我处理完所有输入元素集时它会自动停止,B. 我不喜欢必须收集到列表中 - 我不能在最后收集之前纯粹使用流来完成此操作,甚至只是在平面 map 之后打印吗?
最佳答案
也许您正在寻找类似的东西
IntStream.rangeClosed(1, 20)
.flatMap(i -> IntStream.rangeClosed(i, 20))
...然后你就可以做任何你喜欢的事情;例如.forEach(System.out::println)
.
如果您想对每三个数字执行此操作,最好执行类似的操作
IntStream.rangeClosed(0, 20/3)
.map(i -> 3 * i + 1)
.flatMap(i -> IntStream.rangeClosed(i, 20))
关于java - 使用流的流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35048837/