Java流合并和输出。

4

我有一个对象列表,格式如下:

public class Child
{
    private Mom mom;
    private Dad dad;
    private String name;
    private int age;
    private boolean isAdopted;
}


我需要将这个列表转换成另一种数据结构的列表,将具有相同Mom和Dad键的对象聚合到一起,形成如下所示的形式。
public class Family
{
    private Mom mom;
    private Dad dad;
    private Map<String, int> kids;
}

'kids' map是一个将所有孩子的名字映射到年龄的映射表。

public Collection<Family> transform( final Collection<Child> children )
{
    return children.stream()
                   .filter( child -> !child.getIsAdopted() )
                   .collect( ImmutableTable.toImmutableTable( child -> child.getMom(),
                                                              child -> child.getDad(),
                                                              child -> new HashMap<>(child.getName(), child.getAge() ),
                                                              (c1, c2) -> { 
                                                                  c1.getKids().putAll(c2.getKids());
                                                                  return c1;
                                                              } ) )
                   .cellSet()
                   .stream()
                   .map( Table.Cell::getValue)
                   .collect( Collectors.toList() );
}

有没有一种方法可以在转换为最终列表之前,无需收集到中间表中就完成这项任务?
2个回答

2
如果您能定义一个具有“mom”和“dad”属性的“GroupingKey”,则实现可以简化为以下内容:
@Getter
@AllArgsConstructor
class GroupingKey {
    Mom mom;
    Dad dad;
}

public List<Family> transformer( final Collection<Child> children ) {
    return children.stream()
            .collect(Collectors.collectingAndThen(
                    Collectors.groupingBy(c -> new GroupingKey(c.getMom(), c.getDad())),
                    map -> map.entrySet().stream()
                            .map(e -> new Family(e.getKey().getMom(), e.getKey().getDad(),
                                    e.getValue().stream().collect(Collectors.toMap(Child::getName, Child::getAge))))
                            .collect(Collectors.toList())));
}

如果不通过定义其他类,您可以使用与以下相同的方法转换对象:

public List<Family> transform( final Collection<Child> children ) {
    return children.stream()
            .collect(Collectors.collectingAndThen(
                    Collectors.groupingBy(c -> Arrays.asList(c.getMom(), c.getDad())),
                    map -> map.entrySet().stream()
                            .map(e -> new Family(((Mom) ((List) e.getKey()).get(0)), ((Dad) ((List) e.getKey()).get(1)),
                                    e.getValue().stream().collect(Collectors.toMap(Child::getName, Child::getAge))))
                            .collect(Collectors.toList())));
}

0
你可以像这样做:
public static Collection<Family> transform( final Collection<Child> children ) {
    Map<Mom, Map<Dad, Family>> families = new HashMap<>();
    for (Child child : children) {
        if (! child.isAdopted()) {
            families.computeIfAbsent(child.getMom(), k -> new HashMap<>())
                    .computeIfAbsent(child.getDad(), k -> new Family(child.getMom(), child.getDad(), new HashMap<>()))
                    .getKids().put(child.getName(), child.getAge());
        }
    }
    return families.values().stream().flatMap(m -> m.values().stream()).collect(Collectors.toList());
}

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