如何将这三个订单列表合并到一个具有相同名称项目的列表合并到一行?

时间:2016-10-14 15:27:10

标签: java arraylist hashmap

我有三个订单,其中包含客户从商店购买的商品。 enter image description here 下面是订单上的行模型。

public class ShopOrderItem {

private String name;
private String itemcode;
private int count;
private double price;
private String taxRate;



public ShopOrderItem() {
    super();
}
public ShopOrderItem(String name, String itemcode, int count, double price,
        String taxRate) {
    super();
    this.name = name;
    this.itemcode = itemcode;
    this.count = count;
    this.price = price;
    this.taxRate = taxRate;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getItemcode() {
    return itemcode;
}
public void setItemcode(String itemcode) {
    this.itemcode = itemcode;
}
public int getCount() {
    return count;
}
public void setCount(int count) {
    this.count = count;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}
public String getTaxRate() {
    return taxRate;
}
public void setTaxRate(String taxRate) {
    this.taxRate = taxRate;
}

}

以下是如何获得3个订单。

public class testList {

ShopOrderItem a = new ShopOrderItem("apple","001",2,(double)4.00,"0.17");
ShopOrderItem b = new ShopOrderItem("banana","002",1,(double)2.00,"0.17");
ShopOrderItem c = new ShopOrderItem("light","003",1,(double)30.00,"0.17");
ShopOrderItem d = new ShopOrderItem("apple","001",5,(double)4.00,"0.17");
ShopOrderItem e = new ShopOrderItem("light","003",10,(double)30.00,"0.17");
ShopOrderItem f = new ShopOrderItem("apple","001",1,(double)4.00,"0.17");
ShopOrderItem g = new ShopOrderItem("pen","004",3,(double)3.00,"0.17");

List<ShopOrderItem> orderA = new ArrayList<ShopOrderItem>();
orderA.add(a);
orderA.add(b);
orderA.add(c);

List<ShopOrderItem> orderB = new ArrayList<ShopOrderItem>();
orderB.add(d);
orderB.add(e);

List<ShopOrderItem> orderC = new ArrayList<ShopOrderItem>();
orderC.add(f);
orderC.add(g);

}

我想将此3个列表合并到一个列表中。 当同名时,添加计数。 例如,我的新列表将有一行,名称是苹果,计数是三个订单&#39;苹果的总和。 我如何合并这三个名单?

3 个答案:

答案 0 :(得分:1)

用法:groupByNameAndSumCount(orderA, orderB, orderC)

static List<ShopOrderItem> groupByNameAndSumCount(List<ShopOrderItem>... orders) {
    List<ShopOrderItem> merged = new ArrayList<>();
    for (List<ShopOrderItem> order : orders) {
        merged.addAll(order);
    }

    // group all by name as this is our invariant
    HashMap<String, ShopOrderItem> grouped = new HashMap<>();
    for (ShopOrderItem item : merged) {
        String name = item.getName();
        if (grouped.containsKey(name)) {
            ShopOrderItem current = grouped.get(name);
            // sum count
            current.setCount(current.getCount() + item.getCount());
        } else {
            grouped.put(name, item);
        }
    }

    // reusing to reduce memory footprint
    merged.clear();

    // prepare result
    for (String key : grouped.keySet()) {
        merged.add(grouped.get(key));
    }
    return merged;
}

希望它有所帮助,先生!

答案 1 :(得分:0)

您可以将3个列表添加到一个列表中,对其进行排序,然后将它们放入地图中。然后将地图变成一个列表。

    List<ShopOrderItem> merged = new ArrayList<ShopOrderItem>();
    merged.addAll(orderA);
    merged.addAll(orderB);
    merged.addAll(orderC);

    Collections.sort(merged, new Comparator<ShopOrderItem>() {

        @Override
        public int compare(ShopOrderItem o1, ShopOrderItem o2) {
            return (Integer.parseInt(o1.getItemcode()) - Integer.parseInt(o2.getItemcode()));

        }
    });
    HashMap<String,Integer> map = new HashMap<String,Integer>();
    for (ShopOrderItem shopOrderItem : merged) {
        if(map.containsKey(shopOrderItem.getItemcode())){
            int current = map.get(shopOrderItem.getItemcode());
            current+=shopOrderItem.getCount();
            map.remove(shopOrderItem.getItemcode());
            map.put(shopOrderItem.getItemcode(), current);
        }else{
            map.put(shopOrderItem.getItemcode(), shopOrderItem.getCount());
        }
    }
    List<ShopOrderItem> result = new ArrayList<ShopOrderItem>();
    Set<Entry<String,Integer>> set = map.entrySet();
    for (Entry<String, Integer> entry : set) {
        if(entry.getKey().equals(a.getItemcode())){
            ShopOrderItem t = new ShopOrderItem(a.getName(), a.getItemcode(), entry.getValue(), a.getPrice(), a.getTaxRate());
            result.add(t);  
        }else if(entry.getKey().equals(b.getItemcode())){
            ShopOrderItem t = new ShopOrderItem(b.getName(), b.getItemcode(), entry.getValue(), b.getPrice(), b.getTaxRate());
            result.add(t);  
        }
        else if(entry.getKey().equals(c.getItemcode())){
            ShopOrderItem t = new ShopOrderItem(c.getName(), c.getItemcode(), entry.getValue(), c.getPrice(), c.getTaxRate());
            result.add(t);  
        }
        else if(entry.getKey().equals(g.getItemcode())){
            ShopOrderItem t = new ShopOrderItem(g.getName(), g.getItemcode(), entry.getValue(), g.getPrice(), g.getTaxRate());
            result.add(t);  
        }

    }

答案 2 :(得分:0)

使用Java 8:

Collection<ShopOrderItem> result = Stream.of(orderA, orderB, orderC)
                                            .flatMap(Collection::stream)
                                            .collect(Collectors.groupingBy(
                                                        ShopOrderItem::getItemcode, 
                                                        Collectors.reducing(new ShopOrderItem(), Use::merge)
                                                    ))
                                            .values();

private static ShopOrderItem merge(ShopOrderItem s1, ShopOrderItem s2)
{
    return new ShopOrderItem(s2.getName(), s2.getItemcode(), s1.getCount() + s2.getCount(), s2.getPrice(), s2.getTaxRate());
}