java-forum.org
Java 6 Einstieg und professioneller Einsatz
Alter Preis: 34,90 EUR
Jetzt: 0,00 EUR

zzgl. Versandkosten

Zurück   java-forum.org > Java - Programmierung > Java Basics - Anfänger-Themen

Java Basics - Anfänger-Themen Fragen ausschließlich zu Java-Grundlagen von Ein- und Umsteigern

Antwort    
Themen-Optionen Thema durchsuchen Ansicht
Alt 01.10.2009, 14:23   #1 (permalink)
Benutzer
double
 
Registriert seit: 29.07.2008
Beiträge: 76
Abgegebene Danke: 4
Erhielt 0 Danke für 0 Beiträge
Standard Tutorial equals und hashCode überschreiben

Hallo allerseits,

ich habe ein kleines Tutorial zum Thema equals und hashCode geschrieben:

http://blog.buhbuhbuh.de

Wer sich dafür interessiert, ist herzlich eingeladen mal vorbei zu schauen. Auch für konstruktive Kritik bin ich immer dankbar.

Viele Grüße
neurox
neurox ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 14:32   #2 (permalink)
Java-Forum Team
Moderator
 
Benutzerbild von SlaterB
 
Registriert seit: 13.11.2005
Beiträge: 27.714
Abgegebene Danke: 0
Erhielt 1.799 Danke für 1.780 Beiträge
ich wäre froh, nie
if (xy) befehl;
oder
else befehl;
lesen zu müssen

Klammern, Klammern, Klammern, gerade für die Anfänger

----

zwei Produkte mit gleicher artikelNr, gleichem preis, aber unterschiedlicher produkteBezeichnung
würden bei dir equal sein, aber unterschiedlichen hashCode() liefert -> aua

falls produkteBezeichnung immer von artikelNr abhängig sein soll, (was du wohl kaum garantieren kannst), dann brauchst du es in der hashCode-Berechnung gar nicht

edit:
zudem: produkteBezeichnung != artikelBezeichnung
__________________
Hansa wird Meister.

Geändert von SlaterB (01.10.2009 um 14:35 Uhr)
SlaterB ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 14:39   #3 (permalink)
Benutzer
double
Themenstarter
 
Registriert seit: 29.07.2008
Beiträge: 76
Abgegebene Danke: 4
Erhielt 0 Danke für 0 Beiträge
Zitat: SlaterB
Beitrag anzeigen
zwei Produkte mit gleicher artikelNr, gleichem preis, aber unterschiedlicher produkteBezeichnung
würden bei dir equal sein, aber unterschiedlichen hashCode() liefert -> aua
In dem Fall hast Du wohl nicht genau gelesen. Ich habe davor ja extra geschrieben, dass ich das Objekt noch mal erweitert habe, damit man sieht, wie man aus einen String auch noch einen hashCode heraus bekommt und nicht nur aus int und BigDecimal. Aber vielleicht ist das auch etwas missverständlich.

Aber mit den Klammer hast Du schon recht. Ich werde das noch mal etwas überarbeiten. Dann stehen da zwar etwas mehr Zeilen, aber vermutlich ist es dann noch leserlicher.

Grüße
neurox
neurox ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 14:53   #4 (permalink)
Java-Forum Team
Moderator
 
Registriert seit: 13.09.2007
Beiträge: 11.892
Abgegebene Danke: 124
Erhielt 631 Danke für 572 Beiträge
Hier meine Kritikpunkte:
Zwei BigDecimals mit == zu vergleichen ist eig. nicht korrekt (wie eig. bei allen Objekten)

Würde auch vermeiden, alles in einem if/else Block zu schreiben, Boch macht das in seinem Buch auch anders
maki ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 15:17   #5 (permalink)
Benutzer
double
Themenstarter
 
Registriert seit: 29.07.2008
Beiträge: 76
Abgegebene Danke: 4
Erhielt 0 Danke für 0 Beiträge
Zitat: maki
Beitrag anzeigen
Hier meine Kritikpunkte:
Zwei BigDecimals mit == zu vergleichen ist eig. nicht korrekt (wie eig. bei allen Objekten)
... das ist sogar ganz und gar nicht korrekt. Habe ich übersehen. Werde ich auch noch ändern.

Zitat: maki
Beitrag anzeigen
Würde auch vermeiden, alles in einem if/else Block zu schreiben, Boch macht das in seinem Buch auch anders
Ich sehe schon, das Buch ist beliebt
neurox ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 15:20   #6 (permalink)
Java-Forum Team
Moderator
 
