首页 > 解决方案 > Java 8 Streams:分阶段映射

问题描述

是否可以在不创建中间集合的情况下分阶段对流进行映射?

我正在使用 Selenium 并映射WebElements 流。重要的是要分批进行以避免StaleReferenceException被抛出,因为页面会动态更新自身,并且某些map操作需要相对较长的时间才能完成。

问题(简化):

public class StreamTest {

    public static void main(String[] args) {
        String[] input = new String[] {"1", "2", "3", "4", "5"};
        List<String> list = map(input).collect(Collectors.toList());
    }

    private static Stream<String> map(String[] input) {
        return Arrays.stream(input).parallel()
                .map(s -> {
                    String ret = s + "0";
                    System.out.println(String.format("%10s%10s", s, ret));
                    return ret;
                })
                .map(s -> {
                    String ret = s + "0";
                    System.out.println(String.format("%10s%10s", s, ret));
                    return ret;
                })
                .map(s -> {
                    String ret = s + "0";
                    System.out.println(String.format("%10s%10s", s, ret));
                    return ret;
                });
    }
}

样本输出:

         3        30
         4        40
        30       300
         1        10
         5        50
        10       100
         2        20
        50       500
       300      3000
        40       400
       500      5000
        20       200
       100      1000
       400      4000
       200      2000

期望的输出:

         1        10
         2        20
         3        30
         4        40
         5        50
        10       100
        20       200
        30       300
        40       400
        50       500
       100      1000
       200      2000
       300      3000
       400      4000
       500      5000

当前解决方案:

private static Stream<String> map(String[] input) {
    return Arrays.stream(input)
            .map(s -> s + "0")
            .collect(Collectors.toList()).stream()              
            .map(s -> s + "0")
            .collect(Collectors.toList()).stream()
            .map(s -> s + "0");
}

有没有办法在每次调用之间创建一个虚拟集合来实现这一点map

注意:我需要使用带有n 个调用的流,map而不是n 个for 循环的序列。

标签: seleniumjava-8java-stream

解决方案


这似乎有效:

String[] input = new String[] {"1", "2", "3", "4", "5"};

Stream.of("", "0", "00")
      .flatMap(suffix -> Stream.of(input)
           .map(prefix -> prefix + suffix)
           .map(s -> String.format("%10s%10s", s, s + "0")))
      .forEach(System.out::println);

糟糕的排序是由于parallel()调用造成的,这可能是可以避免的。


推荐阅读