The equals() documentations states (emphasis added):
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.
public boolean add(E e)
Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.
Specified by:
add in interface Collection<E>
Specified by:
add in interface Set<E>
Overrides:
add in class AbstractCollection<E>
Parameters:
e - element to be added to this set
Returns:
true if this set did not already contain the specified element
I hadn't been here for fifteen years
Aahan Agrawal wrote:
Also, how should I construct a hashCode() method such that every unique coordinate returns a unique integer? Is there some mathematical function that, using both x and y, could return a distinct output for every distinct combination of x and y?
Some function of the form x^n + y^m comes to mind, but I'm not sure how to determine if this would map a unique int to every x and y?
Paweł Baczyński wrote:Also note that your equals() method violates the contract of Object.equals()...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Unfortunately they do not give enough information to find that paper, so one cannot verify that assertion at the source. Angelika Langer is a bit more optimistic about equals() methods and lists some correct and incorrect implementations; you may need to follow that link to next section several times to find that piece.Winston Gutkowski wrote: . . . this excellent article[/url] warns us that:
"The authors of a 2007 paper concluded that almost all implementations of equals() are faulty."
. . .
Eric Osman wrote:What is your reaction to this solution compared to one where hashCode and equals are overridden?
Since Carey hasn't suppied any means to alter x and y once the constructor has completed, why not make the class immutable by marking those two fields and the whole class final? That gets you out of having to mark any methods final, since there can't be any subclasses. It also obviates a potential problem with HashSets, HashMaps, etc.; if you enter mutable objects as Es or Ks and those objects change state so as to change their hashcodes, it will become impossible to locate those objects again. I believe that problem will NOT occur if you use mutable objects as Vs in a hash table or map.Stephan van Hulst wrote:Carey . . . make the method final.
Please explain more; that situation is exactly the sort of thing records are good for. Again, records weren't available eight years ago.. . . Or if you don't mind the downsides of using a record . . .
Somebody's on their way to help already, the cheque's in the post, and overriding equals() is easy. This thread lists several places where you can read how difficult it can be to override equals(). IDEs can help, but the boilerplate code they produce will be no good for people who need to learn how objects work. The example you showed is a correct implementation of equals(), which can be reused mutatandis mutatis for any class, using Objects#equals() to prevent any problems where a field points to null.Stephan van Hulst wrote:. . . Overriding equals() and hashCode() is a really tiny effort . . .
Not quite what Odersky Spoon and Venners said:-We found buggy or fragile equals() methods in nearly every Java application that we examined.
In one case, Vaziri, Tip, Fink, and Dolby mention a hashcode() method using the wrong alphabet of variables. In order to write hashcode() correctly, the alphabet of variables it uses must be a subset of the alphabet of variables used by equals(). It is obviously easiest to use exactly the same variables in both places, remembering that does count as a subset. Objects#hash() wasn't available in 2007, but you showed how much easier that makes it to write a hashcode() method.. . . after studying a large body of Java code, the authors of a 2007 paper concluded that almost all implementations of equals methods are faulty.
Campbell Ritchie wrote:Please explain more; that situation is exactly the sort of thing records are good for.
Campbell Ritchie wrote:Somebody's on their way to help already, the cheque's in the post, and overriding equals() is easy.
Campbell Ritchie wrote:You have to write your own constructor and getter methods if you want to include a mutable type as a field of a record, too.
Stephan van Hulst wrote:. . . if you need to return mutable types from your getters (other than collection types), your design is off in the first place . . .
Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |