使用下面提供的代码,我想要实现的是: 我有订单进来,如果列表中有相同产品的订单 - 由产品名称标识,我必须增加第一个订单的数量并删除其他类似的订单。
以下列表中类似订单的示例:P3和P4。
但是这种方法导致例外,并且想知道你们是否可以建议任何其他方法。
这是一个示例列表,我的列表一般包含800或更多订单。
public class RollUpLogic {
public static void main(String[] args) {
List<Order> orderList = new ArrayList<Order>();
orderList.add(new Order("P1", 1));
orderList.add(new Order("P2", 1));
orderList.add(new Order("P3", 1));
orderList.add(new Order("P3", 1));
orderList.add(new Order("P3", 1));
orderList.add(new Order("P4", 1));
orderList.add(new Order("P4", 2));
//if same product ordered, Rollup the quantity and remove duplicate orders
Iterator<Order> iterator = orderList.iterator();
while(iterator.hasNext()) {
Order order = iterator.next();
int firstIndex = orderList.indexOf(order);
int lastIndex = orderList.lastIndexOf(order);
while(firstIndex!=lastIndex) {
//+1 qty of firstindex order
order.setProductQTY(order.getProductQTY()+1);
//remove order at lastIndex
orderList.remove(lastIndex); //throws concurrent modification exception
lastIndex = orderList.lastIndexOf(order);
}
}
}
}
class Order{
private String productName;
private int productQTY;
public Order(String productName, int productQTY) {
super();
this.productName = productName;
this.productQTY = productQTY;
}
public int getProductQTY() {
return productQTY;
}
public void setProductQTY(int productQTY) {
this.productQTY = productQTY;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((productName == null) ? 0 : productName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Order other = (Order) obj;
if (productName == null && other.productName != null) {
return false;
} else if (!productName.equals(other.productName))
return false;
return true;
}
}
答案 0 :(得分:0)
我建议您使用分组订单创建另一个列表。 对于内存来说这不是一个问题,因为您将添加引用。
答案 1 :(得分:0)
您只需创建一个新列表,而不是修改现有列表。在迭代集合时,您不能使用Collection.remove
(或add
等),这就是导致异常的原因。
为提高效率,您可以使用LinkedHashMap
代替。
LinkedHashMap<Order> orderMap = new LinkedHashMap<Order>();
for (Order order: orderList) {
String orderName = order.getProductName();
if (orderMap.containsKey(orderName)) {
Order existing = orderMap.get(orderName);
existing.setProductQty(existing.getProductQty() + order.getProductQty());
} else {
orderMap.put(orderName, order);
}
}
// optionally, copy back to the list
orderList.clear();
for (Order order: orderMap.values()) {
orderList.add(order);
}
答案 2 :(得分:0)
您尝试实现的基本上是从String(productName)到int(quantity)的MultiMap。为什么不使用一个(例如guava有一个很好的通用实现,或者你可以使用trove TObjectIntHashMap及其adjustOrPutValue
方法?
答案 3 :(得分:0)
答案 4 :(得分:0)
使用Map<String, Integer>
跟踪每个产品名称的商品数量:
Map<String, Integer> productQuantity = new HashMap<>();
for(Order o : orderList) {
Integer q = productQuantity.get(o.getProductName());
int newQ = o.getProductQTY() + (q == null ? 0 : q.intValue());
productQuantity.put(o.getProductName(), newQ);
}
然后,您可以将此地图转换为更新订单的“列表”。