Java 8按分组、计数和转换为自定义对象

Java 8按分组、计数和转换为自定义对象,java,collections,java-8,java-stream,Java,Collections,Java 8,Java Stream,我有以下代码: Map<List<Object>, Long> collector = root.getReports().stream().collect( Collectors.groupingBy(r -> Arrays.asList(i.X(), i.Y(), i.Z(), i.A()), Collectors.counting())); for(Entry<Object, Long> entry : collector.entrySe

我有以下代码:

Map<List<Object>, Long> collector = root.getReports().stream().collect(
    Collectors.groupingBy(r -> Arrays.asList(i.X(), i.Y(), i.Z(), i.A()), Collectors.counting()));

for(Entry<Object, Long> entry : collector.entrySet())
    System.out.println(String.format("%s = %s", entry.getKey(), entry.getValue()));
我需要将这个结果放入一个自定义类,这个类:

@EqualsAndHashCode @ToString
public class CustomReport implements Serializable {
    private static final long serialVersionUID = 2074900904056768029L;

    @Getter @Setter
    private Integer x, y, z;
    
    @Getter @Setter
    private String a;

    @Getter @Setter
    private Long result;
}

有一种方法可以做到这一点,而无需查看所有列表并手动执行?

不确定这是否是您想要的。但是您可以直接获得一个
映射
,而不是首先创建一个
映射
,然后通过它将这些对象转换为目标类

先决条件是
CustomReport
应该实现
equals()
[]和
hashCode()
[]

然后你可以这样做:

root.getReports().stream().collect(
    Collectors.groupingBy(i -> new CustomReport(i.X(), i.Y(), i.Z(), i.A()), 
        HashMap::new,
        Collectors.counting()));
我假设
CustomReport
也有一个兼容的构造函数。如果必须使用setter进行初始化,则可以将分类器的第一个参数替换为:

i -> {
    CustomReport c = new CustomReport();
    c.setX(i.X());
    ...
    return c;
}
你说的“手动”是什么意思?您必须编写将一个
条目
映射到
CustomReport
的代码。这取决于“浏览所有列表并手动执行”的含义。您需要以某种方式循环收集器返回的
入口集
,无论是在流中还是在for循环中,并且需要手动分配每个变量。
i -> {
    CustomReport c = new CustomReport();
    c.setX(i.X());
    ...
    return c;
}