Java - 汇总列表中每个重复订单的订单数量

时间:2015-01-20 15:50:15

标签: java algorithm

使用下面提供的代码,我想要实现的是: 我有订单进来,如果列表中有相同产品的订单 - 由产品名称标识,我必须增加第一个订单的数量并删除其他类似的订单。

以下列表中类似订单的示例: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;
}   
}

5 个答案:

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

然后,您可以将此地图转换为更新订单的“列表”。