# toString() methode überschreiben mit rekursivem aufruf.



## reliC (24. Dez 2007)

Hi all, sitze grad an nem kleinen problem mit meinem Java programm...soll ne übung sein und naja irgendwie klappts grad nicht.
Ich soll ne Klasse Stapel(Stack) implementieren mit einem push und pop welcher etwas zum stapel hinzufügt und mit pop den stack durchsucht und den gefundenenen wert zurückgibt bzw ausgibt....naja also Die Objekte auf dem Stapel sollen vom Typ Object sein. Dann soll ich eben noch für die Ausgabe die vorhandene Methode toString() überschreiben und damit dann die "String" Objekte so ausgeben:
"A,B,C...." 

nun hier mal mein Code bekomme irgendwie immer ein Stackoverflow und weiß nich wo der fehler liegt....


```
public class Stapel {
	public int anzahl=0;
	Object[] objekt;
	
	
	public Stapel(){
		this.objekt = new Object[1000];
	}
	
	
	public void push(Object o){
			if(this.anzahl < 1000){
			this.objekt[anzahl] = o;
			this.anzahl = this.anzahl + 1;
		}
	}
	
	
	public Object pop(Object o){
		
		for(int i=0; i<this.anzahl; i++){
			if(this.objekt[i]==o){
				return this.objekt[i];
			
			}
		}return null;
	}
	
	
	public String toString(){
		
		int zaehler = -1;
		
		if(zaehler < this.anzahl){
			zaehler++;
			return this.objekt[zaehler]+","+toString();
			
		}else
			return (String)this.objekt[zaehler];
	
	}

	
}
```

wär echt nett wenn mir da einer ein tipp geben könnte oder geht das gar nicht so wie ich es mache mit der rekursion?? 

greetz reliC ach und frohe weihnachten *g*


----------



## Ark (24. Dez 2007)

In welcher Reihenfolge sollen denn die Elemente ausgegeben werden?

a) ältestesElement, ..., jüngstesElement
b) jüngstesElement, ..., ältestesElement

Ark

EDIT: Seit wann wird in einem Stack _gesucht?!_ :shock: In Stacks wird nur _gefunden!_ Ich habe keine Ahnung, was du da implementiert hast, aber ein Stack ist das definitiv nicht.

Ark


----------



## reliC (24. Dez 2007)

hehe vielleicht habe ich die aufgabe falsch beschrieben, also die aufgabenstellung war so:

_
In dieser Aufgabe soll eine Klasse implementiert werden, die einen Stapel realisiert.
Die Klasse soll einen Konstruktor und zwei Methoden zur Verfügung stellen:
✗ Der Konstruktor hat keinen Parameter und soll einen leeren Stapel erzeugen.
✗ Die Methode push legt ein Objekt auf den Stapel.
✗ Die Methode pop nimmt ein Objekt vom Stapel und gibt es als Rückgabewert
zurück.
Detailbeschreibung:
✗ Die Objekte auf dem Stapel sollen vom Typ Object sein.
✗ Verwenden Sie zur Implementierung der Klasse die Klasse Vector.
Die Dokumentation von Vector finden Sie unter
http://java.sun.com/j2se/1.5.0/docs/api/index.html


*
B ) Überschreiben Sie in Stapel die Methode toString() so, dass die Stapelinhalte
durch Kommata getrennt aufgezählt werden.
 Beispiel: "auto,katze,hund"
*_

