StackOverflow

SlamHomer

Mitglied
Hi,

ich schreibe gerade ein Programm für meinen Bruder, mit dem er englisch Vokabeln lernen kann (mit GUI).

Nun hab ich folgende Methode:
Java:
public static void position_befüllen(englisch_vok[] vok_position, englisch_vok[] vok_zufall, int i){		
		while(i<=9){
			Random randomGen = new Random();
			int random = randomGen.nextInt(10);
			if(vok_zufall[random]!=null){
				vok_position[i]=vok_zufall[random];
				vok_zufall[random]=null;
				i++;
			}else{position_befüllen(vok_position,vok_zufall,i);}			
		}
	  
	}

welche mit
Java:
englisch_vok.zufall_befüllen(englisch_vok.vok_zufall);
englisch_vok.position_befüllen(englisch_vok.vok_position,englisch_vok.vok_zufall,0);
aufgerufen wird (englisch_vok ist die Classe der obrigen Methode ;) ).

Was soll diese Methode machen? Es soll zufällig eine Vokabel aus dem Array vok_zufall gewählt werden und an die stelle i im Array vok_position gesetzt werden und diese Vokabel dann (durch null) in vok_zufall gelöscht werden. Falls an der stelle null steht ruft sich die Methode rekursiv mit dem aktuellen wert von i wieder auf.

Die Arrays werden mit
Java:
protected static englisch_vok[] vok_zufall=new englisch_vok[10];
protected static englisch_vok[] vok_position=new englisch_vok[10];
initialisiert.
englisch_position ist vor der obrigen Methode leer, wärend englisch_zufall mit Vokabeln befüllt ist.

Folgender fehler kommt bei dieser Methode leider:
Code:
Exception in thread "main" java.lang.StackOverflowError
	at englisch_package.englisch_vok.position_befüllen(englisch_vok.java:60)
	at englisch_package.englisch_vok.position_befüllen(englisch_vok.java:65)
	at englisch_package.englisch_vok.position_befüllen(englisch_vok.java:65)
	at englisch_package.englisch_vok.position_befüllen(englisch_vok.java:65)
	(...)
geht noch eine weile so weiter.
60 ist :int random = randomGen.nextInt(10);
65 ist: }else{position_befüllen(vok_position,vok_zufall,i);}

Laut Debugger läuft alles so wie ich es will-sprich das Array vok_position wird komplett richtig befüllt- bis i=10 ist. Jetzt sollte er eigendlich nichts mehr machen, aber i wird dann wieder zu 9->10->9->10->9->(...) usw.
Nur ich hab keine Ahnung warum.
Wenn ich den Teil weglasse, der dafür da ist, dass keine Vokabel doppelt eingetragen wird, geht alles klar, nur hab ich dann halt Vokabeln doppelt.


Btw. ich denke mal, dass meine Lösungung der Methode nicht gerade optimal ist. Ich möchte aber (später) selber Code optimierungen vornehmen, deswegen bitte keine "Spoiler" ^^' wie man es besser machen könnte.
 

Marco13

Top Contributor
Mal ganz isoliert betrachtet:
Java:
while(i<=9)
{
    // Hier code der NIE aus der Schleife raushüpft 
    // (sondern bestenfalls mal einen rekursiven Aufruf macht)
}

Spoiler: ... Später ;)
 
S

SlaterB

Gast
so ganz check ich das Posting von Marco13 auch nicht, i wird doch erhöht, theoretisch die Schleife beendet,
man muss es nur im Gesamtkontext sehen,

der erste Aufruf (EA) findet ein leeres Array vor, der Zufall ist einem hold und gleich 8 Positionen werden erfolgreich übertragen,
dann ist irgendwann etwas null oder nicht null, jedenfalls diese andere Situation die unverständlicherweise zum rekursiven Aufruf führt (warum?),
dort geht noch alles gut, i steht bei 8 oder so, im Zufallsbereich 0-9 sind noch zwei Elemente frei, entweder direkt hier oder durch weitere Rekursion werden irgendwann alle 10 Elemente übertragen, EINE while-Schleife letztlich durchbrochen,
dann gehts aber zurück zu einer der höheren Rekursionsstufen, spätestens zum ersten Aufruf EA, der ja eine Rekursion gestartet hatte in diesem Beispiel,
bei dem ist i immer noch 8, die Variable wird nicht auf magische Weise auf 10 aktualisiert,
und da nun im Zufallsarray nichts mehr drin ist (welches als übergebenes Objekt durchaus verändert "zurückkommt") ist eine Endlosschleife besiegelt bzw. ein ständiger rekursiver Aufruf, der zur Exception führt,

bevor du komplizierte schrecklich aussehende Programme schreibst (kein _, Klassen groß!), solltest du einfache Dinge üben
int x = 4:
int y = x;
y++;
// ist x nun 4 oder 5?
 

SlamHomer

Mitglied
Daran hatte ich garnicht gedacht, danke ^^

(...)
bevor du komplizierte schrecklich aussehende Programme schreibst (kein _, Klassen groß!), solltest du einfache Dinge üben
int x = 4:
int y = x;
y++;
// ist x nun 4 oder 5?

Mehrere Klassen sind eigendlich kein Prob. für mich, nur hab ich seit über einem Jahr nicht mehr programmiert. Hab gedacht das wäre wie fahrradfahren, aber hab wohl doch ein paar Sachen vergessen :oops:
 

Marco13

Top Contributor
Ja, das was ich da geschrieben hatte war vielleicht verwirrend. Nicht ganz so verwirrend wie das Programm an sich (stell dir mal vor, du hättest die Vokabeln auf Kärtchen geschrieben: Wie wüdest du die Aufgabe dann lösen?). Spätestens, wenn der eine Array voll und der andere leer ist, landet er in einer undurchschaubaren Mischung aus Endlosschleife und Endlosrekursion.
 

Landei

Top Contributor
So lehrreich das Schreiben einer eigenen Misch-Funktion auch sein mag, sollte man doch die "eingebaute" Lösung bevorzugen:

Java:
import java.util.*;

...

//Java Standard sind Klassen in Großschreibung und CamelCase, 
//also EnglischVok statt englisch_vok
List<EnglischVok> vokabeln = new ArrayList<EnglischVok>();
for(...) {
   EnglischVok vokabel = ... //woher auch immer
   vokabeln.add(vokabel);
}
Collections.shuffle(vokabeln); //jetzt sind sie gemischt
 

Ähnliche Java Themen

Neue Themen


Oben