[英]Java GroupBy multiple with Sum
I'm trying to make group by
like in mySQL, I have multiple columns (properties) and I must group by two fields ( socio
and idSolicitudEgreso
) and sum another one ( montoPago
).我试图让group by
就像在MySQL中,我有多个列(属性),我必须利用两个场组( socio
和idSolicitudEgreso
),总结另一个( montoPago
)。 I did:我做了:
Map<String, Map<String, Integer>> mymap = santa.stream()
.collect(Collectors.groupingBy(Santander::getPanSocio,
Collectors.groupingBy(Santander::getPanIdsolicitudegreso,
Collectors.summingInt(Santander::getPanMontopago))));
mymap.forEach((key, value) -> System.out.println(key + ":" + value));
My class object is:我的类对象是:
public class Santander {
private String panRutbeneficiario;
private String panNombrebeneficiario;
private String panEmailbeneficiario;
private String panMetodopago;
private String panCodigobancoabono;
private String panTipocuentaabono;
private String panNumcuentaabono;
private String panFechapago;
private String panCampobanco1;
private String panCampobanco2;
private int panMontopago;
private String panTipocuentacargodet;
private String panNumcuentacargodet;
private String panCodigosucursal;
private String panReferenciacliente;
private String panRetencionfactura;
private String panAbonovalesvistalinea;
private String panCantidaddocumentos;
private String panSocio;
private String panIdsolicitudegreso;
}
I getting this result with this code:我用这个代码得到这个结果:
BANCO DEL ESTADO:{35113=3026882} BANCO DEL ESTADO:{35113=3026882}
As you can see I get the group very well, ( socio
, id
and sum
as well), but I need to get all the objects or list of object.正如你所看到的,我很好地得到了组,( socio
, id
和sum
),但我需要获取所有对象或对象列表。 I just get 3 of 20 fields.我只得到 20 个字段中的 3 个。 What change I must do in my Java stream code to get the list of objects (grouped)?我必须在 Java 流代码中进行哪些更改才能获取对象列表(分组)? Please?请?
Thanks谢谢
PS: the output I expect is: PS:我期望的输出是:
{ panRutbeneficiario=146174558, panNombrebeneficiario=No Definido,
panEmailbeneficiario=, panMetodopago=CAT_CSH_TRANSFER, panCodigobancoabono=12,
panTipocuentaabono=Ahorro, panNumcuentaabono=8275301, panFechapago=2020-07-30,
panCampobanco1=, panCampobanco2=, panMontopago=111960,
panTipocuentacargodet=CAT_CSH_CCTE, panNumcuentacargodet=null,
panCodigosucursal=, panReferenciacliente=, panRetencionfactura=,
panAbonovalesvistalinea=null, panCantidaddocumentos=null,
panSocio=BANCO DEL ESTADO, panIdsolicitudegreso=35113
}
You may need to prepare an object to hold the grouping result for example:您可能需要准备一个对象来保存分组结果,例如:
public class Summary {
private final String panSocio;
private final String panSolicitude;
private final int total;
public Summary(String socio, String solicitude, int total) {
this.panSocio = socio;
this.panSolicitude = solicitude;
this.total = total;
}
public String getPanSocio() { return this.panSocio; }
public String getPanSolicitude() { return this.panSolicitude; }
public int getTotal() { return this.total; }
public String toString() {
return String.format("{ socio=\"%s\", solicitude=\"%s\", total=%d}%n",
panSocio, panSolicitude, total);
}
}
Then it is possible to iterate over the entries of mymap
, use flatMap
to transform the entries of the inner map into Stream<Summary>
therefore collecting into the list of Summary
objects (sorted if necessary):然后可以迭代mymap
的条目,使用flatMap
将内部映射的条目转换为Stream<Summary>
从而收集到Summary
对象列表中(如有必要,进行排序):
List<Summary> remap = mymap.entrySet()
.stream()
.flatMap(e -> e.getValue().entrySet() // e.getKey() -> panSocio
.stream() // ee.getKey() -> solicitude, ee.getValue() -> total
.map(ee -> new Summary(e.getKey(), ee.getKey(), ee.getValue()))
)
.sorted(Comparator.comparing(Summary::getPanSocio)
.thenComparing(Summary::getPanSolicitude))
.collect(Collectors.toList());
Update更新
Of course, it is possibe to reuse existing Santander
class to collect the results providing that Santander
has a constructor or builder allowing to populate at least the three relevant fields panSocio
, panSolicitude
, panMontopago
:当然,如果Santander
具有允许填充至少三个相关字段panSocio
、 panSolicitude
、 panMontopago
的构造函数或构建器,则可以重用现有的Santander
类来收集结果:
List<Santander> grouped = mymap.entrySet()
.stream()
.flatMap(e -> e.getValue().entrySet() // e.getKey() -> panSocio
.stream() // ee.getKey() -> solicitude, ee.getValue() -> total
.map(ee -> new Santander(e.getKey(), ee.getKey(), ee.getValue())) // the rest of the fields set to some default values
)
.collect(Collectors.toList());
However, the rest of Santander
fields will be undefined / default upon applying summarizingInt
collector by Santander::getMontopago
.但是,在Santander::getMontopago
应用summarizingInt
收集器后,其余的Santander
字段将是未定义/默认的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.