© Excellent backgrounds/Shutterstock.com
Kolumne: Java-Trickkiste

Listen ohne Seiteneffekte


Letzten Monat haben wir seiteneffektfreies Programmieren betrachtet, was in Java im Wesentlichen Klassen bedeutet, bei denen alle Attribute final sind. Das hat den Vorteil, dass man Objekte herumreichen kann, ohne sich Gedanken machen zu müssen, wer sie verändern könnte – kurzum, es hilft dabei, robusten Code zu schreiben.

Wenn man ein Objekt „verändert“, erzeugt man eine Kopie mit dem veränderten Inhalt (Listing 1). Eine Bestellposition hat final-Felder für den Artikel und die bestellte Anzahl an Exemplaren des Artikels. Beide werden beim Erzeugen initialisiert.

Zum nachträglichen Ändern der bestellten Anzahl gibt es eine Methode mitAnzahl(). Die erzeugt ein neues BestellPos-Objekt mit geänderter Anzahl, während das Original unverändert bleibt.

Listing 1

public cllPos { private final String artikel; private final int anzahl; public BestellPos (String artikel, int anzahl) { this.artikel = artikel; this.anzahl = anzahl; } public BestellPos mitAnzahl (int neueAnzahl) { return new BestellPos (artikel, neueAnzahl); } public String getArtikel () { return artikel; } public int getAnzahl () { return anzahl; } }

Unveränderliche Collections ...

Man kann auch eine ganze Bestellung mit einer Liste von Positionen in einer unveränderlichen Datenstruktur ablegen (Listing 2). Dabei landen die Positionen in einem AHashSet – das ist eine unveränderliche Setimplementierung aus der Open-Source-Bibliothek a-foundation, die u. a. die wichtigsten Scala-Collection-Klassen nach Java portiert [1]. Das Interface ASet kapselt dabei die konkrete Klasse.

Listing 2

public class Bestellung { private final String bestellNr; private final ASet<BestellPos> positionen; public Bestellung (String bestellNr, Iterable<BestellPos> positionen) { this.bestellNr = bestellNr; this.positionen = AHashSet.create (positionen); } public String getBestellNr () { return bestellNr; } public ASet<BestellPos> getPositionen () { return positionen; } public String asString() { return "Bestellung " + bestellNr + ":\n" + positionen .map (b -> b.getAnzahl () + "x " + b.getArtikel ()) .mkString("\n"); } public int getGesamtAnzahl() { return positionen.foldLeft (0, (r, b) -> r + b.getAnzahl ()); } public Bestellung mitNeuerAnzahl (BestellPos pos, int neueAnzahl) { return new Bestellung (bestellNr, positionen.map (b -> b != pos ? b : b.mitAnzahl (neueAnzahl))); } public Bestellung addPos (BestellPos pos) { ASet<BestellPos> neueListe = positionen.added (pos); return new Bestellung (bestellNr, neueListe); } public ...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang