Tengo un mapa de listas de un objeto en particular y quiero agregar todos los elementos de las listas en función de una variable de instancia particular.
Mi Objeto:
class Risk{
Integer id, riskValue, totRisk=0;
String name;
Integer getId(){
return id;
}
Risk(Object[] result){
id=(Integer)result[0];
riskValue=(Integer)result[1];
name=(String)result[3];
}
}
Obtengo de la base de datos una lista de matrices de tipo objeto:
List< Object[] > results=getResults();
Utilizo Java 8 para agrupar mis datos por ID, porque quiero SUMAR por riskValue
todos los objetos de tipo que Risk
tienen el mismo id
.
Esto es lo que hago:
List<Risk> risks=results.stream().map(Risk::new).collect(Collectors.toList());
Map<Integer, List<Risk>> byId=risks.stream.collect(Collectors.groupingBy(Risk::getId));
En este punto, tengo todos mis objetos de riesgo agrupados por ID. Y quiero que cada lista sume todos los objetos riskValue
y tenga el total en la variabletotRisk
¿Cómo calcular en la variable totRisk
el total de las variables riskValue
en cada Lista?
Note1: Quiero hacerlo usando Java 8, sé cómo hacerlo usando Java 7 y más abajo.
Nota 2: Quizás también sea posible hacerlo de una vez, al no tener que agrupar primero por ID. Lo que quiero lograr es sumar todos los objetos con el mismo ID en el original List<Object[]> results
. Si se puede hacer con una sola declaración, es aún mejor.
Debe tener en cuenta que puede combinar Collector
s. VerCollectors.groupingBy(Function,Collector)
Map<Integer, Integer> byId=risks.stream.collect(
Collectors.groupingBy(Risk::getId, Collectors.summingInt(Risk::getRiskValue)));
También puedes combinarlo con la primera operación:
Map<Integer, Integer> byId=results.stream().map(Risk::new).collect(
Collectors.groupingBy(Risk::getId, Collectors.summingInt(Risk::getRiskValue)));
Tenga en cuenta que supongo que tiene un método getRiskValue()
en su clase Risk
; de lo contrario, debe reemplazarlo Risk::getRiskValue
con una expresión lambda r -> r.riskValue
para acceder al campo; sin embargo, siempre se recomienda tener métodos getter.
El resultado se asigna de id a total.
Después de leer su pregunta nuevamente, noté que realmente desea resumir riskValue
y almacenar dentro totRisk
de cadaRisk
instancia (?) . Esto es un poco más complicado ya que no se ajusta al patrón de uso común:
Map<Integer, List<Risk>> byId=results.stream().map(Risk::new).collect(
Collectors.groupingBy(Risk::getId, Collectors.collectingAndThen(
Collectors.toList(), l-> {
int total=l.stream().collect(Collectors.summingInt(r -> r.riskValue));
l.forEach(r->r.totRisk=total);
return l;
})));
en este punto realmente deberíamos cambiar a usar import static java.util.stream.Collectors.*;
:
Map<Integer, List<Risk>> byId=results.stream().map(Risk::new).collect(
groupingBy(Risk::getId, collectingAndThen(toList(), l-> {
int total=l.stream().collect(summingInt(r -> r.riskValue));
l.forEach(r->r.totRisk=total);
return l;
})));
Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.
En caso de infracción, por favor [email protected] Eliminar
Déjame decir algunas palabras