Java While- in For-Schleife umschreiben

Status
Für weitere Antworten geschlossen.

FreddyCollin

Ensign
Registriert
Dez. 2014
Beiträge
236
Hi, sitze grade an Übungsaufgaben und habe leider niemand der mich korrigieren kann, deshalb frag ich hier nur kurz nach ob das richtig ist (ich hoffe das zählt nicht als "Hausaufgabenhilfe")


Aufgabe:
Schreiben sie die Schleife im folgenden Java-Programmcodefragment so in eine for-Schleife um, dass das Programmfragment genau die selbe Ausgabe erzeugt wie vorher.

Code:
ArrayList<Rucksack> studentenRucksaecke = new ArrayList<Rucksack>();
...
int pos = studentenRucksaecke.size();
while (pos >= 1) {
	pos--;
	studentenRucksaecke.get(pos).gewichtPruefen();
}

Meine Lösung wäre also:
Code:
ArrayList<Rucksack> studentenRucksaecke = new ArrayList<Rucksack>();
...
for(int pos = studentenRucksaecke.size(); pos>=1; pos--) { 
	studentenRucksaecke.get(pos).gewichtPruefen()
	}

ist das schon richtig so?
 
Macht die Schleife denn was sie soll?
Auf anhieb sieht es richtig aus. Ich überseh aber auch gerne Kleinigkeiten.
 
NiThDi hat natürlich Recht.

Code:
for(int pos = studentenRucksaecke.size(); pos>=1; pos--) { 
	studentenRucksaecke.get(pos - 1).gewichtPruefen()
	}
 
Zuletzt bearbeitet:
Bei deinem Code wirst du wahrscheinlich eine ArrayIndexOutOfBoundsException bekommen und hast außerdem das Problem, dass das erste Objekt in der Liste (Index 0) nicht behandelt wird.

Erklärung zur Exception:
size() liefert dir die Anzahl der Elemente in der Liste. Da die Indizes der Listen und Arrays aber 0-basiert sind (d.h. der Zugriff beginnt bei 0), ist der Index des letzten Elements immer size() - 1 bzw bei Arrays length - 1.

Erklärung for-Schleifen Fehler:
Deine Abbruchbedingung (pos >= 1) ist falsch formuliert. Die Schleife wird das erste Element der Liste (Index 0) nicht behandeln, weil die Abbruchbedingung schon beim Vorletzten greift. In der ursprünglichen while-Schleife ist alles korrekt, denn dort ist pos vor dem Abbruch zwar auch 1, wird dann aber vor dem Zugriff auf die Liste nochmal um 1 verringert (pos--).

So viel dazu erst mal, will dir die Lösung jetzt nicht direkt vorgeben. Denke das schaffst du :)

Edit: @jenix: Die Liste muss von hinten nach vorn abgearbeitet werden, daher ist dein Code leider nicht die Lösung der Aufgabe.
 
Zuletzt bearbeitet:
jenix schrieb:
Deine Lösung ist richtig, schöner ist jedoch die vorgeschlagene Lösung unten. Hat den Vorteil, dass es leserlicher ist und weniger fehleranfällig, da der Index nicht mit der Länge verwechselt wird (ist ein Klassiker).
Code:
ArrayList<Rucksack> studentenRucksaecke = new ArrayList<Rucksack>();
...
for(Rucksack studentenRucksack : studentenRucksaecke) { 
studentenRucksack.gewichtPruefen();
}

das ist doch eine For-Each und keine For-Schleife?!
@NiThDi
Ich versteh den Fehler, aber müsste doch dann so gehen oder:

Code:
for(int pos = studentenRucksaecke.size(); pos>=0; pos--) { 
	studentenRucksaecke.get(pos).gewichtPruefen()
	}


//Funktionalität kann ich nicht prüfen da es pseudo Code Fragment ist
 
Zuletzt bearbeitet:
Hast du probiert, ob das funktioniert? So wie ich das sehe, wird da immer noch eine IndexOutOfBoundsException kommen.
 
FreddyCollin schrieb:
Ich versteh den Fehler, aber müsste doch dann so gehen oder:

Code:
for(int pos = studentenRucksaecke.size(); pos>=0; pos--) { 
	studentenRucksaecke.get(pos).gewichtPruefen()
	}


//Funktionalität kann ich nicht prüfen da es pseudo Code Fragment ist

nein das geht kaputt, da die size methode die anzahl der rucksäcke zurückgibt (vermutlich) - beispielsweise 8.
jetzt wird aber die adressierung dieser rucksäcke nicht mit 1 sondern mit 0 beginnend (wie eigentlich immer in der informatik) gemacht. das heißt, wenn du 8 rucksäcke hast ist die position vom ersten gespeicherten rucksack pos=0 und die vom letzten rucksack pos=7. daraus folgt, dass ein .get(8) zwangsläufig fehlschlagen muss, weil nur 8 rucksäcke da sind :)

veranschaulichung hier:
http://2.bp.blogspot.com/-v-dkON4gw...1x8PGgt-U/s1600/Array+in+Java+Comparision.gif

wobei indices dein "pos" ist und und array length der rückgabewert deiner size() methode.
 
Zuletzt bearbeitet:
@aroxx
es ist SEINE aufgabe - ich finde bei solchen anfragen sollte man lediglich Hilfestellungen zur selbstbearbeitung geben. das ist die wirklich einzige sinnvolle hilfe.

