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

huangapple go评论72阅读模式
英文:

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&lt;List&lt;Object&gt;, Long&gt; collector = root.getReports().stream().collect(
	Collectors.groupingBy(r -&gt; Arrays.asList(i.X(), i.Y(), i.Z(), i.A()), Collectors.counting()));

for(Entry&lt;Object, Long&gt; entry : collector.entrySet())
	System.out.println(String.format(&quot;%s = %s&quot;, 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&lt;CustomReport, Long&gt; directly instead of first creating a Map&lt;List&lt;Object&gt;, Long&gt; 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 -&gt; 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 -&gt; {
    CustomReport c = new CustomReport();
    c.setX(i.X());
    ...
    return c;
}

huangapple
  • 本文由 发表于 2020年9月5日 03:29:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63747041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定