Eu estou lutando para reduzir uma lista:
Digamos que eu tenho um List<Item> listItems
com uma Item
classe 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;
}
}
Agora, na minha listItems
lista, eu tenho alguns elementos com a mesma effect
propriedade.
Eu quero remover todos os elementos da minha listItems
lista com a mesma effect
propriedade, exceto aquele com a maior value
propriedade. ( value
É o número representado como um String
).
Além disso, eu quero manter todo o elemento com uma única effect
propriedade.
Como posso conseguir isso? Eu acho que eu vou ter que lidar com Comparator
.
Parece que você quer agrupar os itens de sua lista effect
, usando max(value)
como uma agregação. Você pode fazer isso da seguinte forma:
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();
A solução acima recolhe elementos do fluxo para um Map
. Para isso, ele usa uma sobrecarga de Collectors.toMap
que requer 3 argumentos:
- keyMapper : a
Function
que transforma elementos do fluxo de chaves - valueMapper : um
Function
que transforma os elementos do fluxo de valores - mergeFunction : um
BinaryOperator
que é usado para colisões resolver entre os valores associados com a mesma chave
Neste caso, a Item::getEffect
referência método está a ser utilizado como o keyMapper função, que transforma um Item
exemplo para a sua effect
. Em seguida, Function.identity()
está a ser utilizado como o valueMapper função, que não faz nada, isto é, deixa cada Item
instância intocado. Finalmente, BinaryOperator.maxBy(Comparator.comparingInt(i -> Integer.parseInt(i.getValue())))
está a ser utilizada como a mergeFunction
, que é uma BinaryOperator
que recebe dois valores do mapa que ter a mesma chave (isto é, dois Item
casos com o mesmo effect
), e resolve a colisão no mapa, seleccionando o Item
exemplo que tem o máximo value
( value
é primeiro convertidos para Integer
, de modo que nós comparamos os valores numéricos em vez de cordas).