und die aufgabe ist nun wirklich nicht schwer - du hast die ziel ausgabe und bastelst dir aus den Komponenten mithilfe der forschleife stück für stück deinen code.
- for grundgerüst
- überlege in welcher Richtung die while schleife läuft
- baue die gegeben Daten/Konstrukte ein
- lasse es laufen
- überprüfe warum eine exception geworfen wird
- passe den code an
- fertig
 
FreddyCollin schrieb:
//Funktionalität kann ich nicht prüfen da es pseudo Code Fragment ist

Klar kannst du das prüfen. Mach doch einfach ein kleines Testprojekt, welches nur eine Klasse mit der main() Methode hat und darin legst du halt eine Liste von Integers an und spielst das durch. Das dauert max. eine Minute :)

@sparvar: Sehe ich so wie du (bezogen auf deinen ersten Satz).
 
Zuletzt bearbeitet:
sparvar schrieb:
@aroxx
es ist SEINE aufgabe - ich finde bei solchen anfragen sollte man lediglich Hilfestellungen zur selbstbearbeitung geben. das ist die wirklich einzige sinnvolle hilfe.

eigentlich hast du recht. habs mal entfernt vllt hat ers noch nicht gesehen :D
 
ich bin zwar kein java entwickler, aber in c++ wäre ein iterator ggf auch nützlich...

sowas wie...

Code:
ArrayList<Rucksack> studentenRucksaecke = new ArrayList<Rucksack>();

//iterator erstellen und hinter das letzte element der liste zeigen lassen
ListIterator<Rucksack> iter = studentenRucksaecke.listIterator( studentenRucksaecke.size() );

// rückwärts durch die liste wandern..
while( iter.hasPrevious() ) {
  iter.previous().gewichtPruefen();
}

ein vorteil ist, dass man nicht mit array-index arbeiten muss...
wie gesagt; java ist bei mir schon jahre her und das ganze ist aus dem kopf her ungetestet...
 
Eigene Iteratoren sind nix für Leute die grad Schleifen lernen :)

Hier geht es um OutOfBounds Exception, also den Zugriff auf Speicher über die Grenzen hinweg.
Ein Array bekommt Speicher reserviert, z.B. von Adresse 0x000000 bis 0x000010, also immer durchgehend. In diesem Fall passen 11 Einträge rein.

An jeder Adresse stehen Pointer, also ein Verweis auf eine andere Stelle im Speicher, wo dann die Werte deiner Variablen etc. stehen. Greift man nun auf 0x000011 zu, kennt das System keinen Eintrag dazu und wirft dir so einen Error.

Auf 0x000011 greifst du z.B. zu wenn du zu weit iterierst, d.h. dein ">=" müsste eventuell einen Schritt weniger machen, also ">". Java ist hier sehr kulant und zeigt einem solche Errors sehr präzise an.
 
Zuletzt bearbeitet:
Ich will auch gar keine Lösung, will es natürlich kapieren... Würde gerne dem Ansatz nachgehen, dass ich es auf Funktionalität prüfe und habe versucht eine Arrayliste anzulegen... Alles geklappt nur sagt er mir für die letzte Zeile "Methode gewichtPruefen is undefined for type integer."


Code:
import java.util.ArrayList;


public class Umschreiber {
	
	
	public void gewichtPruefen(){
		
	}
	
	public static void main(String[]args){
		
		ArrayList<Integer> studentenRucksaecke = new ArrayList<Integer>();
		studentenRucksaecke.add(1);
		studentenRucksaecke.add(4);
		studentenRucksaecke.add(7);
		studentenRucksaecke.add(11);
		studentenRucksaecke.add(14);
		studentenRucksaecke.add(16);
		studentenRucksaecke.add(19);
		studentenRucksaecke.add(13);
		studentenRucksaecke.add(3);
		studentenRucksaecke.add(2);
		studentenRucksaecke.add(6);	
		
		
		for(int pos = studentenRucksaecke.size(); pos>=0; pos--) { 
			studentenRucksaecke.get(pos).gewichtPruefen();
			}
		
	}

}

Wie muss ich die Methode denn anpassen, damit ich eine Ausgabe hab?
 
Ich weiß nicht, ob du das mit der Punkt-Schreibweise schon so ganz verstanden hast. Also
Code:
studentenRucksaecke.add(6);
funktioniert nur, weil die Klasse, zu der studentenRucksaecke gehört - nämlich ArrayList - eine Methode add bereitstellt.

Die Methode gewichtPruefen wird jetzt von Umschreiber bereitgestellt, allerdings gibt dir studentenRucksaecke.get(...) einen Integer und keinen Umschreiber.

Ich glaube, die Lösung, die du suchst, ist, die Methode gewichtPruefen statisch zu machen und den Wert von studentenRucksaecke.get(pos) als Parameter zu übergeben.
 
Erstell' dir einfach eine Klasse Rucksack, die einen Integer aufnimmt und die Methode gewichtPruefen() bereitstellt (was auch immer die macht). Dann kannst du sowas machen
Code:
studentenRucksaecke.add(new Rucksack(1));
 
Die Klasse Integer stellt keine Methode namens gewichtPruefen() zur Verfügung, daher kann das nicht funktionieren. Ich nehme an, dass ihr Objektorientierung noch nicht behandelt habt?
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben