Wie intelligent ist dieses überschriebene .equals() ?

Status
Nicht offen für weitere Antworten.

t3_chris

Mitglied
Hi!

Ich muss für mehrere meiner Klassen equlas() überschreiben.
Da diese Klassen extrem viele Eigenschaften haben möchte ich nicht jede dieser Eigenschaften händisch vergleichen.

Daher habe ich mir folgendes überlegt:

Code:
   @Override
    public boolean equals(Object obj) {
        DemoMock other;
        if( obj instanceof DemoMock) {
            other = (DemoMock) obj;
        }
        try {
            ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
            ObjectOutputStream os1 = new ObjectOutputStream(bos1);
            os1.writeObject(this);
            os1.close();

            ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
            ObjectOutputStream os2 = new ObjectOutputStream(bos2);
            os2.writeObject(other);
            os2.close();

            byte[] arr1 = bos1.toByteArray();
            byte[] arr2 = bos2.toByteArray();

            return Arrays.equals(arr1, arr2);
        } catch (Exception e) {
            e.printStackTrace();
            return <irgendwas>;
        }
    }

Welche Nachteile bzw. Gefahren hat der Vergleich des serialisierten Objekts (ausser der wahrscheinlich nicht sehr guten Performance)?

mfg
christian
 
S

SlaterB

Gast
zumindest könntest du ja bei !(obj instanceof DemoMock) sofort false zurückgeben statt other==null zu serialisieren ;)

der Code dürfte auch gar nicht funktionieren, other könnte nicht initalisiert sein,
eine andere Gefahr als schlechte Performance und Mega-Arrays wenn enthaltene Elemente auf riesige Datenstrukturen verweisen fällt mir nicht ein
 

tfa

Top Contributor
t3_chris hat gesagt.:
Ich muss für mehrere meiner Klassen equlas() überschreiben.
Da diese Klassen extrem viele Eigenschaften haben möchte ich nicht jede dieser Eigenschaften händisch vergleichen.
Eine gute IDE macht sowas automatisch, z.B. Eclipse: Source->Generate hashCode() and equals()
 

t3_chris

Mitglied
SlaterB hat gesagt.:
der Code dürfte auch gar nicht funktionieren,

Ja, das stimmt der Code funktioniert so nicht, war aber auch nur zur Frage bezügl. des "Konzepts" gedacht.

Ich komme momentan nicht an den Original Code ran, da ich in an meinem Arbeitsplatz noch nicht ins SVN gecheckt hatte und ihn daher von hier aus - zu Hause - nicht sehen kann.

danke,
christian
 

t3_chris

Mitglied
tfa hat gesagt.:
Eine gute IDE macht sowas automatisch, z.B. Eclipse: Source->Generate hashCode() and equals()

... verwende Netbeans.... aber woher weiß Eclipse eigentlich ob evtl. vorhandene Sub-Objekte das equals() sinnvoll implementiert haben? Oder vergleicht Eclipse anders als mit equals()? Kannst du ein Beispiel posten?

mfg
christian
 

t3_chris

Mitglied
t3_chris hat gesagt.:
tfa hat gesagt.:
Eine gute IDE macht sowas automatisch, z.B. Eclipse: Source->Generate hashCode() and equals()

... verwende Netbeans.... aber woher weiß Eclipse eigentlich ob evtl. vorhandene Sub-Objekte das equals() sinnvoll implementiert haben? Oder vergleicht Eclipse anders als mit equals()? Kannst du ein Beispiel posten?

mfg
christian

Oh. Habe gerade gesehen, dass Netbeans das ja auch kann....
 

tfa

Top Contributor
t3_chris hat gesagt.:
aber woher weiß Eclipse eigentlich ob evtl. vorhandene Sub-Objekte das equals() sinnvoll implementiert haben?
Gar nicht. Das musst du schon sicherstellen.

Oder vergleicht Eclipse anders als mit equals()? Kannst du ein Beispiel posten?
Eclipse vergleicht nicht, es generiert die equals-Methode:

Code:
public class Person {
	
	private String name;
	private int schuhgröße;
	private String telefonnummer;
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Person))
			return false;
		final Person other = (Person) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (schuhgröße != other.schuhgröße)
			return false;
		if (telefonnummer == null) {
			if (other.telefonnummer != null)
				return false;
		} else if (!telefonnummer.equals(other.telefonnummer))
			return false;
		return true;
	}	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + schuhgröße;
		result = prime * result
				+ ((telefonnummer == null) ? 0 : telefonnummer.hashCode());
		return result;
	}
}
 

SchonWiederFred

Bekanntes Mitglied
Was sind das überhaupt für Klassen? Man muss equals und hashCode ja nicht zwangsweise überschreiben, oft ist das sogar falsch. Nimm z.B. eine Klasse "Spieler" in einem Adventure mit 100 Exemplarvariablen. Es wäre ziemlich dumm, equals und hashCode zu überschreiben:

- stecke den Spieler in eine HashSet
- verändere irgendwas am Spieler, gib ihm z.B. Energie
- frage das HashSet, ob der Spieler enthalten ist
- mit großer Wahrscheinlichkeit wird der Spieler nicht im HashSet gefunden

equals und hashCode müssen nur für Wertobjekte überschrieben werden.
 

foobar

Top Contributor
@schonWiederFred Das sehe ich etwas anders. In deinem Beispiel wäre der Spieler auch eine Entity und jede Entity hat zumindest eine id über die diese identifiziert wird. In der equals-Methode des Spielers würde man dann erstmal auf instanceof Spieler prüfen und danach auf die id. So kann man 2 Spieler problemlos vergleichen.
 

SchonWiederFred

Bekanntes Mitglied
Objekte haben doch sowieso schon eine Identität, wozu dann noch die id als Exemplarvariable? Wozu willst Du überhaupt zwei Spieler vergleichen?
 

foobar

Top Contributor
Wenn die Spieler irgendwo persistiert werden kann es vorkommen, daß man einen Spieler aus einer Suche mit einem komplett befüllten Spieler vergleichen will und dann ist es sinnvoll per PK zu vergleichen.
 

byte

Top Contributor
Man sollte bei persistenten Entitäten den equals() Vergleich nicht (nur) auf die ID beschränken! Die ID wird bei neuen Entitäten i.d.R. erst beim Speichern vergeben. Vergleichst Du nur nach ID, dann sind die Entitäten fälschlicherweise so lange gleich, bis sie zum ersten Mal gespeichert wurden.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben