2015-12-19 33 views
3

我有一个似乎很平凡的问题,但我正在寻找解决该问题的最佳方法。ArrayList对其元素的“squash”操作

比方说,我有一个类:

Product.class

public class Product { 
    private int id; 
    private String code; 
    private String price; 
    private String quantity; 

    public Product() {} 

    //getters and setters 

    @Override 
    public boolean equals(Object obj) { 
     boolean result = false; 
     if (obj instanceof ProductOnStockDto) { 
      ProductOnStockDto product = (ProductOnStockDto) obj; 
      result = (this.code.equals(product.getCode()) && this.price.equals(product.getPrice())); 
     } 
     return result; 
    } 
} 

而且让我们说我有这个对象的列表:

List<Product> products; 

其中填充数据,如this (1行是一个列表元素):

而我需要的是迭代这个列表和壁球元素具有相同的代码和相同的价格。例如:

在结果列表,我想有两个产品code 3

code 3 | 1.22 | 11 
code 3 | 2.20 | 6 

所以我会做某事像这样:

for(Product product : products) { 
    for(Product productToSquash : products) { 
     if(product.getId() != productToSquash.getId() && product.equals(productToSquash)) { 
      //Here I would like to squash these two rows 
      //Data conversion is ommited 
      product.setQuantity(product.getQuantity() + productToSquash.getQuantity()); 
      //after that I would like to remove productToSquash object from the collection 
     } 
    } 
} 

但我知道这是不是允许修改我正在迭代的集合。那么按照这个例子,压缩所有产品清单的最好方法是什么?

回答

1

它们加载到HashMap中,以“南瓜”,然后从它加载到新的集合

class Pair 
    { 
     String code; 
     float price; 
    } 

    HashMap<Pair, Product> hashMap = new HashMap<Pair, Product>(); 
    List<Product> collection = new ArrayList<Product>(); //a new container for your values 

    //for every Product in products 
    // if in hashMap there is no Product with code and price add it 
    // else resolve it (override? ignore? ...) 

    for(Entry<Pair, Product> entry : hashMap.values()) { 
     collection.add(entry.getValue()); 
    } 

注意,你必须决定究竟你会被挤压元素

+2

不能做'新列表'。你是不是指'新的ArrayList'? ---无法迭代'hashMap'。你的意思是'hashMap.entrySet()'? ---如果你这样做,为什么不使用'hashMap.values()'? ---在添加值之前,您需要清除()集合。 ---原始值的顺序丢失。 – Andreas

+0

嗨安德烈亚斯,感谢您的建议,这段代码是伪类型的,但当然我应该关心正确的语法 - 我不确定我是否得到* clear()*的东西 - 你能解释一下吗? –

+0

您对“collection”中的每个产品都说过,它假设一些代码最初填充了“collection”列表,然后迭代该列表以构建“hashMap”,最后将值添加回'collection'。如果您在添加“合并”产品之前未清除列表,最终会出现大量重复项目,除非您已“压扁”。 – Andreas

1

首先,您的equals()方法是指ProductOnStockDto。那应该是Product

要在迭代期间删除元素,请直接使用Iterator,即使用“旧样式”for-loop,并使用Map<Product, Product>来跟踪以前看到的产品。这需要你同时实现hashCode()

@Override 
public int hashCode() 
{ 
    return this.code.hashCode() * 37 + this.price.hashCode(); 
} 
Map<Product, Product> map = new HashMap<Product, Product>(); 
for (Iterator<Product> productIter = products.iterator(); productIter.hasNext();) { 
    Product product = productIter.next(); 
    Product productToKeep = map.get(product); 
    if (productToKeep == null) 
     map.put(product, product); 
    else { 
     productToKeep.setQuantity(productToKeep.getQuantity() + product.getQuantity()); 
     productIter.remove(); 
    } 
} 

你真不该这样做,因为equals()方法返回true对于不是真正等于对象。

而应该有公正codeprice一键类,并重点班是一个需要实现equals()hashCode(),不Product

+0

谢谢,它是乐于助人。最后我为map创建了额外的关键类 –