I have a problem that seems to be trivial but I'm looking for the best way of resolving that issue.
Let's say I have a class:
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;
}
}
And let's say I have a list of this objects:
List<Product> products;
Which is filled with data like this(1 row is one list element):
And what I need is to iterate over this list and squash elements that have the same code and the same price. For example:
In the result list I would like to have two products for code 3:
code 3 | 1.22 | 11
code 3 | 2.20 | 6
So I would do sth like this:
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
}
}
}
But as I know it is not allowed to modify collection that I'm iterating on. So what would be the best way to squash all product list according to the example?
First of all, your equals() method refers to ProductOnStockDto. That should be Product.
To remove elements during iteration, use the Iterator directly, i.e. use an "old style" for-loop, and use a Map<Product, Product> to keep track of products previously seen. This requires that you also implement 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();
}
}
You shouldn't really be doing it this way, since the equals() method is returning true for objects that are not truly equal.
You should instead have a key class with just code and price, and the key class is one that needs to implement equals() and hashCode(), not Product.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With