Удалить элемент с повторяющимся свойством на основе другого свойства из списка, используя Java 8 - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь уменьшить список:

Допустим, у меня есть List<Item> listItems с определенным классом Item, таким как:

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;
    }
}

Теперь в моем listItems список, у меня есть некоторые элементы с таким же свойством effect.

Я хочу удалить все элементы из моего списка listItems с тем же свойством effect, за исключением того, который имеет более высокое значение valueимущество.(value - это число, представленное как String).

Кроме того, я хочу сохранить все элементы с уникальным свойством effect.

Как мне этого добиться?Я думаю, мне придется иметь дело с Comparator.

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

Похоже, вы хотите сгруппировать элементы вашего списка по effect, используя max(value) в качестве агрегации.Вы можете сделать это следующим образом:

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();

Приведенное выше решение собирает элементы потока в Map.Для этого используется перегрузка Collectors.toMap, для которой требуется 3 аргумента:

  • keyMapper : a Function, преобразующий элементы потока включи
  • valueMapper : Function, преобразующий элементы потока в значения
  • mergeFunction : BinaryOperator, используемый для разрешенияконфликты между значениями, связанными с одним и тем же ключом

В этом случае ссылка на метод Item::getEffect используется как функция keyMapper , которая преобразует экземпляр Item в свойeffect.Затем Function.identity() используется в качестве функции valueMapper , которая ничего не делает, т.е. оставляет каждый экземпляр Item без изменений.Наконец, BinaryOperator.maxBy(Comparator.comparingInt(i -> Integer.parseInt(i.getValue()))) используется как mergeFunction, то есть BinaryOperator, который получает два значения карты с одинаковым ключом (то есть два экземпляра Item с одинаковым effect) и разрешаетстолкновение на карте путем выбора экземпляра Item, который имеет максимум value (value сначала преобразуется в Integer, так что мы сравниваем числовые значения вместо строк).

0 голосов
/ 19 октября 2018

«Я хочу сохранить все элементы с уникальным свойством эффекта»: при условии, что все Item объекты имеют действительные effect и value:

//group list entries to sub - lists having the same effect value
Map<String, List<Item>> map = itemList.stream()
                                      .collect(Collectors.groupingBy(Item::getEffect)) ;

List<Item> uniqueEfectMaxValue = new ArrayList<>();
//get item having max value and add to uniqueEfectMaxValue
map.forEach((key,list)->{
                          Item item = list.stream().
                             collect(Collectors.maxBy(Comparator.
                                  comparing(Item::getValue))).get();
                          uniqueEfectMaxValue.add(item);
                         }
             );
0 голосов
/ 18 октября 2018
  1. Как объяснено nullpointer, вы можете получить карту с эффектом в качестве ключа,
    и элементом в качестве значения.Пожалуйста, обратитесь к фрагментам кода ниже

Добавьте элементы в список, как показано ниже

List<Item> itemList = new ArrayList<>();
itemList.add(new Item("e1", "10"));
itemList.add(new Item("e1", "20"));
itemList.add(new Item("e1", "30"));
itemList.add(new Item("e2", "10"));
itemList.add(new Item("e3", "10"));
itemList.add(new Item("e3", "-10"));

Логика для устранения дубликатов и сохранения элементов с наибольшим значением

Map<String, Item> effectMap = new HashMap<>();
for (Item item : itemList) {
    Item itemWithHigherValue = effectMap.get(item.getEffect());
    if (itemWithHigherValue == null || 
        (Integer.parseInt(item.getValue()) > 
        Integer.parseInt(itemWithHigherValue.getValue()))) 
    {
        effectMap.put(item.getEffect(), item);
    }

        }

Печать результатов

List<Item> uniqueItemList = new ArrayList<Item>(effectMap.values());

for (Item item : uniqueItemList) {
    System.out.println(item);
}
...