# Object Inhalt vergleichen?



## mobile (9. Apr 2007)

Hi, muss noch mal kurz nerven.

Erstelle irgendwo in meinem Programm Objecte vom Typ Track, diese Objecte enthalten Strings. Heißt, wenn ich nichts eingebe ist ein Object mit leeren Inhalt erzeugt.

Nun möchte ich wo anders in meinem Programm testen ob ein Object in meiner Liste leer ist. Mache das grade so, aber das geht irgendwie nicht.


```
//Neues leeres Object von Disc wird angelegt
			Track emptyTrack = new Track((byte)1, "", "", "");
			
			for(int i = 0; i < list.size(); ++i) {
				System.out.println(list.get(i).equals(emptyTrack));
				if(emptyTrack.equals(list.get(i))) {
					
				}
				else {
					System.out.print((i+1)+ " ");
					System.out.println(list.get(i));
				}
			    System.out.println();
		    }
```

MIt list.get(i) hole ich mir die Objecte aus meiner Liste. die eigentlich leer sind. Aber der vergleich ergibt immer false. Wie geht das vielelicht?

Danke für eure Hilfe!


----------



## Wildcard (9. Apr 2007)

Du musst equals so überschreiben das es true liefert wenn du 2 Objekte als Inhaltsgleich betrachtest.
Aber Vorsicht:
Wer A sagt muss auch B sagen, sprich, wenn du equals überschreibst musst du auch hashCode überschreiben.


----------



## gast (9. Apr 2007)

heißt das, dass ich mir eine eigene Methode equals schreiben muss? Wenn ja wie könnte die dann aussehen? Wie sieht das dann mit hash aus?


----------



## Wildcard (9. Apr 2007)

Was soll ich da sagen?
Ich weiß ja nicht was du als Gleichheit von 2 Tracks bezeichnest.
Du musst sie eben so schreiben das bei 2 Tracks die du als gleich ansiehst true rauskommt.
Für hashCode gilt folgender Kontrakt:
wenn o1.equals(o2) true liefert muss o1.hashCode()= o2.hashCode() sein.
Daher musst du wann immer du equals überschreibst auch hashCode überschreiben.


----------



## Guest (9. Apr 2007)

Warum muss ich denn equals eigentlich überschreiben. Denke, das vergleicht schon Objecte. Will 2 Objecte vergelichen, sind beide Leer gibt es true, mehr will ich doch gar nich!


----------



## Wildcard (9. Apr 2007)

equals ist eine Methode von Object. Jede Klasse kann diese Methode üerschreiben um Gleichheit so zu definieren wie sie im gegebenen Kontext passt.
Ein Object ist inhaltslos, daher überprüft ein nicht überschriebenes equals lediglich ob es sich bei 2 Objekten um ein und das selbe Object handelt (o1 == o2)


----------



## Jango (9. Apr 2007)

Wildcard hat gesagt.:
			
		

> Ein Object ist inhaltslos, daher überprüft ein nicht überschriebenes equals lediglich ob es sich bei 2 Objekten um ein und das selbe Object handelt (o1 == o2)



...was bedeutet: Es wird geprüft, ob zwei Objekte auf den *selben* Speicherbereich _zeigen_. :wink:


----------



## JPKI (9. Apr 2007)

Bau die equals-Methode mal folgendermaßen in deine Klasse "Track" ein:

```
public boolean equals(Object o) {
  Track newTrack = (Track)o;
  boolean boo = (getString1().equals(newTrack.getString1())) &&
  (getString2().equals(newTrack.getString2()));
  return boo;
}
```
Wobei du dir mit den Get-Methoden natürlich diese drei Strings geben lassen solltest, die du im Konstruktor übergibst.


----------



## Guest (9. Apr 2007)

Was vergelich ich den damit überhaupt? Versteh das grade nicht so ganz!


----------



## JPKI (9. Apr 2007)

:roll: Du vergleichst damit, ob das Track-Objekt, das gerade durch die Schleife läuft, mit dem "leeren" übereinstimmt. Ist das denn so schwer :roll: ?


----------



## Guest (9. Apr 2007)

Ja irgendwie schon. Hier ist die Klasse Track 


```
import java.io.Serializable;

/**
 * @athor Timo Konietzko
 * Stellt eine Disc mit zugehörigen Daten da
 * */
public class Track implements Serializable, Daten {
	private static final long serialVersionUID = 1L;
	
	/**Attribute der Klasse, speichert jeweils ein Track*/
	public String interpret = "";
	public String titel = "";
	public String dauer = "";
		
	/**
	 * @param, byte track enthält Track Nr.
	 * @param String i, enthält den Interpreten
	 * @param String t, enthält den Titel
	 * @param String d, enthält die Dauer des Titels
	 * */
	Track(byte track, String i, String t, String d) {
		if(track <= MAX_TRACK) {
			this.interpret = i;
			this.titel = t;
			this.dauer = d;				
		}
	}

        public String getInterpret() {
		return this.interpret;
	}
	
	public String getTitel() {
		return this.titel;
	}
	
	public boolean equals(Object o) {
		System.out.println("IN");
		Track newTrack = (Track)o;
		boolean boo = (this.interpret.equals(newTrack) && (this.titel.equals(newTrack)));
		System.out.println(boo);
		return true;
	}
	
	/**
	 * Gibt ein Track wieder aus
	 * */
	public String toString() {
		String tmp = " ";
		final int MAX = 35;
		final int IMAX = 24;
		
		String tmpI = this.interpret;
		String tmpT = this.titel;
		
		while(tmpI.length() < IMAX) {
			tmpI += tmp;
		}
	    	
	    while(tmpT.length() < MAX) {
	    	tmpT += tmp;
		}
	    
	    return tmpI + tmpT + "\t" + this.dauer;
	}
}
```

