I have simple question to you, I have class Product that have fields like this:
private Integer id;
private String category;
private String symbol;
private S
All Set
implementations remove duplicates, and the LinkedHashSet
is no exception.
The definition of duplicate is two objects that are equal to each other, according to their equals()
method. If you haven't overridden equals
on your Product
class, then only identical references will be considered equal - not different instances with the same values.
So you need to add a more specific implementation of equals
(and hashcode
) for your class. For some examples and guidance, see Overriding equals and hashcode in Java. (Note that you must override hashcode
as well, otherwise your class will not behave correctly in hash sets.)
The code seems to be adding to the list twice. Once during the addAll()
call then once again during the iteration. In this case I believe the second iteration would suffice. The comparison should also be modified to use equals
instead of ==
public void setList(Set<Product> list) {
if(list.isEmpty())
this.list = list;
else {
//this.list.addAll(list); Do not add all
Iterator<Product> it = this.list.iterator();
for(Product p : list) {
while(it.hasNext()) {
if(it.next().getId().equals(p.getId()))
{
this.list.add(p);
}
}
}
}
}
I would suggest you implement your own hash function in a way that it hashes elements with equal ID-s with the same code. This will solve your issue, without you having to code it explicitly.
I won't give you straight answer, but a couple of advices.
Product
in a Set
you need to implement its equals()
and hashCode()
methods.equals()
you will have to decide what "equality" for a Product
means, (Set
can contain only one instance in terms on "equality"). For instance, if two Product
instances are "equal" is it enough if they have the same ID or should we also take quantity into account?. It's not easy to answer this question in your case, but please read on.Product
instances in memory with different quantities
, because one of them would represent a state that is incorrect (ie. particular product's quantity can be either 1 or 3, not both at a time).I think the design is not fully correct. Product
class in your case represents a general product description (including price), so quantity
doesn't really fit there. If someone can order a couple of copies of Product
I think you should create another class such as Order
or OrderLine
which specifies what product is ordered and the corresponding quantity, eg:
class OrderLine { private Product product; private Integer quantity; }
With design like this it's easy to answer question from point 2. Product.equals()
should compare the ID only, and OrderLine.equals()
both the product (ID) and quantity.
As others have already said, you will need to implement (override) equals()
, hashCode()
and (prefarably) compareTo()
from Comparable
interface. These methods, if not implemented correctly can lead to unexpected runtime behavior. Hard to debug issues. Hence, I suggest you use Apache Commons
EqualsBuilder
, HashcodeBuilder
and ComparableBuilder
to implement these methods. An example of how to use Apache Commons builder
can be seen in this link http://www.javaworld.com/community/node/1859