Registriert seit: 13.09.2007
Beiträge: 11.892
Abgegebene Danke: 124
Erhielt 631 Danke für 572 Beiträge
Zitat:
Ich sehe schon, das Buch ist beliebt
Ja, sehr, auch hier.
Stimme zwar nicht mit allem darin überein (wozu braucht jede serialisierbare Klaase eine UUID? Meist will man gar nicht zwischen verschiedenen Versionen serialisieren), würde es aber jedem Java Entwickler empfhelen, nicht nur den angehenden.
maki ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 15:29   #7 (permalink)
Stammbenutzer
Viertel Gigabyte
 
Benutzerbild von faetzminator
 
Registriert seit: 05.01.2007
Beiträge: 3.981
Abgegebene Danke: 27
Erhielt 391 Danke für 386 Beiträge
Zitat: SlaterB
Beitrag anzeigen
Klammern, Klammern, Klammern, gerade für die Anfänger
Hier haben wir aber ein unnötiges else case vorliegen.
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
if (a) {
    return b;
} else {
    return c;
}
finde ich leserlicher mit
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
if (a) {
    return b;
}
return c;
noch schöner fänd ich in diesem Beispiel einen check auf !instanceof und dann ein return false.
__________________
Ich bin keine Signatur, ich headbang hier nur!
faetzminator ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 15:31   #8 (permalink)
Benutzer
double
Themenstarter
 
Registriert seit: 29.07.2008
Beiträge: 76
Abgegebene Danke: 4
Erhielt 0 Danke für 0 Beiträge
Zitat: maki
Beitrag anzeigen
Ja, sehr, auch hier.
Stimme zwar nicht mit allem darin überein (wozu braucht jede serialisierbare Klaase eine UUID? Meist will man gar nicht zwischen verschiedenen Versionen serialisieren), würde es aber jedem Java Entwickler empfhelen, nicht nur den angehenden.
... oder weshalb man in gar keinen Fall Exemptions in der Geschäftslogik verwenden darf. Wir hatten das ja vor ein paar Tagen man am Beispiel von NumberFormatExceptions diskutiert. Er wäre ganz klar dagegen, allerdings habe ich da nirgends im Netz oder in der Java API eine besser Lösung gefunden.

Meint ihr, es macht Sinn solche Tuts hier einzustellen? Ich habe die mal (auch für mich selbst) geschrieben, weil ich immer wieder auf das Thema komme.
neurox ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 22:53   #9 (permalink)
Benutzer
double
Themenstarter
 
Registriert seit: 29.07.2008
Beiträge: 76
Abgegebene Danke: 4
Erhielt 0 Danke für 0 Beiträge
Soo, nun habe ich das ganze noch mal überarbeitet und eure Kommentare berücksichtigt.

Des weiteren habe ich den Code auch noch sehr ausführlich erklärt, so dass es nun auch einsteigertauglich sein sollte.

War ein bisschen Arbeit, ich hoffe es hilft dem einen oder anderen.

Grüße
neurox
neurox ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 01.10.2009, 23:31   #10 (permalink)
Stammbenutzer
Megabyte
 
Benutzerbild von Spacerat
 
