Groovy Lists: Alles, was du wissen musst

Groovy verwendet die Listen aus Java, also das Interface java.util.List und die Implementierungen davon wie ArrayList. Groovy verzichtet aber in der Regel auf die Typisierung der Listen, die man in Java extra noch eingeführt hatte. Echte Erleichterung ist eine Kurzschreibweise, die es erlaubt, Listen im Programmcode einfach aufzubauen.

Die Initialisierung von Listen in Groovy

Die Kurzschreibweise zum Erstellen eines List-Objekts in Groovy sieht so aus:

def numbers = [1, 2, 3]  
def some_strings = ["foo", "bar"]

In Java gibt es keine gute Möglichkeit, ähnlich klar zu einer Liste zu kommen. Man müsste in Java schon so etwas aufbauen:

List some_strings = new ArrayList();
some_strings.add("foo");
some_strings.add("bar");

Es gibt noch ein paar Tricks, die das in Java etwas kürzer machen, aber alle sind nicht wirklich schön. Ich will sie deshalb hier auch gar nicht erst vorstellen.

Listentypen aus Groovy-Sicht

Wie eingangs schon gesagt: Groovy verwendet das Interface java.util.List und Listentypen wie java.util.ArrayList. Daran hat Groovy nicht gedreht. Aber die Möglichkeit der direkten Initialisierung ist neu.

Schauen wir uns einmal an, was Groovy aus der Listeninitialisierung macht:

def numbers = [1, 2, 3]  
print numbers.class

Die Ausgabe lautet

class java.util.ArrayList

Groovy erzeugt also eine ArrayList.

Nun gibt es abseits der ArrayList ja noch andere Listentypen in Java. ArrayList ist nur die einfachste und häufigste. Andere Möglichkeiten wären LinkedList, Stack oder Vector. Groovy erlaubt es daher in der Listeninitialisierung, den Typ der Liste anzugeben. Das geht so:

def numbers = [1, 2, 3] as LinkedList
print numbers.class

Jetzt erhalten wir:

class java.util.LinkedList

gemischte Listen

Wie in Java können Listen Elemente verschiedenster Typen aufnehmen, auch gemischt:

def gemischtwarenladen = [1, "a", true]  

Zugriff auf die Elemente einer Liste

Um an die Elemente einer Liste zu kommen, gibt es verschiedene Möglichkeiten.

Zunächst einmal geht natürlich weiterhin die getAt-Methode aus Java:

def some_strings = ["foo", "bar", "hello", "world"] 
print some_strings.getAt(2)

Mit dem Resulat „hello“. Der Grund ist: das nullte Element der Liste ist „foo“. So wie Java – und wie überhaupt die meisten Programmiersprachen – zählt Groovy die Liste angefangen mit dem nullten Element. Und wenn „foo“ das nullte Element ist, dann ist „hello“ das zweite. Das hat alles so seinen Sinn (glaub mir!), aber es bleibt ein beliebter Anfängerfehler.

Weitere Wege (die in Java so nicht gehen) sind:

Eckige Klammern:

def some_strings = ["foo", "bar", "hello", "world"] 
print some_strings[2]

Hier funktionieren auch negative Zahlen. (Das ist wohl by Python abgeschrieben, denn dort geht das auch). Die -1 indiziert das letzte Element der Liste. Die -2 das vorletzte.

def some_strings = ["foo", "bar", "hello", "world"] 
print some_strings[-1]

Die Ausgabe ist „world“.

Das geht auch mit -1 bis -4. Bei -5 erhalten wir diese Fehlermeldung:

Exception thrown

java.lang.ArrayIndexOutOfBoundsException: Negative array index [-5] too large for array size 4

weitere Elemente zur Liste hinzufügen

Nun kann man mit Listen natürlich auch arbeiten. Mal angenommen, wir wollen einen weiteren String zu unserer Sammlung hinzufügen:

def some_strings = ["foo", "bar", "hello", "world"] 
some_strings.add("more")
print some_strings

Die Ausgabe lautet:

[foo, bar, hello, world, more]

Über Java hinaus kann man das aber auch so schreiben:

def some_strings = ["foo", "bar", "hello", "world"] 
some_strings << "more"
print some_strings

Dieser Operator betrachtet (in Anlehnung an eine Stream-Syntax aus C++) das Array als einen Stream, in den man auf diese Art ein Element hineinschieben kann.

Was man sonst noch mit Listen machen kann

Groovy-Listen sind Java-Listen und können alles, was eine Java-Liste auch kann. Hier sind ein paar gängige Methoden. Achtung: die Liste ist nicht vollständig. Allein schon die Java-Liste kann noch einges mehr. Dafür möchte ich dann aber auf die offizielle Dokumentation der java.util.List verweisen.

add()fügt ein neues Element hinzu
contains()prüft, ob die Liste das angegebene Element enthält. Liefert true, falls das der Fall ist und false, falls nicht.
get()Zugriff auf ein bestimmtes Element
isEmpty()liefert true, falls die Liste leer ist. Und false, falls die Liste mindestens ein Element enthält
minus()Liefert eine neue Liste zurück die aus der ursprünglichen Liste nur noch diejenigen enthält, die abgezogen wurden
plus()liefert eine neue Liste zurück, die die Elemente beider Listen enthält
pop()entfernt das letzte Element aus der Liste
remove()entfernt das Element an der benannten Position aus der Liste
reverse()liefert eine neue Liste zurück, die genau anders herum sortiert ist
size()liefert die Anzahl der Elemente aus der Liste zurück
sort()liefert eine neue Liste zurück, die sortiert ist

Achtung: wenn es hier wiederholt heißt „liefert eine neue Liste zurück“, dann ist das genau so gemeint. Diese Methoden verändern die ursprüngliche Liste nicht. Ein Beispiel:

def some_strings = ["foo", "bar", "hello", "world"] 
println some_strings.reverse()
println some_strings

Die zwei Zeilen der Ausgabe lauten:

[world, hello, bar, foo]
[foo, bar, hello, world]

Bitte nimm dir genug Zeit, diesen Unterschied zu verstehen.

Mehr Groovy gibt es hier.

heiko

Dipl.-Ing. Heiko Evermann

Vorheriger Artikel