java 8列表分组与值映射函数生成列表

时间:2017-09-06 20:36:28

标签: java-8 grouping java-stream flatten

我有以下

public class Person {

    public String name;

    public List<Brand> brands;

    //Getters
}

List<Person> persons(可能具有相同的名称)。我需要将<String, List<Brand>>的地图与人name的地图分组为关键字,并将累计的Brands列为值。

像这样的东西

 Map<String, List<List<String>>> collect = list.stream().collect(
        groupingBy(Person::getName, mapping(Person::getBrands, toList()))
 );

会产生不良后果,我知道原因。如果在分组期间值可能会以某种方式变平?有没有办法在那里使用Streams api?

5 个答案:

答案 0 :(得分:2)

java 9将专门为此类任务添加flatMapping收集器:

list.stream().collect(
    groupingBy(
        Person::getName, 
        flatMapping(
            p -> p.getBrands().stream(), 
            toList()
        )
    )

答案 1 :(得分:1)

您需要将合并品牌合并为一个List

list.stream().collect(Collectors.toMap(
            Person::getName,
            Person::getBrands,
            (left, right) -> {
                left.addAll(right);
                return left;
            },
            HashMap::new));

答案 2 :(得分:1)

猜测结果是什么,只需toMap收集器即可实现:

Map<String, List<String>> collect = persons.stream().collect(
    toMap(
            Person::getName,
            Person::getBrands,
            (l1, l2) -> ImmutableList.<String /*Brand*/>builder().addAll(l1).addAll(l2).build())
);

答案 3 :(得分:1)

您可以为groupBy

的下游创建自定义收藏家
Collector.of(LinkedList::new, 
            (list, person) -> list.addAll(person.brands), 
            (lhs, rhs) -> { lhs.addAll(rhs); return rhs; })

答案 4 :(得分:0)

开源库中提供了MoreCollectorsStreamEx

list.stream().collect(
    groupingBy(Person::getName, MoreCollectors.flatMapping(p -> p.getBrands().stream()));