Lambda和Stream:在Map中收集

6

我希望使用Stream和Lambda来构建地图。

我尝试了很多方法,但卡住了。这里是使用Stream/Lambda和经典循环两种方式的Java代码。

Map<Entity, List<Funder>> initMap = new HashMap<>();
List<Entity> entities = pprsToBeApproved.stream()
    .map(fr -> fr.getBuyerIdentification().getBuyer().getEntity())
    .distinct()
    .collect(Collectors.toList());

for(Entity entity : entities) {
    List<Funder> funders = pprsToBeApproved.stream()
        .filter(fr -> fr.getBuyerIdentification().getBuyer().getEntity().equals(entity))
        .map(fr -> fr.getDocuments().get(0).getFunder())
        .distinct()
        .collect(Collectors.toList());
    initMap.put(entity, funders);
        }

正如你所看到的,我只知道如何在列表中收集信息,但是我无法使用地图实现相同效果。因此,我必须再次流式传输我的列表以建立第二个列表,最终将所有内容放入一个映射中。 我也尝试了"collect.groupingBy"语句,因为它也应该生成一个映射,但是我失败了。


https://dev59.com/-1wZ5IYBdhLWcg3wPOJM#31693843 - dres
嗯,这个不错。看看这个链接:https://dev59.com/aGIj5IYBdhLWcg3wWT2c - GOXR3PLUS
你想在一个流中构建地图...我真的不太明白你的意思。第一步是使用 entities.forEach(entity-> ..... ); - GOXR3PLUS
1个回答

7

看起来你想将 pprsToBeApproved 列表中的任何内容映射到你的 Funder 实例上,并按买方 Entity 进行分组。

你可以按照以下方式进行操作:

Map<Entity, List<Funder>> initMap = pprsToBeApproved.stream()
    .collect(Collectors.groupingBy(
        fr -> fr.getBuyerIdentification().getBuyer().getEntity(), // group by this
        Collectors.mapping(
            fr -> fr.getDocuments().get(0).getFunder(), // mapping each element to this
            Collectors.toList())));                     // and putting them in a list

如果您不希望特定实体有重复的资助者,可以收集到一个映射集合中:
Map<Entity, Set<Funder>> initMap = pprsToBeApproved.stream()
    .collect(Collectors.groupingBy(
        fr -> fr.getBuyerIdentification().getBuyer().getEntity(),
        Collectors.mapping(
            fr -> fr.getDocuments().get(0).getFunder(),
            Collectors.toSet())));

这里使用了Collectors.groupingByCollectors.mapping来实现。

1
第一段代码运行正常,但是数据重复,这对我来说不好,因为我想分组条目。 第二段代码很好,并且给了我与我的糟糕代码相同的结果。还有一件事:在这2种情况下,我必须用 Object 替换我使用的真实对象(实体和出资人):Map<Object,Set<Object>> initMap = ...我不明白为什么。转换我的类不起作用。我还发现我不熟悉 Set 对象。 我真的从未使用过它,可能是因为我不知道它真正有用的地方。 - Lovegiver
1
我知道@Eugene,我只是在写我的答案。不用紧张^^ - Lovegiver
2
@Lovegiver Set 是一个不允许重复的集合。至于 Map<Object, Set<Object>> initMap = ...,我不明白为什么编译器没有推断出正确的类型。fr.getBuyerIdentification().getBuyer().getEntity() 返回的对象是 Entity 类型吗?fr.getDocuments().get(0).getFunder() 返回的对象是 Funder 类型吗?如果两者都是,则您不应该有任何问题。 - fps
你说得对,@Federico!!fr.getDocuments().get(0).getFunder() 返回一个资助者(Funder),但是 fr.getBuyerIdentification().getBuyer().getEntity() 只返回实体(Entity)的名称字符串。我不知道为什么这两个对象之间的绑定是这样的(一个字符串,而不是类本身)。 - Lovegiver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接