使用Java 8

时间:2018-10-18 17:26:52

标签: java java-8 java-stream

我正在努力减少清单:

假设我有一个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 :(得分:4)

似乎您想使用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 :将流中的元素转换为键的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的{​​{1}}实例来解决地图中的冲突(value首先被转换为value,因此我们比较数字值而不是字符串。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

“我想让所有元素都具有独特的效果属性”:假设所有<?php $conn = mysqli_connect('localhost', 'root', '', 'cms'); if(mysqli_connect_errno()) echo 'DB connection error:'.mysqli_connect_error(); ?> 对象都具有有效的Itemeffect

value