如何从arrayList中删除重复的元素,但是将它们的sum参数删除?

存在带有参数名称,代码,数量和到期日期的对象Item。在我从数据(.csv)创建arrayList之后,得到了重复项的排序列表。

Item name Apples,code 5649.0,quantity 1,exp date 2019-07-03.

Item name Oranges,code 124123.0,quantity 3,exp date 2019-12-04.

Item name Oranges,quantity 4,exp date 2019-12-04.

Item name Peach,code 946598.0,exp date 2017-11-10.

Item name Tomatoes,code 6.5987989764689741E17,quantity 2,exp date 2019-06-20.

对象项具有这些属性

 private String name;

 private double code;

 private int quantity;

 private String expDate;

现在,我需要删除重复项,但是如果名称,有效日期和代码相同(例如,将一行与Oranges保留一行,但将数量更改为7个),则将数量相加。

我考虑过类似的事情,但是不知道在循环中写些什么。


for(Item a : itemsneed) {
            for(int b=1; b<itemsneed.size(); b++) {
                if(a.getcode()==itemsneed.get(b).getcode() && a.getExpDate().equals(itemsneed.get(b).getExpDate())) {


                }
            }

这是我在考虑的问题,但不知道继续前进的方向。这是对的吗?还是有其他更简单的解决方案?

athrunyang 回答:如何从arrayList中删除重复的元素,但是将它们的sum参数删除?

使用适当的键组合结构并创建一个映射器函数-然后将其提供给groupingBy下游的summingInt流收集器,并根据收集的数据重新创建Item对象的列表

我将使用Lombok在下面展示示例,但是基本上我的意思是使用正确的ItemKey / HashCode实现创建不可变的Equals类,并在Item中添加构造函数类,用于根据Item和计算的数量重新创建ItemKey对象(这可以通过另一种方式实现,例如使用某种工厂方法)

@Data
@AllArgsConstructor
class Item {
    private String name;

    private double code;

    private int quantity;

    private String expDate;

    public Item(ItemKey key,int quantity) {
        this.name = key.getName();
        this.code = key.getCode();
        this.expDate = key.getExpDate();
        this.quantity = quantity;
    }
}

@Value
class ItemKey {
    private String name;
    private double code;
    private String expDate;
}

// ... 

Function<Item,ItemKey> compositeKey = item -> new ItemKey(item.getName(),item.getCode(),item.getExpDate());

List<Item> filteredAndQuantityAggregated = itemsNeed.stream()
    .collect(Collectors.groupingBy(compositeKey,Collectors.summingInt(Item::getQuantity)))
    .entrySet()
    .stream()
    .map(entry -> new Item(entry.getKey(),entry.getValue()))
    .collect(Collectors.toList());
,

再次使用流的groupingBy功能,没有龙目岛和某些样式差异的方法。

映射看起来像这样

    List<Item> items = new ArrayList<>();
    Map<ItemGroupKey,Integer> grouped = items.stream()
            .collect(Collectors.groupingBy(ItemGroupKey::new,summingInt(Item::getQuantity)));
    List<Item> dedupedSummed = grouped.entrySet().stream()
            .map(t -> t.getKey().getItem().forQuantity(t.getValue()))
            .collect(Collectors.toList());

,但是您需要先设置好一种机制,然后机器才能运行,ItemGroupKey会在名称,代码和expirationDate相等时指出两个项目相等。请注意,您还必须添加适当的hashCode()实现。我选择使用Item.forQuantity方法来创建具有特定数量集的项目的副本。

   class ItemGroupKey{
    private final Item item;

    ItemGroupKey(Item item) {
        this.item = item;
    }

    public Item getItem() {
        return item;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ItemGroupKey other = (ItemGroupKey) o;
        return Double.compare(other.getItem().getCode(),item.getCode()) == 0 &&
                Objects.equals(other.getItem().getName(),item.getName()) &&
                Objects.equals(other.getItem().getExpDate(),item.getExpDate());
    }

    @Override
    public int hashCode() {
        return Objects.hash(item.getCode(),item.getName(),item.getExpDate());
    }
}

class Item {
    private final String name;
    private final double code;
    private final int quantity;
    private final String expDate;

    Item(String name,double code,int quantity,String expDate) {
        this.name = name;
        this.code = code;
        this.quantity = quantity;
        this.expDate = expDate;
    }

    public Item forQuantity(int quantity){
        return new Item(name,code,quantity,expDate);
    }

    public String getName() {
        return name;
    }

    public double getCode() {
        return code;
    }

    public int getQuantity() {
        return quantity;
    }

    public String getExpDate() {
        return expDate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Item item = (Item) o;
        return Double.compare(item.code,code) == 0 &&
                quantity == item.quantity &&
                Objects.equals(name,item.name) &&
                Objects.equals(expDate,item.expDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name,expDate);
    }
}
本文链接:https://www.f2er.com/3150165.html

大家都在问