Gripa Lauro Neto:
¿Cómo hacer el grupo I una lista dentro de un objeto por dos de los atributos de los objetos?
Estoy usando Drools 7.9.0 y Java 8. Tengo una Result
clase que se utiliza como retorno a cada regla Drools emparejado.
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
@NoArgsConstructor
public class Result implements Serializable {
private Integer id;
private String name;
private List<Occurrences> occurrences = new ArrayList<>();
public void addOccurrence(Occurrences occurrence) {
this.occurrences.add(occurrence);
}
}
Después de la ejecución Drools, termino con una List<Result>
. Convertido a JSON se parece a esto.
RESULTADO ACTUAL:
[
{
name: "Whatever"
id: 0001,
occurrences: [{
(...)
}]
},
{
name: "Whatever"
id: 0001,
occurrences: [{
(...)
}]
},
{
name: "Whatever"
id: 0002,
occurrences: [{
(...)
}]
},
{
name: "Other thing"
id: 0002,
occurrences: [{
(...)
}]
}
]
Necesito grupo a mi lista de Result
s por lo que el ocurrences
se agrupan por id
y name
, de esta manera.
GASTOS ESPERADOS:
[
{
name: "Whatever"
id: 0001,
occurrences: [{
(...)
}, {
(...)
}]
},
{
name: "Whatever"
id: 0002,
occurrences: [{
(...)
}]
},
{
name: "Other thing"
id: 0002,
occurrences: [{
(...)
}]
}
]
¿Cuál sería la mejor forma de implementar esto? Tengo dos opciones:
- Cambio Drools rige por lo que mi
List<Result>
ya está estructurado el I necesidad manera. Tal vez crear una clase con unaddResult
método que comprueba la lista deid
ename
y añadir la aparición de la entrada derecha. Pero esto no es lo ideal, ya que aumentará la complejidad dentro de las reglas. - Post-procesar mi
List<Result>
por lo que los grupos de laoccurrences
deid
yname
. Pero no tengo ni idea de cómo hacer esto de forma optimizada y simple.
¿Cuál es la mejor manera de hacer la segunda opción?
Etienne Miret:
Yo añadiría el siguiente método a Result
:
Result addOccurrences (List<Occurrences> occurrences) {
this.occurrences.addAll (occurrences);
return this;
}
Y entonces se puede usar Streams:
List<Result> collect = results.stream ()
.collect (Collectors.groupingBy (Result::getId, Collectors.groupingBy (Result::getName, Collectors.toList ())))
.values ()
.stream ()
.map (Map::values)
.flatMap (Collection::stream)
.map (Collection::stream)
.map (resultStream -> resultStream.reduce ((r0, r1) -> r0.addOccurrences (r1.getOccurrences ())))
.filter (Optional::isPresent)
.map (Optional::get)
.collect (Collectors.toList ());