Das Gemüse fehlt!
Erinnerst du dich noch an das leckere Rezept? Nudeln mit Thunfisch und Oliven?
Inzwischen haben wir ja mit dem EinkaufHelper eine Klasse, die Interaktivität hinzufügt, aber der Einkaufszettel selbst ließe sich auch noch verbessern. Zeit für ein neues Feature!
Um nur den Einkaufszettel zu testen solltest du eine neue Datei TestEinkaufszettel im selben Workspace, in dem auch deine Einkaufszettel-Klasse liegt, anlegen. Darein kommt erst einmal der Code, den wir ursprünglich für das Starten des Einkaufszettels geschrieben hatten:
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.druckeNummerierteListe();
Läuft das soweit?
Liegt die Klasse Einkaufszettel
auch wirklich im gleichen Workspace?
Dann wird das der Grund gewesen sein. Sorge dafür, dass die Klasse, so wie wir sie in den letzten Kapiteln angelegt hatten, im selben Workspace liegt. Ansonsten ist sie für unser Testskript nicht sichtbar.
Ist der Einkaufszettel auch auf dem aktuellen Stand und zeigt keine Fehler an?
Dann müsste das Testskript eigentlich funktionieren… falls du den Fehler nicht noch selbst findest, bitte jemanden um Hilfe!
Lies die Fehlermeldungen genau, und versuche, alle Fehler zu beheben. Falls du irgendwo hängen bleibst, bitte jemanden um Hilfe.
Du solltest also folgende Ausgabe angezeigt bekommen:
0: Spaghetti
1: Oliven, schwarz, entsteint
2: Thunfisch in Olivenöl
Stell dir vor, deine Familie bekommt mit, dass du einkaufen gehst. Dein Vater bittet dich, ihm Bananen fürs Müsli mitzubringen…
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.einkaufHinzufügen("Bananen");
e.druckeNummerierteListe();
Deine Schwester braucht neue Zahncreme…
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.einkaufHinzufügen("Bananen");
e.einkaufHinzufügen("Zahncreme");
e.druckeNummerierteListe();
Und deine Mutter bittet dich, ihr die neue Ausgabe von »The complete Java Developer« mitzubringen.
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.einkaufHinzufügen("Bananen");
e.einkaufHinzufügen("Zahncreme");
e.einkaufHinzufügen("The complete Java Developer");
e.druckeNummerierteListe();
Außerdem fällt dir ein, dass es total lecker wäre, der Thunfisch-Oliven-Sauce noch gelbe Paprika hinzuzufügen…
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.einkaufHinzufügen("Bananen");
e.einkaufHinzufügen("Zahncreme");
e.einkaufHinzufügen("The complete Java Developer");
e.einkaufHinzufügen("gelbe Paprika");
e.druckeNummerierteListe();
Siehst du, welches Problem wir gerade erzeugen?
Genau!
Der Einkaufszettel ist nicht topologisch sortiert!
Wenn du einen Supermarkt betrittst, stehst du üblicherweise in der Obst- und Gemüseabteilung. Wenn du weitergehst, kommt vielleicht die Marmeladen- und Müsli-Abteilung, dann Milchprodukte, und so weiter. Einem ordentlichen (d.h. topologisch sortierten 😉) Einkaufszettel kannst du beim Einkaufen folgen, und du kommst in der Reihenfolge an den Produkten vorbei, in der sie auf dem Zettel stehen.
Das wäre natürlich das einfachste. Aber so einfach ist die Welt nicht immer… wir brauchen also ein Feature, mit dem wir unseren Einkaufszettel umsortieren können – cool wäre es z.B., wenn wir zwei Artikel einfach vertauschen könnten.
Erinnerst du dich noch an den Index?
Genau den! Damit lässt sich noch einiges anfangen! Unsere Einkaufszettel-Implementierung gibt ja bereits jetzt den Index mit aus – intern wird mit einkauf.get(i)
das Listenelement an der Position i
ausgegeben. Auf ähnliche Weise lässt sich auch etwas in die Liste hineinschreiben. Was würde diese Zeile bewirken, wenn sie auf die Liste ["Spaghetti", "Oliven", "Thunfisch", "Bananen", …]
im Einkaufszettelobjekt angewendet würde?
einkauf.set(3, "Äpfel");
Wird…
Das ist leider nicht richtig.
Das ist leider nicht richtig.
Das stimmt!
Das ist leider nicht richtig.
An der Indexposition 3 werden die Bananen durch die Äpfel ersetzt. (Die Bananen sind das vierte Element auf der Liste, haben aber den Index drei, weil wir bei null anfangen zu zählen…)
Bevor du nun in der Einkaufszettel-Klasse eine neue Methode tauschePositionen
programmierst, versuche dich an folgender
Übung
Kann es losgehen?
Hier ist ein Skript, in dem die Zeilen durcheinander geraten sind. Kopiere dir diese Zeilen in eine neue Datei in der Online-IDE:
sam.set(3, "Fail better");
sam.add("Fail");
ArrayList<String> sam = new ArrayList<>();
sam.set(2, sam.get(0) + " again");
sam.add("Give up");
println(sam);
sam.add("Go home");
sam.add("Try");
Sortiere die Zeilen nun so um, dass diese Ausgabe herauskommt, wenn du das Skript ausführst:
[Try, Fail, Try again, Fail better]
Brauchst du noch einen Sortier-Tipp, der deine Coding-Coolness um mindestens 42% steigert?
In jedem anständigen Code-Editor gibt es eine Tastenkombination, um Zeilen zu vertauschen. In der Online-IDE geht das mit Alt+↓ oder Alt+↑. Versuch es einmal!
Lass dein Skript laufen, und vergleiche deine Ausgabe mit der Vorgabe. Sieh’ dir die Lösung erst an, wenn du selbst darauf gekommen bist oder du wirklich nicht mehr weiter weißt.
ArrayList<String> sam = new ArrayList<>();
sam.add("Try");
sam.add("Fail");
sam.add("Give up");
sam.add("Go home");
sam.set(2, sam.get(0) + " again");
sam.set(3, "Fail better");
println(sam);
So kommt die korrekte Ausgabe heraus.
Genau! Nun wirst du dein neu erworbenes Wissen dazu einsetzen, eine Methode zu schreiben, die ganz allgemein Artikel in unserem Einkaufszettel tauschen kann.
Wechsle zur Klasse Einkaufszettel, und füge innerhalb der Klasse diesen Methodenkopf hinzu:
public void tauscheArtikel(int indexA, int indexB) {
}
Überlege nun, wie sich ein Element gegen ein anderes tauschen lässt!
Sehr schön!
Gerne! Erinnerst du dich noch an die Zeile sam.set(2, sam.get(0) + " again");
aus der Übung? Was passierte da genau?
Das stimmt teilweise, aber die Elemente werden nicht vertauscht!
Um zu verstehen, was passiert, ist es gut, innerhalb der Klammern mit dem Lesen anzufangen.
Genau! Die-set
-Methode hat zwei Parameter. Das erste Argument, das übergeben wird, ist der Index, an dem etwas geschrieben wird – hier Index 2, also das dritte Element. Das zweite Argument ist das, was geschrieben wird, hier der Ausdruck sam.get(0) + " again"
.
So ist es. Mit sam.get(0)
bekommen wir das erste Element (Index 0) der Liste – das ist irgendeine Zeichenkette (ein String
). Das +
verbindet diese Zeichenkette mit der Zeichenkette " again"
.
Das wäre merkwürdig, denn die Methode heißt ja lediglich set
.
So ist es! Innerhalb der äußeren Klammer steht der Index 2 und irgendeine zusammengesetzte Zeichenkette, und das bedeutet, dass diese auf dem dritten Listenplatz (Index 2) abgespeichert wird.
Das stimmt nicht ganz – es passiert noch etwas mehr.
Um zu verstehen, was passiert, ist es gut, innerhalb der Klammern mit dem Lesen anzufangen.
Genau! Die-set
-Methode hat zwei Parameter. Das erste Argument, das übergeben wird, ist der Index, an dem etwas geschrieben wird – hier Index 2, also das dritte Element. Das zweite Argument ist das, was geschrieben wird, hier der Ausdruck sam.get(0) + " again"
.
Mit sam.get(0)
bekommen wir das erste Element (Index 0) der Liste – das ist irgendeine Zeichenkette (ein String
). Das +
verbindet diese Zeichenkette mit der Zeichenkette " again"
.
So ist es! Innerhalb der äußeren Klammer steht der Index 2 und irgendeine zusammengesetzte Zeichenkette, und das bedeutet, dass diese auf dem dritten Listenplatz (Index 2) abgespeichert wird.
Gut erkannt, genau so ist es!
Das stimmt leider nicht.
Um zu verstehen, was passiert, ist es gut, innerhalb der Klammern mit dem Lesen anzufangen.
Genau! Die-set
-Methode hat zwei Parameter. Das erste Argument, das übergeben wird, ist der Index, an dem etwas geschrieben wird – hier Index 2, also das dritte Element. Das zweite Argument ist das, was geschrieben wird, hier der Ausdruck sam.get(0) + " again"
.
Mit sam.get(0)
bekommen wir das erste Element (Index 0) der Liste – das ist irgendeine Zeichenkette (ein String
). Das +
verbindet diese Zeichenkette mit der Zeichenkette " again"
.
Das wäre merkwürdig, denn die Methode heißt ja lediglich set
.
So ist es! Innerhalb der äußeren Klammer steht der Index 2 und irgendeine zusammengesetzte Zeichenkette, und das bedeutet, dass diese auf dem dritten Listenplatz (Index 2) abgespeichert wird.
Nun aber zurück zur tauscheArtikel
-Methode. Was wäre mit einer Implementierung wie dieser:
public void tauscheArtikel(int indexA, int indexB) {
this.einkauf.set(indexA, this,einkauf.get(IndexB));
this.einkauf.set(indexB, this,einkauf.get(IndexA));
}
Würde der Tausch hier funktionieren?
Leider stimmt das nicht…
Gut erkannt!
Er würde nicht funktionieren! Nach der ersten Zeile (this.einkauf.set(…
) wäre unter IndexA
das Element von IndexB
abgespeichert, aber unter IndexB
wäre dies ebenfalls der Fall! Das Element, das vorher unter IndexA
zu finden war, wäre nun verloren!
Das ist es! Der Zwischenspeicher könnte vielleicht so aussehen:
public void tauscheArtikel(int indexA, int indexB) {
String zwischenspeicherArtikelA = this.einkauf.get(indexA);
}
Versuche nun den Rest der Methode alleine!
Test deine Methode selbst, in dem du sie in der Datei TestEinkaufszettel aufrufst. Wenn du zufrieden bist (oder nicht weiter weißt), sieh’ dir den Lösungsvorschlag an.
public void tauscheArtikel(int indexA, int indexB) {
String zwischenspeicherArtikelA = this.einkauf.get(indexA);
this.einkauf.set(indexA, this.einkauf.get(indexB));
this.einkauf.set(indexB, zwischenspeicherArtikelA);
}
Falls noch nicht geschehen, sollten wir die Methode testen! Wechsle zur Datei TestEinkaufszettel, und sortiere die Liste mit Hilfe unserer neuen Methode so um, dass die Bananen und die gelbe Paprika ganz vorne stehen:
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.einkaufHinzufügen("Bananen");
e.einkaufHinzufügen("Zahncreme");
e.einkaufHinzufügen("The complete Java Developer");
e.einkaufHinzufügen("gelbe Paprika");
e.druckeNummerierteListe();
// An dieser Stelle sollst du unsere neue Methode aufrufen!
Wenn du fertig bist, lass das Testskript laufen. Vergleiche es dann auch mit dem Lösungsvorschlag.
Eine mögliche Lösung könnte so aussehen:
Einkaufszettel e = new Einkaufszettel();
e.einkaufHinzufügen("Spaghetti");
e.einkaufHinzufügen("Oliven, schwarz, entsteint");
e.einkaufHinzufügen("Thunfisch in Olivenöl");
e.einkaufHinzufügen("Bananen");
e.einkaufHinzufügen("Zahncreme");
e.einkaufHinzufügen("The complete Java Developer");
e.einkaufHinzufügen("gelbe Paprika");
e.druckeNummerierteListe();
// An dieser Stelle sollst du unsere neue Methode aufrufen!
e.tauscheArtikel(0, 3);
e.tauscheArtikel(1, 6);
// Wir sehen, ob nun alle Artikel in der richtigen Reihenfolge stehen:
e.druckeNummerierteListe();
Neue Vokabeln in dieser Lektion
Schreibe den entsprechenden Code auf, und überprüfe, ob du richtig liegst!
Das erste Element einer bereits vorhandenen Liste meineBücher
auf »The Art of Programming« setzen.
meineListe.set(0, "The Art of Programming");
Das vierte Element einer bereits vorhandenen Liste meineFilme
auf »The Imitation Game« setzen.
meineFilme.set(3, "The Imitation Game");
Das letzte Element einer bereits vorhandenen Liste meineBücher
auf »The Hitchhiker’s Guide to the Galaxy« setzen.
meineListe.set(meineListe.size() - 1, "The Hitchhiker’s Guide to the Galaxy");