【问题标题】:Concatenating stream in it's own forEach loop在它自己的 forEach 循环中连接流
【发布时间】:2019-03-19 11:57:56
【问题描述】:

示例 1:

 public TailCall<TestClass> useOfStream(Stream<Test> streamL) {
        ArrayList<Test> testList2 = new ArrayList<>();
        Stream<Test> streamL2 = testList2.stream();

        streamL.forEach(test -> {
            for (int i = 1; i < 14; i++) {
                if (/*insert if statement*/) {
                    Test test2 = new Test();
                    Stream<Test> streamT = stream.of(test2);
                    **streamL2.concat(streamL2, streamT);**
                } else {
                    //do something with TestClass
                }
            }
        });
        if (streamL2.findAny().isPresent()) {
            return call(() -> useOfStream(streamL2));
        } else {
            return TailCalls.done(TestClass);
        }
    }

所以,对于streamL 中的某个元素,我最多可以组成13 个同类元素。这些新制作的元素(我已添加到streamL2)应该以与streamL 相同的方式进行迭代。是否有可能将这些新元素添加到streamL? 正在做:

    streamL.forEach(test -> {
        for (int i = 1; i < 14; i++) {
            if (/*insert if statement*/) {
                Test test2 = new Test();
                Stream<Test> streamT = stream.of(test2);
                **streamL.concat(streamL, streamT);**
            } else {
                //do something with TestClass
            }
        }
    });

如果甚至可以在它自己的 for-Each 循环中连接一个流,那么 forEach 循环是否也会通过那些新添加的元素?这将消除我对递归方法的需要。 另一个问题是,在流中创建的对象(例如,Test test2 = new Test(); 在 streamL 的 forEach 循环中)是否会被程序延迟处理?换句话说,这个对象会在内存堆中占据任何位置吗? (不过这个问题没那么重要,主要是我的第一个问题)

【问题讨论】:

  • 我不确定我是否真的明白你在问什么,但我建议你看看Stream.flatMap(...)
  • 第二个代码块可以做吗?这就是我要问的......如果是,这是否意味着 streamL 的初始 forEach 循环会持续到调用 forEach 循环时的原始 streamL 结束,或者它是否会持续到流的真正结束(也循环了新添加的元素)。
  • 我看不出“第二个”代码块和第一个代码块的中心部分有什么区别。正如我所说,我不确定我是否理解您的需求,但使用 flatMap() 应该可以帮助您到达那里(可能与 IntStream 结合使用)。
  • 我可以将现有的 streamL 或 streamL2 和新添加的元素 (test2) 放在同一个流中,使用 flatmap 而不是 concat,但我真的不知道这是否对我有任何帮助我的问题。
  • 在第一个块中,我在 streamL 的 forEach 之前创建一个 streamL2 并将所有新创建的元素添加到 streamL2,然后在 forEach 的末尾我检查 streamL2 是否为空,如果不是我将此流返回给 useOfStream 方法。在第二个块中,我没有制作任何 streamL2,而是尝试向我正在 forEach 循环的 streamL 添加新元素

标签: java foreach java-stream


【解决方案1】:

您可以将第一个 forEach 替换为 flatMap 并使用 Stream.builder() 创建一个包含附加元素和重用 t 元素的子流:

Stream.of("A1", "A2").flatMap(t -> {
    Stream.Builder<String> subStream = Stream.builder();
    subStream.add(t);
    for (int i = 1; i < 3; i++) {
        subStream.add("B" + i);
    }
    return subStream.build();
}).forEach(System.out::print);

打印

A1B1B2A2B1B2

【讨论】:

  • .flatMap(t -&gt; Stream.concat(Stream.of(t), IntStream.range(1, 3).mapToObj(i -&gt; "B"+i)))
  • 非常感谢,所以没有办法避免我的递归方法。如果我想遍历新元素并做同样的事情,我必须以新的平面映射流作为参数来调用我的方法。返回 subStream.build() 只有在 Stream.of("A1", "A2") 的所有元素都被 flatMap() 方法循环过时才被实例化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 2015-10-30
  • 1970-01-01
  • 2021-05-12
  • 2018-01-04
  • 2014-02-26
  • 2020-08-23
相关资源
最近更新 更多