Lambda&Stream:收集地图

Lov*_*ver 5 java lambda hashmap java-8 java-stream

我想使用Stream&Lambda夫妇构建一个Map.

我尝试了很多方法但是我被困了.这是使用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);
        }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我只知道如何在列表中收集,但我不能对地图做同样的事情.这就是为什么我必须再次流式传输我的列表以构建第二个列表,最后将所有列表放在一个地图中.我也尝试了'collect.groupingBy'语句,因为它也应该生成一张地图,但我失败了.

Fed*_*ner 6

您似乎想要将列表中的任何内容映射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
Run Code Online (Sandbox Code Playgroud)

如果您不想要特定实体的重复资助者,则可以收集到集合的地图:

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())));
Run Code Online (Sandbox Code Playgroud)

这用Collectors.groupingBy起来了Collectors.mapping.

  • @Lovegiver`Set`是一个不允许重复的集合.对于`Map <Object,Set <Object >> initMap = ...`,我不明白为什么编译器没有推断出正确的类型.`fr.getBuyerIdentification().getBuyer().getEntity()`返回一个类型为`Entity`的对象吗?并且`fr.getDocuments().get(0).getFunder()`返回一个类型为`Funder`的对象?如果两者都是,那么你应该没有任何问题. (2认同)