简体   繁体   English

如何使用Java 8 Streams在一次迭代中平面映射2个不同的字段?

[英]How to flatMap 2 different fields in one iteration with Java 8 Streams?

If I have a List where each element contains 2 List fields, how can I merge all the contained lists in one iteration through the main list. 如果我有一个List ,其中每个元素包含2个List字段,如何通过主列表在一次迭代中合并所有包含的列表。

In other words, what's the best way to express the following imperative code in a functional form using streams? 换句话说,使用流以功能形式表达以下命令式代码的最佳方法是什么?

public class App {
    public static void main(String[] args) throws InterruptedException {
        List<Item> items = asList(new Item(singletonList("A"), singletonList("B")),
                new Item(singletonList("C"), singletonList("D"))
        );

        List<String> set1 = new ArrayList<>(), set2 = new ArrayList<>();
        for (Item item : items) {
            set1.addAll(item.set1);
            set2.addAll(item.set2);
        }
    }

    private static class Item {
        public final List<String> set1, set2;

        public Item(List<String> set1, List<String> set2) {
            this.set1 = set1;
            this.set2 = set2;
        }
    }
}

What you are trying to do is to collect the result of a Stream pipeline with 2 different collectors. 您要做的是收集具有2个不同收集器的Stream管道的结果。 Furthermore, each collector needs to flatmap the List<String> of the current Stream item. 此外,每个收集器都需要对当前Stream项的List<String>进行flatmap。

There are no built-in collectors for this task, but you can use the StreamEx library which provides such collectors: 此任务没有内置收集器,但您可以使用提供此类收集器的StreamEx库:

Item item = StreamEx.of(items)
                    .collect(MoreCollectors.pairing(
                       MoreCollectors.flatMapping(i -> i.set1.stream(), Collectors.toList()),
                       MoreCollectors.flatMapping(i -> i.set2.stream(), Collectors.toList()),
                       Item::new)
                    );

This code pairs two collectors that flatmaps each set into a List and stores the result into an Item . 此代码将两个收集器配对,将每个集平面映射到List ,并将结果存储到Item This Item will contain your set1 and set2 variables. Item将包含您的set1set2变量。

The collector flatMapping will be available in Java 9 ( see this mail ). 收集器flatMapping将在Java 9中提供( 请参阅此邮件 )。

Just use two separate, straightforward stream operations: 只需使用两个独立的直接流操作:

List<Item> items; 
List<String> set1=items.stream().map(i -> i.set1).flatMap(List::stream).collect(toList());
List<String> set2=items.stream().map(i -> i.set2).flatMap(List::stream).collect(toList());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM