4

So this is more of an "trying to understand" question, than a "I need a solution" question. For an assignment we were ask to create a List of products that have an itemNumber and a price, but only one of each, so no item with the same itemNumber. I figured I could create a set and that would get rid of the duplicates problem. But if I add a producta 1 , 4.99 and a productb 1 , 2.99 , both products are added.

Does that mean, that the set determines these products to be different b/c they have a different price and therefore can be added to the set?

progyammer
  • 1,498
  • 3
  • 17
  • 29
Nik Rawlins
  • 133
  • 1
  • 10
  • 1
    What Set implementation are you using? – Eran Jan 24 '17 at 11:35
  • 4
    Wether or not a Set considers two Objects equal is (usually) depending on the equals and hashCode implementation of the objects class. Did you implement/override those 2 methods in your Product class? – OH GOD SPIDERS Jan 24 '17 at 11:37
  • 1
    @NikRawlins if you have a java.util.HashSet of Product(s) you need to define equals /hashcode. Otherwise (jdk-8 wise) hashcode is computed with masrsaliag xor shift implementation and hashcode is Identity hashcode - which probably is not what you want – Eugene Jan 24 '17 at 11:39
  • @DavidConrad damn Safari auto-correct :) marsaglia.. – Eugene Jan 24 '17 at 11:43
  • 1
    The irony of this this question is that it itself is a duplicate :) – Chetan Kinger Jan 24 '17 at 11:48
  • 1
    @CKing hahah yes! – Eugene Jan 24 '17 at 11:49
  • 1
    The Set doesn't determine if two objects are a duplicate. It uses hashCode/equals or compareTo to determine this. – Peter Lawrey Jan 24 '17 at 11:51

2 Answers2

5

Assuming you are using a form of java.util.Set. Sets in java use the equals method to compare two objects. You want to override the equals method for the class that you wish to compare (Product) to tell the set that they are equal when the item numbers match.

https://docs.oracle.com/javase/7/docs/api/java/util/Set.html

Edit: As 911DidBush and Todd Sewell mentioned, whenever you override the equals method you will also want to override the hashCode method as to not break the contract of hashCode.
From the Java doc:

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html

Sore Throat
  • 189
  • 5
  • 3
    you should add that the hashCode method should also be overridden. Only overriding the equals method and then trying to use it in a HashSet for example is a recipie for disaster. – OH GOD SPIDERS Jan 24 '17 at 11:40
  • 2
    "if you are using a HashSet, you will also want to override the `hashCode` method" -> No! If you are overriding equals you *must* override `hashcode` to conform to the contract of `equals`. – Todd Sewell Jan 24 '17 at 11:47
  • 1
    This answer in combination with the comments helped me understand, thank you for your answers! – Nik Rawlins Jan 24 '17 at 11:52
5

A quote from the Set javadoc:

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element.

As you can see, whether or not two objects are considered the same is determined by calling the accordingly named equals method. Keep in mind that when you implement equals you should also implement hashcode, as explained here and in the equals javadoc.

Community
  • 1
  • 1
Todd Sewell
  • 1,444
  • 12
  • 26