wie ich das verstanden habe einfach vom jüngsten element zum ältesten element...denke das is so schon richtig dann gemacht nur leider bekomme ich halt ein stack overflow.... als fehlermeldung da irgendwie die rekursion nicht so funktioniert wie sie soll obwohl ich ja eine abbruchbedingung habe durch den zaehler mit dem this.anzahl der objekte die gespeichert wurden im array ;(


----------



## Marco13 (24. Dez 2007)

Es gibt 1000 Möglichkeiten, die toString zu implementieren. Aber in deiner Implementierung wird "toString" eben rekursiv aufgerufen, und zwar immer auf dem selben Objekt. Wenn
if(zaehler < this.anzahl){ 
einmal erfüllt ist, dann ist es immer erfüllt - auch beim nächsten rekursiven Aufruf.

Am einfachsten wäre es vmtl. eine Methode zu machen, die nacheinander alle Elemente des Arrays durchgeht und an einen String hängt. Falls sie unbedingt rekursiv sein soll (wozu kein Anlaß besteht) dann könnte das mit einer
private String toString(int aktuellerArrayIndex) { ... }
gemacht werden. Der rekursive Aufruf würde dann so aussehen
return .... + toString(aktuellerArrayIndex*+1*);

Und in der eigentlichen toString-Methode würde dann nur stehen
return toString(0);


----------



## reliC (24. Dez 2007)

ahhh jetzt versteh ich wo mein fehler liegt bzw wieso ich ein stack overflow hatte. Hab das dann mal so gelöst wie du  gemeints hast. Dabei wird zwar toString in der Methode nicht mehr überschrieben aber ich denke das ist so schon ok:


```
public String toString(int zaehler){
		
		if(zaehler < this.anzahl-1){
			return this.objekt[zaehler]+","+toString(zaehler+1);
			
		}return (String)this.objekt[zaehler];
	
	}
```



danke für eure hilfe  :toll: 

greetz reliC


----------



## Marco13 (25. Dez 2007)

Ja nochmal: Du "musst" trotzdem in der Klasse eine Methode anbießen

```
public String toString()
{
    return toString(0);
}
```

Die 'toString' Methode wird nämlich automatisch aufgerufen, wenn man aus einem Objekt einen String macht, bzw. das Objekt ausgibt. Hier:

```
System.out.println(objekt);
```
wird (wenn 'objekt' nicht 'null' ist!) praktisch

```
System.out.println(objekt.toString());
```
ausgeführt.

Und auch nochmal: Es besteht eigentlich kein Grund, diese Methode rekursiv zu schreiben: Man könnte auch einfach mit einer for-Schleife durch den Array laufen. Aber es kann nicht schaden, wenn man bei BEIDEM weiß, wie es geht


----------



## tincup (25. Dez 2007)

Aber nochmal was anderes, was Ark oben schon gesagt hatte, du hast *keinen* Stack implementiert.

Deine Aufgabenstellung war:


			
				reliC hat gesagt.:
			
		

> Die Methode pop nimmt ein Objekt vom Stapel und gibt es als Rückgabewert
> zurück.



Und die Implementierung ist:


```
public Object pop(Object o){
		
		for(int i=0; i<this.anzahl; i++){
			if(this.objekt[i]==o){
				return this.objekt[i];
			
			}
		}return null;
	}

	
}
```

Das ist nicht das richtige. Dein pop() erfüllt eher "Die Methode pop prüft ob ein Objekt im Speicher drin ist und gibt es dann zurück, null falls nicht". Bei einem korrekten Stack gibt es mit pop() das zuletzt hinzugefügte Objekt zurück, und das ist dann nicht mehr im Stapelspeicher drin, wird also nach dem pop() gelöscht (bzw. die Referenz darauf wird gelöscht).


EDIT:

Bei Wiki kannst du es nachgucken (die ersten Abschnitte sollten für die Funktionsweise reichen):
http://de.wikipedia.org/wiki/Stapelspeicher


----------



## reliC (25. Dez 2007)

@marco
jetzt hab ichs klar muss ja so sein da ich sonst immer z.b x.toString(0) aufrufen...hab das jetzt geändert. Stimmt ich könnte das auch mit der for schleife lösen aber finde rekursion irgendwie schicker bzw wollte das auch mal wieder üben weil sonst hab ich alles meistens mit den schleifen gelöst.

@tincup
danke für deine hilfe hab wirklich die beschreibung für die methode pop() falsch verstanden. Hab das mal geändert denke das wär jetzt so richtig aber ich muss immer um 2 wärte verringern da er mir nach dem letzten element immer noch ein null objekt reinsetzt seh auch grad nicht wieso das so ist aber mit -2 klappt das ja auch. Falls das noch immer falsch ist was ich fabriziert habe dann bitte korriegiert mich wills ja lernen...



```
public Object pop(){
		
		Object o = null;
		o=this.objekt[anzahl-2];
		this.objekt[anzahl-2]=null;
		return o;
		
	}
```



greetz reliC


----------



## Andreas29 (26. Dez 2007)

Hi,

ich möchte mich hier gerne nochmal kurz in die Diskussion einmischen:
@relic:
Verwende die Rekursion nur, wenn es gar nicht anders geht (was wie meine Vorredner schon erwähnt haben hiern icht der Fall ist). Denn Rekursion liest sich schwerer als eine einfache Schleife und ist somit, meiner bescheidenen Meinung nach, zweitrangig in der Verwendung.
Wollte ich nur mal anmerken.

Grüße und weiterhin frohe Festtage!
Andreas


----------

