Java流合并和输出

Java流合并和输出,java,java-stream,guava,Java,Java Stream,Guava,我有一个表格中的对象列表: public class Child { private Mom mom; private Dad dad; private String name; private int age; private boolean isAdopted; } 我需要将这个列表转换成一个不同数据结构的列表,将具有相同父母密钥的对象聚合到表单中 public class Family { private Mom mom; pri

我有一个表格中的对象列表:

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

我需要将这个列表转换成一个不同数据结构的列表,将具有相同父母密钥的对象聚合到表单中

public class Family
{
    private Mom mom;
    private Dad dad;
    private Map<String, int> kids;
}

公共类族
{
私人妈妈;
私人爸爸;
私人地图儿童;
}
其中“儿童”地图是所有儿童姓名到年龄的地图

目前,我的翻译工作如下:

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() );
}
公共集合转换(最终集合子级)
{
返回children.stream()
.filter(child->!child.getIsAdopted())
.collect(不可变的.toimmutable(child->child.getMom(),
child->child.getDad(),
child->newhashmap(child.getName(),child.getAge()),
(c1,c2)->{
c1.getKids().putAll(c2.getKids());
返回c1;
} ) )
.cellSet()
.stream()
.map(Table.Cell::getValue)
.collect(Collectors.toList());
}

在转换到最终列表之前,是否有一种方法可以让我这样做而不必收集到中间表?

您可以这样做:

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());
}
公共静态集合转换(最终集合子级){
映射族=新的HashMap();
用于(儿童:儿童){
如果(!child.isAdopted()){
families.computeIfAbsent(child.getMom(),k->newHashMap())
.ComputeFabSent(child.getDad(),k->new Family(child.getMom(),child.getDad(),new HashMap())
.getKids().put(child.getName(),child.getAge());
}
}
返回families.values().stream().flatMap(m->m.values().stream()).collect(collector.toList());
}

如果可以使用
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())));
}
@Getter
@AllArgsConstructor
类分组键{
妈妈妈妈;
爸爸爸爸;
}
公共列表转换器(最终集合子项){
返回children.stream()
收集,收集收集,然后收集(
Collectors.groupingBy(c->newgroupingkey(c.getMom(),c.getDad()),
map->map.entrySet().stream()
.map(e->新族(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())));
}
公共列表转换(最终集合子项){
返回children.stream()
收集,收集收集,然后收集(
Collectors.groupingBy(c->Arrays.asList(c.getMom(),c.getDad()),
map->map.entrySet().stream()
.map(e->newfamily(((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());
}