2015-12-19 55 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創建了額外的關鍵類 –