So und hier die Klasse Open wod er vergleich gemacht wird:


```
//...
//Neues Object von Disc wird angelegt
			Track emptyTrack = new Track((byte)1, "", "", "");
			
			for(int i = 0; i < list.size(); ++i) {				
				if(emptyTrack.equals(list.get(i))) {
					System.out.println("GUT");
				}
				else {
					System.out.print((i+1)+ " ");
					System.out.println(list.get(i));
				}
			    System.out.println();
		    }
//...
```

So und wie soll das jetzt laufe?


----------



## JPKI (9. Apr 2007)

Anonymous hat gesagt.:
			
		

> ```
> public boolean equals(Object o) {
> System.out.println("IN");
> Track newTrack = (Track)o;
> ...


Wieso vergleichst du, wenn du sowieso true zurückgibst?  :bae:  :wink: 
Deine Codetransfer-Fähigkeiten sind (mit Verlaub ;-) ) etwas beschränkt, kann das sein?
Zunächst einmal muss die equals-Methode so aussehen:

```
public boolean equals(Object o) {
      System.out.println("IN");
      Track newTrack = (Track)o;
      boolean boo = (this.interpret.equals(newTrack.interpret) && (this.titel.equals(newTrack.interpret)));
      System.out.println(boo);
      return boo;
   }
```
Die Schleife ist in Ordnung. So müsste das jetzt funktionieren!


----------



## mobile (9. Apr 2007)

ja ist etwas schwer, grad für mich! Jetzt bekomme ich bei


```
Track newTrack = (Track)o;
```

nen ClassCastException?? Hab das so übernommen wie beschrieben!


----------



## JPKI (9. Apr 2007)

Die List, bei der das Track-Objekt in der Schleife übergeben wird, muss (sollte) als List<Track> deklariert werden! Und sie muss natürlich Track-Objekte enthalten...

Anders kann ich mir die ClassCastException nicht erklären...


----------



## mobile (9. Apr 2007)

Also wenn ich ein Object erstelle und gebe anstatt einem String (zB Michael) nichts ein sondern drücke nur Enter, was wird denn dann in dem String gespeichert? Das ist doch dann ein leerer String oder nicht? Also vergleichbar mit 

String s = " ";  oder?

Würde mir nämlich glaub ich weiter helfen. Es gibt ja die Möglichkeit, Groß und Kleinschreibung zu ignorieren, kann man dann auch einfach ein Leerzeichen aus s ignorieren?


----------



## JPKI (9. Apr 2007)

Kommt drauf an, wie du den String bekommst. Wenn du JOptionPane benutzt, bekommst du "" als Rückgabewert wenn du Enter drückst.
Aber das erklärt die ClassCastException nicht! Poste mal den Code, wie du die Liste erstellst!


----------



## mobile (9. Apr 2007)

```
public void make() {	
		System.out.println();
		System.out.println("Disc Nummer: " + akMdnr);
		System.out.println("----------------");
		System.out.println();
		try {	
			for(byte i = 1; i <= MAX_TRACK ; i++) {	 
		 	    System.out.println("Track    : " + i);
				    
		 	    System.out.print("Interpret: ");
				String interpret = din.readLine();
				    
				System.out.print("Titel    : ");
				String titel = din.readLine();
						     
				System.out.print("Dauer    : ");
				String dauer = din.readLine();
				   			    
				System.out.println();
				
				//Neues Object von Disc wird angelegt und in Liste gepseichert
				Track track = new Track(interpret, titel, dauer);
				liste.add("" + track);
			}
			
			boolean save = false;
			while(save == false) {
				save = doSave();
			}
						
			//Liste wird serialisiert
			try {
				//Name für die List wird gebildet
				String listname = "Disc_";
				listname += String.valueOf(this.akMdnr);
				listname += ".ser";
			    
				FileOutputStream fs = new FileOutputStream(listname);
				ObjectOutputStream os = new ObjectOutputStream(fs);
				os.writeObject(liste);
				os.close();
				System.out.println("Disc wurde unter " + Make.mdnr + " gespeichert!");
			}
//...
```

in doSave() wird die eingabe von ja oder nein getestet.


----------



## Roar (9. Apr 2007)

liste.add(*"" + *track); 
das is mumpitz :autsch: wie kommst du auf sowas? damit fügst du der liste einen String und keinen Track hinzu.


----------



## JPKI (9. Apr 2007)

```
list.add(track);
```
Ich geb's auf! Gegen so viel ****heit ist kein Kraut gewachsen   :cry:    :bloed:  :noe:


----------



## Verjigorm (9. Apr 2007)

auch wenn also wenn ich manchmal lese, was ihr hier so postet, dann hab ich teilweise echt Hemmungen etwas im ANFÄNGERFORUM zu fragen :bloed: 

auch wenn einem hier sehr oft sehr schnell geholfen werden kann


----------



## JPKI (9. Apr 2007)

Eigentlich sind wir hier immer gewillt zu helfen. Aber wenn sich jemand weigert, sich das Brett vorm Kopf zu entfernen, regt mich das auf.

Vor allem, wenn die Probleme so offensichtlich sind! Wer zu einer List einen String added (list.add(""+track) (!) :roll: ) und sich dann wundert, dass er beim Typecasting (Track track = (Track)list.get(int) :roll: ) eine ClassCastException bekommt, hat ein ziemliches Brett vorm Kopf.


----------

