如何将嵌套的FOR循环更改为Java8 Stream API?

时间:2016-09-02 12:03:42

标签: java java-8 java-stream

以下示例可能很简单,但我创建它以显示我需要使用不同的数据(而不是整数)来实现。此代码可运行等。

List<List<Integer>> master = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    List<Integer> inner = new ArrayList<Integer>();
    master.add(inner);
    for (int j = 0; j < 10; j++) {
        inner.add(i * 10 + j);
    }
}
System.out.println(master);
//lets make single collections from that but add 1000 to every element - this represents some intermediate operations to generate part of final result
List<Integer> finalAccumulated = new ArrayList<Integer>(); // this will represent our accumulated, final result
for (List<Integer> topLvl : master) {
    ArrayList<Integer> intermedialeAccumulated = new ArrayList<>(); //this step is important as it represents returning a collection of results for stream#map not single result
    for (Integer nested : topLvl) { // this represents stream#map (or maybe collector?)
        intermedialeAccumulated.add(nested + 1000);
    }
    finalAccumulated.addAll(intermedialeAccumulated); // this represent accumulation of collection of results, not just single result like stream#map do
}
System.out.println(finalAccumulated);

如何使用 finalAccumulated获得与Stream中相同的结果。单一我的意思是在调用链中可以有只有单个终止动作所以结果形式将是

finalAccumulated=master.stream()...intermediateCalls()...terminateCollectingCall();

运行代码here

的在线ID

3 个答案:

答案 0 :(得分:2)

只需使用平面地图:

List<Integer> finalAccumulated = master
  .stream()
  .flatMap((x) -> x.stream())
  .map((i) -> i + 1000)
  .collect(Collectors.toList());

答案 1 :(得分:-1)

以下是如何使用单个finalAccumulated生成相同的Stream

List<Integer> finalAccumulated = IntStream.range(1000, 1000 + 10 * 10).boxed().collect(Collectors.toList());

对于这样的操作,这将是一种过度设计和通用的方法

private static <T> List<T> flattenWith(List<List<T>> master, Function<T, T> transform) {
        return master.stream()
                     .flatMap(List::stream)
                     .map(transform)
                     .collect(Collectors.toList());
    }

用法

flattenWith(master, x -> x + 1000)

答案 2 :(得分:-1)

 private static void test() {
        List<List<Integer>> master = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            List<Integer> inner = new ArrayList<Integer>();
            master.add(inner);
            for (int j = 0; j < 10; j++) {
                inner.add(i * 10 + j);
            }
        }
        System.out.println(master);
//lets make single collections from that but add 1000 to every element - this represents some intermediate operations to generate part of final result
        List<Integer> finalAccumulated = new ArrayList<Integer>(); // this will represent our accumulated, final result
        for (List<Integer> topLvl : master) {
            ArrayList<Integer> intermedialeAccumulated = new ArrayList<>(); //this step is important as it represents returning a collection of results for stream#map not single result
            for (Integer nested : topLvl) { // this represents stream#map (or maybe collector?)
                intermedialeAccumulated.add(nested + 1000);
            }
            finalAccumulated.addAll(intermedialeAccumulated); // this represent accumulation of collection of results, not just single result like stream#map do
        }
        //map then using flatmap
        List<Integer> finalAccumulated2 = master.stream().map(topLvl -> {
            ArrayList<Integer> intermedialeAccumulated = new ArrayList<>();
            for (Integer nested : topLvl) { 
                intermedialeAccumulated.add(nested + 1000);
            }
            return intermedialeAccumulated;
        }).flatMap(intermedialeAccumulated -> intermedialeAccumulated.stream())
                .collect(Collectors.toList());
    }