英文:
Java 8 grouping by, counting and transforming to custom object
问题
我有这段代码:
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()));
基本上会产生这样的结果:
[16292, 141, 6, 100] = 2
[16288, 250, 59, 500] = 14
[16286, 250, 91, 50] = 4
[16287, 250, 91, 60] = 29
[16286, 250, 91, 80] = 10
[16293, 141, 6, 100] = 3
[16282, 079, 116, 50] = 9
...
我需要将这些结果放入这个自定义类中,就是这个:
@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;
}
有没有办法在不手动遍历整个列表的情况下完成这个操作?
英文:
I have this code:
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()));
Which basically produces this:
[16292, 141, 6, 100] = 2
[16288, 250, 59, 500] = 14
[16286, 250, 91, 50] = 4
[16287, 250, 91, 60] = 29
[16286, 250, 91, 80] = 10
[16293, 141, 6, 100] = 3
[16282, 079, 116, 50] = 9
...
I need to to put this results into a custom class, this one:
@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;
}
There's a way to do this without go through all the list and doing it manually?
答案1
得分: 1
不确定这是否符合您的要求。但您可以直接获取一个 Map<CustomReport, Long>
,而不是首先创建一个 Map<List<Object>, Long>
,然后遍历该映射将这些对象转换为目标类。
前提是 CustomReport
应实现 equals()
[1] 和 hashCode()
[2] 方法。
然后您可以这样做:
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;
}
英文:
Not sure if this is what you want. But you can get a Map<CustomReport, Long>
directly instead of first creating a Map<List<Object>, Long>
and then going through it to convert those objects to your target class.
The prerequisite is that CustomReport
should have equals()
[1] and hashCode()
[2] implemented
Then you can do this:
root.getReports().stream().collect(
Collectors.groupingBy(i -> new CustomReport(i.X(), i.Y(), i.Z(), i.A()),
HashMap::new,
Collectors.counting()));
I am assuming CustomReport
has a compatible constructor too. If you have to initialize with setters, then you can replace the first argument of the classifier with :
i -> {
CustomReport c = new CustomReport();
c.setX(i.X());
...
return c;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论