Erweiterte Collection-Typen
Die Google Collections bieten eine Handvoll erweiterter Collection-Typen. Neben den unveränderlichen, die wir bereits gesehen haben, gibt es eine weitere interessante Kategorie - den Multimap-Typ. Eine Multimap-Implementierung erlaubt es, mehrere Werte zum selben Schlüssel abzulegen. Es ist relativ umständlich, dieses Verhalten in einer traditionellen Implementierung aus dem Java Collections Framework zu ermöglichen:
Map<String, List<String>> map = new HashMap<String, List<String>>();map.put("key1", Arrays.asList("value1", "value1.1„));map.put("key2", Arrays.asList("value2", "value2.1„));
Verwendet man Google Collections’ Multimap-Implementierung, ist das Assoziieren von mehreren Werten zu einem Schlüssel vergleichsweise einfach. Es lassen sich zudem alle Werte eines Schlüssels aus der Multimap wiederfinden und in eine handelsübliche java.util.Map zurückkonvertieren:
import static com.google.common.collect.ImmutableMultimap.of;ImmutableMultimap<String, String> map = of(“key1”, “value1”,“key1”, “value 1.1”, “key2”, “value2”, “key2”, “value2.1”);Collection<String> key1 = map.get(“key1”);Map<String, Collection<String>> traditional = map.asMap();
Diese Art von Collection könnte hilfreich sein, um beispielsweise mehrere Informationen mit einem speziellen Type zu assoziieren, ohne dabei eine zusätzliche Wrapper-Klasse einführen zu müssen. Eine Ausprägung davon sind z.B. Informationen über einen Benutzer, die zusammen auf einer Webseite angezeigt werden sollen.
Es gibt natürlich auch zu diesem Typen ein unveränderliches Gegenstück, die ImmutableMultimap. Obwohl der Name dieses Google Collection Type auf eine Map-Struktur hinweist, gibt es auch eine List- und Set-Implementierung der Multimap.
Funktionale Aspekte
Die Google-Collections-Bibliothek bringt Aspekte mit sich, die einen funktionalen Ansatz widerspiegeln. Wer beispieweise mit Groovy vertraut ist, dem sollten die folgenden Beispiele wie kalter Kaffee vorkommen. Es gibt eine Klasse, um Funktionen zu definieren, und Hilfsklassen, um traditionelle oder Google Collections anhand dieser Funktion zu transformieren:
import static com.google.common.collect.Lists.transform;List<Person> allEmployees = …;List<EmailAddress> emailList = tranform(allEmployees, emailAddressFunc);Function<Person, EmailAddress> emailAddressFunc =new Function<Person, EmailAddress>() {public EmailAddress apply(Person argEmployee) {return argEmployee.getEmailAddress();}}
Die Hilfsklasse Lists aus dem Google-Collections-Arsenal hat eine Methode namens transform. Diese erwartet eine List- und Function-Implementierung, um dann eine transformierte Sicht in Form einer List zurückzuliefern. Auch hier sind alle Akteure generisch gehalten. Function wird sowohl mit dem erwarteten Typ, als auch mit dem Rückgabewert deklariert. Der Rückgabewert ergibt auch gleichzeitig den Typ der transformierten Liste. Mit einer weiteren Hilfsklasse Ordering, kann man die transformierte Liste zudem sortieren.
Die Methode transform ist in gleicher Form durch die Hilfsklasse Maps verfügbar. Leider gibt es kein Äquivalent für Set-Implementierungen.
Eine weitere nette Hilfsklasse der Google Collections, die ein paar funktionale Aspekte für List- und Set-Implementierung mit sich bringt, ist Iterables:
import static com.google.collect.Iterables.find;List<EmailAddress> emailList = …;EmailAddress pred = new EmailAddress("linsin@synyx.de");EmailAddress emailList = find(emailList, pred);
Iterables stellt eine einfache und typsichere Suchfunktionalität zur Verfügung. Des Weiteren ermöglichen es List- oder Set-Implementierungen, anhand der Klasse Predicate zu filtern.
List<EmailAddress> synyx = filter(emailList, new Predicate<EmailAddress> {public boolean apply(EmailAddress argAddr) {return argAddr.endsWith("synyx.de");}});
Es existieren noch weitere Methoden von Iterables , die einen funktionalen Ansatz widerspiegeln. Beispielsweise gibt es die Möglichkeit, zwei oder mehrere Iterable-Implementierungen zusammenzufassen, zu teilen oder bestimmte Elemente zu entfernen.
Zusammenfassung
Die Google-Collections-Bibliothek bietet praktische Lösungen zu vielen kleinen Problemen, die Entwickler jeden Tag im Umgang mit dem Java Collections Framework begegnen. Die Lösungen, die Google dabei anbietet, sind gründlich getestet und von einer großen Entwicklergemeinde akzeptiert. Auch wenn die Google Collections kein Standard sind, ist es unwahrscheinlich, dass die Unterstützung demnächst eingestellt wird, da Google die Bibliothek in ihrer internen Codebasis ebenfalls verwenden. Mit der Veröffentlichung der finalen Version, die stabile Schnittstellen mit sich bringt, ist Google Collections bereit für geschäftskritische Applikationen.
David Linsin (linsin[at]synyx.de) arbeitet als Senior Developer und Software Architect bei der Firma Synyx GmbH & Co. KG in Karlsruhe. Er entwickelt und konzipiert dort schwerpunktmäßig Java Enterprise Applikationen. Darüber hinaus leitet er die Java User Group Karlsruhe und schreibt regelmäßig auf http://dlinsin.blogspot.com.
Links & Literatur
- http://java.sun.com/j2se/1.5.0/docs/guide/collections/
- http://code.google.com/p/google-collections
- http://jaxenter.com/Google-Collections-Library-1-0-released-10047.html
- http://github.com/dlinsin/area51/tree/master/GoogleCollectionsSample/




