java 8 list grouping with value mapping function producing 列表

java 8 list grouping with value mapping function producing list

我有一个关注class

public class Person {

    public String name;

    public List<Brand> brands;

    //Getters
}

和一个List<Person> persons(可能同名)。我需要在 <String, List<Brand>> 的地图中分组,其中 Person 的 name 作为键,累积的列表 Brands 作为值。

像这样

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

产生了不希望的结果,我知道为什么。如果在分组过程中这些值可以以某种方式变平?有没有办法用 Streams api?

您需要合并 个品牌成为一个 List:

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

猜猜想要的结果是什么,你可以用 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())
);

您可以为 groupBy 的下游创建自定义收集器:

Collector.of(LinkedList::new, 
            (list, person) -> list.addAll(person.brands), 
            (lhs, rhs) -> { lhs.addAll(rhs); return rhs; })

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

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

MoreCollectors provided in open source library: StreamEx

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