Registriert seit: 12.10.2004
Beiträge: 2.270
Abgegebene Danke: 42
Erhielt 111 Danke für 108 Beiträge
Da musst du wohl noch mal bei:
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public boolean equals(Object obj)
{
  if(this == obj) { // kurz und buendig
    return true;
  }
  if(!(obj instanceof Produkt)) {
    return false;
  }
  Produkt p = (Produkt) obj;
  // artikelNr ist primitiv und kann deswegen nicht null sein. Nullcheck eruebrigt sich.
  boolean rc = artikelNr != produkt.artikelNr;
  // equalsIgnoreCase missachtet inhaltliche Gleichheit und sollte deswegen nicht unbedingt verwendet werden.
  // Zustand von artikelBezeichnung und preis haengen von den Implementationen der Set-Methoden ab. Nullchecks erforderlich.
  rc &= artikelBezeichnung == produkt.artikelBezeichnung
            || (artikelBezeichnung != null && artikelBezeichnung.equals(produkt.artikelbezeichnung));
  rc &= preis == produkt.preis || (preis != null && preis.equals(produkt.preis);
  return rc;
}
__________________
Kaum macht man's richtig... geht's
Code:
public String why() {
  return "I 've been told so!";
}
Spacerat ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 00:13   #11 (permalink)
Java-Forum Team
IRC-Operator (Java-Chat)
Moderator
 
Registriert seit: 02.07.2009
Beiträge: 5.181
Blog-Einträge: 1
Abgegebene Danke: 12
Erhielt 1.015 Danke für 1.009 Beiträge
Zitat: Spacerat
Beitrag anzeigen
Da musst du wohl noch mal bei:
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public boolean equals(Object obj)
{
  if(this == obj) { // kurz und buendig
    return true;
  }
  if(!(obj instanceof Produkt)) {
    return false;
  }
  Produkt p = (Produkt) obj;
  // artikelNr ist primitiv und kann deswegen nicht null sein. Nullcheck eruebrigt sich.
  boolean rc = artikelNr != produkt.artikelNr;
  // equalsIgnoreCase missachtet inhaltliche Gleichheit und sollte deswegen nicht unbedingt verwendet werden.
  // Zustand von artikelBezeichnung und preis haengen von den Implementationen der Set-Methoden ab. Nullchecks erforderlich.
  rc &= artikelBezeichnung == produkt.artikelBezeichnung
            || (artikelBezeichnung != null && artikelBezeichnung.equals(produkt.artikelbezeichnung));
  rc &= preis == produkt.preis || (preis != null && preis.equals(produkt.preis);
  return rc;
}
du meinst wohl eher
Java Code: Quelltext in neuem Fenster öffnen
1
2
//Produkt p ....
Produkt produkt = (Produkt) obj;


man könnte vllt auch noch
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
if (obj == null) {
            return false;
        }
vor die ganzen checks machen, die würde man sich dann nämlich sparen im falle von null - ich geh nu pennen, gn8 an alle
eRaaaa ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 00:26   #12 (permalink)
Stammbenutzer
Megabyte
 
Benutzerbild von Spacerat
 
Registriert seit: 12.10.2004
Beiträge: 2.270
Abgegebene Danke: 42
Erhielt 111 Danke für 108 Beiträge
Zitat: eRaaaa
Beitrag anzeigen
du meinst wohl eher
Java Code: Quelltext in neuem Fenster öffnen
1
2
//Produkt p ....
Produkt produkt = (Produkt) obj;
Ja, mein ich.
Zitat: eRaaaa
Beitrag anzeigen
man könnte vllt auch noch
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
if (obj == null) {
            return false;
        }
vor die ganzen checks machen, die würde man sich dann nämlich sparen im falle von null
...Hab' mir sagen lassen, dass das durch "instanceof" mit abgedeckt wird. An den nötigen Nullchecks der Instanzvariablen "artikelBezeichnung" und "preis" ändert das allerdings nichts.
__________________
Kaum macht man's richtig... geht's
Code:
public String why() {
  return "I 've been told so!";
}
Spacerat ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 00:48   #13 (permalink)
Java-Forum Team
IRC-Operator (Java-Chat)
Moderator
 
Registriert seit: 02.07.2009
Beiträge: 5.181
Blog-Einträge: 1
Abgegebene Danke: 12
Erhielt 1.015 Danke für 1.009 Beiträge
Zitat: Spacerat
Beitrag anzeigen
Hab' mir sagen lassen, dass das durch "instanceof" mit abgedeckt wird.
oh, stimmt ! dann nehm ich alles zurück (eclipse auto generate hauts auch rein )

nach der suche wie ich das umschreiben kann, bin ich auf folgenden beitrag gestoßen:

EclipseZone - Generate incorrect equals methods with ...

verwirrt mich jetzt irgendwie wie macht mans denn nu richtig
gerade auch weil er ja auch das buch anspricht, von dem hier die rede ist.

nu geh ich aber wirklich ins bett, hoffe dass mich bis zu mnachmittag jemand belehrt
eRaaaa ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 06:34   #14 (permalink)
Premium-Benutzer
 
Benutzerbild von The_S
 
Registriert seit: 29.11.2004
Beiträge: 11.490
Blog-Einträge: 1
Abgegebene Danke: 32
Erhielt 123 Danke für 111 Beiträge
Wenn du magst, kannst du ja auch mal hier einen Blick rein werfen :

Java Blog Buch : 04.03.11 Besondere Methoden (equals, hashCode und toString)

Außerdem werden (habs mal grob überflogen) die produktBezeichungen nicht verglichen (equals wäre hier angebracht) und die preise falsch (du machst das mit ==, bei einem BigDecimal verwendet man aber compareTo).

Nachtrag: OK, produktBezeichnung wird nicht verglichen, weil du ja die artikelNummer vergleichst. Sorry, hab ich überlesen.

Geändert von The_S (02.10.2009 um 07:12 Uhr)
The_S ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 07:52   #15 (permalink)
Stammbenutzer
Megabyte
 
Registriert seit: 28.11.2008
Beiträge: 1.401
Abgegebene Danke: 27
Erhielt 156 Danke für 155 Beiträge
Für das vergleichen der Attribute kann man, wenn man faul ist auch: org.apache.commons.lang.builder (Commons Lang 2.4 API) benutzen.

Weiterhin würde mich jetzt auch nochmal interessieren, was nun beim checken der "Objektart" das richtige ist.

Bisher habe ich das immer wie in "Effective Java" gemacht:
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
10
11
public class A {
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (!(obj instanceof A)) {
      return false
    }
    A other = (A) obj;
    ...
}
mvitz ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 07:58   #16 (permalink)
Premium-Benutzer
 
Benutzerbild von The_S
 
Registriert seit: 29.11.2004
Beiträge: 11.490
Blog-Einträge: 1
Abgegebene Danke: 32
Erhielt 123 Danke für 111 Beiträge
Richtig ist alles, was den equals-contract erfüllt

Object (Java 2 Platform SE v1.4.2)#equals

Nachtrag: Da ist wohl was mit dem Link schiefgegangen.
The_S ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 08:16   #17 (permalink)
Stammbenutzer
Viertel Gigabyte
 
Benutzerbild von byte
 
Registriert seit: 17.06.2005
Beiträge: 4.593
Blog-Einträge: 1
Abgegebene Danke: 7
Erhielt 22 Danke für 20 Beiträge
Am effektivsten gehts imo so: Building equals(), hashCode(), compareTo() and toString() with ease | Benjamin Winterberg
byte ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 08:51   #18 (permalink)
Java-Forum Team
Moderator
 
Benutzerbild von SlaterB
 
Registriert seit: 13.11.2005
Beiträge: 27.714
Abgegebene Danke: 0
Erhielt 1.799 Danke für 1.780 Beiträge
hashCode muss wirklich nicht alle Attribute beinhalten,
von beispielsweise
private String firstName;
private String lastName;
private Date birthday;
private String street;
private String city;
private String zipcode;
sollte firstName + lastName eindeutig genug sein, im Extremfall noch das Datum,
durch den Rest wirds auch nicht besser
__________________
Hansa wird Meister.
SlaterB ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 09:09   #19 (permalink)
Stammbenutzer
Viertel Gigabyte
 
Benutzerbild von byte
 
Registriert seit: 17.06.2005
Beiträge: 4.593
Blog-Einträge: 1
Abgegebene Danke: 7
Erhielt 22 Danke für 20 Beiträge
Lass die Datenbestände geeignet groß werden und Du hast unrecht.
byte ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 02.10.2009, 09:11   #20 (permalink)
Premium-Benutzer
 
Registriert seit: 06.01.2007
Beiträge: 14.092
Abgegebene Danke: 0
Erhielt 1.104 Danke für 1.031 Beiträge
Im Gegenteil: Der Sinn von hashCode ist ja auch, dass er schnell ausgerechnet werden kann. Wenn man sich bei der Berechnung auf Fields beschränken kann, die immutable sind, kann es sogar Sinn machen, eine "private int hashCode" anzulegen, die schon im Konstruktor berechnet wird - und bei Personen sollte das eigentlich der Fall sein ... man ändert seinen Namen nicht 10 mal am Tag, und das Geburtsdatum ändert sich höchstens 4 mal

EDIT: @byte: hashCode muss nicht eindeutig sein, und ist es meistens auch nicht. Auch ein public int hashCode() { return 0; } wäre "richtig". Blöd, aber richtig.
Marco13 ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Antwort    

Lesezeichen

Stichworte
equals hashcode

Latex Maths & Physics Editor ...

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln
Es ist Ihnen erlaubt, neue Themen zu verfassen.
Es ist Ihnen erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Frage zu equals() und hashCode() bienchen84 Java Basics - Anfänger-Themen 28 11.06.2009 00:30
equals() - hashCode() - Contract Spacerat Java Basics - Anfänger-Themen 54 03.04.2009 23:19
HashCode überschreiben! Skull Java Basics - Anfänger-Themen 17 24.03.2009 11:05
Vergleiche mit Equals(), hashCode() und == rene_kochan Java Basics - Anfänger-Themen 10 16.10.2008 09:52
Überschreiben von equals und hashcode für Collection vogella Allgemeine Java-Themen 7 17.08.2007 15:50


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:37 Uhr.


Powered by vBulletin® Version 3.8.6 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.2
Thanks for Smilies by smilies.4-user.de