java - 如何从arrayList中删除重复元素但它们的总和参数?
问题描述
有带有参数名称、代码、数量和到期日期的对象项目。在我从数据(.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, code 124123.0, quantity 4, exp date 2019-12-04.
Item name Peach, code 946598.0, quantity 1, 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;
现在我需要删除重复项,但如果名称、exp 日期和代码相同,则对数量求和(例如,将一行保留为 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())) {
}
}
这就是我正在考虑的,但不知道从哪里开始。这是对的吗?还是有其他更简单的解决方案?
解决方案
再次使用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
,当它们的名称、代码和过期日期相等时,它会指出两个项目相等。请注意,您还必须添加适当的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, code, quantity, expDate);
}
}
推荐阅读
- driver - Xilinx Zynq 外设驱动程序
- javascript - 后端未将书籍添加到 android app sql
- python - matplotlib:在 3D 轴上绘制路径
- logistic-regression - R 代码从 10 CV 中的 Logistic 回归模型中提取 ROC
- python-3.x - Python:如果单词中的字符是字母,则仅保留超过 3 个单词的行
- node.js - 无法确定您的项目使用哪个原生 SDK 版本,因为未安装模块 `expo`
- azure - 没有可用于服务此操作的连接:SETEX 令牌;redis缓存Dotnet Framework 4.5上的SocketFailure
- sharepoint - 使用用户信息添加/更新项目 Sharepoint Client C#
- reactjs - 我该如何渲染
作为 元素而不是作为?
- .net - 如果字符串包含多个值