Estoy luchando para reducir una lista:
Digamos que tengo una List<Item> listItems
con una Item
clase definida como:
public class Item {
private String effect;
private String value;
public String getEffect() {
return effect;
}
public void setEffect(String effect) {
this.effect = effect;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Ahora, en mi listItems
lista, tengo algunos elementos con el mismo effect
inmueble.
Quiero eliminar todo elemento de mi listItems
lista con la misma effect
propiedad, excepto el que tiene la mayor value
propiedad. ( value
Es el número representado como una String
).
Además, yo quiero seguir todo el elemento con una única effect
propiedad.
¿Cómo puedo lograr eso? Creo que voy a tener que hacer frente Comparator
.
Parece que desea agrupar los artículos de su lista effect
, usando max(value)
como una agregación. Esto se puede hacer de la siguiente manera:
Map<String, Item> byEffectHavingMaxValue = listItems.stream()
.collect(Collectors.toMap(
Item::getEffect, // group by effect
Function.identity(), // keep items as values
BinaryOperator.maxBy( // when effect exists, keep the item with max value
Comparator.comparingInt(i -> Integer.parseInt(i.getValue())))));
Collection<Item> result = byEffectHavingMaxValue.values();
La solución anterior elementos recopila de la corriente a una Map
. Para ello, se utiliza una sobrecarga de Collectors.toMap
que requiere de 3 argumentos:
- KeyMapper : una
Function
que transforma elementos de la corriente a las teclas - valueMapper : a
Function
que transforma elementos de la corriente a valores - mergeFunction : una
BinaryOperator
que se utiliza para resolver las colisiones entre los valores asociados con la misma clave
En este caso, la Item::getEffect
referencia del método se está utilizando como la KeyMapper función, que transforma una Item
instancia en la effect
. A continuación, Function.identity()
se utiliza como el valueMapper función, que no hace nada, es decir, se deja a cada Item
instancia sin tocar. Finalmente, BinaryOperator.maxBy(Comparator.comparingInt(i -> Integer.parseInt(i.getValue())))
se está utilizando como la mergeFunction
, que es una BinaryOperator
que recibe dos valores del mapa que tienen la misma clave (es decir, dos Item
instancias con la misma effect
), y se resuelve la colisión en el mapa mediante la selección de la Item
instancia que tiene la max value
( value
es primero Convertido a Integer
, de modo que se comparan los valores numéricos en lugar de cuerdas).