### A Set of Coordinate instances

No. 186

#### Inserting Coordinate instances into a Set.

 Q: Create a Set of Coordinate instances including duplicates. Iterate over this set and write each value to System.out in a similar fashion to Inserting strings into a Set. . Compare your output to the corresponding example Inserting strings into a Set. . Did you expect this behaviour? Explain this result and a solution. A: Our code is very similar to Inserting strings into a Set. : final Set points = new HashSet(); points.add(new Coordinate(1, 2)); points.add(new Coordinate(4, 1)); points.add(new Coordinate(1, 2)); // Equal to first Object // Iterate over all inserted coordinates System.out.println("The set contains " + points.size() + " elements:"); for (final Coordinate c : points) { System.out.println(c.toString()); }Since we do have set semantics we expect the duplicate coordinate value (1|2) to be dropped and thus to appear only once. So our set should contain {(4|1), (1|2)}. We however see the duplicate object appearing on standard output: The set contains 3 elements: (4|1) (1|2) (1|2)This is due to our own fault not providing a hashCode() implementation being compatible to our overridden equals() method. Consider: final Coordinate c12 = new Coordinate(1, 2), c12Duplicate = new Coordinate(1, 2); System.out.println("c12.hashCode() and c12Duplicate.hashCode():"+ c12.hashCode() + "," + c12Duplicate.hashCode());This yields the following output:c12.hashCode() and c12Duplicate.hashCode():1334574952,1882008996Apparently the two instances c12 and c12Duplicate are equal to each other. Their hash codes however are different clearly violating the contract being described in Java Collections - hashCode() and equals(). The values actually stem from hashCode() being defined in our superclass Object. The former exercise Inserting strings into a Set. involved instances of class String having well defined equals() and hashCode() implementations. To resolve this issue we thus have to override not just equals() but hashCode() as well: public class Coordinate { private int x, y; ... @Override public int hashCode() { // See last answer (06/16/2014) in // http://stackoverflow.com/questions/16629893/good-hashcode-implementation return Long.valueOf(x * 31 + y).hashCode(); } }This yields:c12.hashCode() and c12Duplicate.hashCode():33,33And finally:The set contains 2 elements: (1|2) (4|1)