double-Comparsion und hashCode()

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

double-Comparsion und hashCode()
Im letzten wöchentlichen Meeting wurde ja gesagt, man soll in der isEqual() Methode von Coordinate, die doubles mit einem delta vergleichen.
Gleichzeitig muss man ja noch die hashCode() Methode überschrieben.
Hier ergibt sich nun aber ein Problem, denn die hashCode() Methode muss folgende Eigenschaft erfüllen.

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

Wenn man nun also die Objekte new Coordinate(3*1.1,0,0) und new Coordinate(3.3,0,0) hat, sollen die also nach equals() gleich sein, aber wie soll dann der hashCode() gleich sein?
In dem Meeting wurde ja noch gesagt man soll die hashCode() Methode einfach per IDE generieren lassen. Genau dann würde aber die obige Eigenschaft nicht mehr erfüllt sein.
Was ist nun also richtig?


Hi,

ich habe in Coordinate einfach eine simple hashCode()-Methode selber implementiert und die doubles entsprechend meines deltas mit

/**
 * Rundet den übergebenen Wert auf die Anzahl der übergebenen Nachkommastellen
 *
 * @param value ist der zu rundende Wert.
 * @param decimalPoints ist die Anzahl der Nachkommastellen, auf die mathematisch gerundet werden soll.
 */
private double rint(double value, int decimalPoints) {
   double d = Math.pow(10, decimalPoints);
   return Math.rint(value * d) / d;
}

gerundet.

LG


Das Vergleichen von Gleitkommazahlen mit einem Delta (also [m]abs(a-b) < delta[/m]) widerspricht alleine auch schon den geforderten Eigenschaften von equals():

Vielleicht liegt hier, wenn das kein Tippfehler war, die Antwort?


Widerspricht wieder https://github.com/dirkriehle/adap-course/blob/master/Generated/Lecture%20slides/ADAP%20A02%20-%20Course%20Homework.pdf Folie 10

Die einzige Möglichkeit um die Transitivität bei equals() zu erfüllen wäre das ganze mit Division ohne Rest zu vergleichen also so wie @jsh247 es vorgeschlagen hat.
Dann ist aber wieder 0.99999999999999 != 1.
So eine Äquivalenzrelation hat halt nun mal gewisse Regeln, da kann man nicht einfach so ein delta einbauen.


Hi zusammen,

es ist richtig, dass die hashcode() der equals() Methode entsprechen MUSS. D.h. auch die hashcode() Methode muss dieser Logik folgen.
Mein Vorschlag wäre, ähnlich wie jsh247 vorgeschlagen hat, eine private Hilfsmethode anzulegen, die dann in equals() und hashcode() verwendet wird. Ich würde dabei nach einer gewissen Nachkommastelle runden.

Der equals() Vergleich sollte immer auf der Fachlichkeit der Domäne beruhen. Eine Anforderungsanalyse könnte für den Anwendungsfall von Wahlzeit beipielsweise ergeben, dass es nicht nötig ist eine Geo-Auflösung von unter 1m zu haben.

Ich hoffe das klärt eure Fragen.

Viele Grüße,
Georg