Sammlungsklassen
Als Sammlungsklassen bezeichnet man Klassen, die ein Behältnis für eine Anzahl von Objekten bilden. Bisher haben wir in dieser Hinsicht die Arrays kennengelernt. Alle Sammlungsklassen wurden mit Java 1.2 in das sogenannte Collections – Framework integriert, das eine Reihe von Sammlungsklassen umfasst, die jeweils für sehr spezielle Zwecke besonders geeignet sind. Wir wollen hier einige grundlegende Datenstrukturen aus diesem Framework kennenlernen, weniger spezialisiert und in vielen Fällen verwendbar sind.
Arrays sortieren
Arrays haben wir bereits kennengelernt. Sie sind ein einfach zuhandhabendes Konstrukt, haben aber zwei nicht zu vernachlässigende Nachteile: Um ein bestimmtes Objekt zu bekommen, müssen wir eine Schleife über das gesamte Array laufen lassen und jedes einzelne Objekt vergleichen, bis wir das richtige gefunden haben. Zweitens sind Arrays nicht erweiterbar, sondern haben eine feste Größe.Wenn wir ein zusätzliches Objekt anfügen wollen, müssen wir ein neues Array erzeugen.
Nützlich für den Umgang mit Arrays ist die Klasse java.util.Arrays, die eine Reihe von Komfortmethoden für die Verarbeitung von Arrays anbietet. So können wir Arrays mit bestimmten Werten füllen, sie sortieren, die equals-Methode auf sie anwenden oder ihre String-Darstellung anzeigen.
Das Beispiel zeigt das Sortieren von Arrays. Die zu sortieren Objekte, hier java.lang.Strings, haben eine „natürliche" Reihenfolge, die allerdings die Groß- und Kleinschreibung berücksichtigt. Um case-insensitive zu sortieren, könnten wir einen Comparator schreiben, der bei zwei Objekten der Klasse entscheidet, welches zuerst kommt. Dieser Comparator wird dann von der sortierenden Klasse, hier java.util.Arrays, zu Rate gezogen.
Comparator definiert int compare(Object, Object), wobei der Rückgabewert anzeigt, ob Objekt eins größer(Rückgabewert ist größer Null), gleich (Rückgabeist Null) oder kleiner als Objekt zwei (Rückgabewert ist kleiner Null) sein soll. Die Höhe des Rückgabewertes hat keine Bedeutung.
- Neben dem Comparator sein noch auf das Interface java.lang.Comparable hingewiesen, das eine ähnliche Funktion erfüllt. Es wird von Datenobjekten implementiert, wenn diese eine „natürliche“ Reihenfolge anbieten. So implementiert java.lang.String ebenfalls Comparable#compareTo(Object). Die hier erzeugte Reihenfolge kommt zum Tragen, wenn wir die Sortierung wie im ersten Fall ohne Angabe eines Comparators durchführen.
Vektor
Ein java.util.Vector ist ein Container, der beliebig viele Datenaufnehmen kann. Er erweitert seine Kapazität bei Bedarf selbständig. Da alle Operationen auf java.lang.Object basieren, können im Prinzip auch Objekte unterschiedlicher Klassen verwendet werden. Casten ist stets erforderlich.
Das Beispiel zeigt die Verwendung von Vector:
Man erkennt, daß der Vector im Gegensatz zum Array eine schöne Druckdarstellung besitzt. Um alle Elemente eines Vektors nacheinander zu bekommen, lässt man sich vom Vector einen java.util.Iterator geben; den selben Zweck erfüllt die ältere Klasse java.util.Enumeration.
Hashtable und Properties
Java.util.Hashtable bietet eine Key->Value Struktur an, also eine Art benanntes Array. Keys und Values müssen Objekte sein, ein doppelter Key überschreibt seinen Vorgänger. Mit Hashtable#put(Key,Value) können Elemente hinzugefügt werden,auf die dann über den Schlüssel zugegriffen werden kann: Value=Hashtable#get(Key). Alle Keys kann man mit Hashtable#keys() bekommen.
Java.util.Properties ist eine spezielle Hashtable, die als Keys und Values nur Strings zulassen. Sie besitzen die spezialisierten Methoden setProperty(String key, String value) und String getProperty(String key), die einem das Casten ersparen.
Properties können sich selbst aus einem Stream lesen oder in einen Stream schreiben; der Stream kann dann beispielsweise in eine Datei geführt werden, vergleichen Sie dazu bitte das Kapitel über Streams. Properties sind daher extrem nützlich, wenn es darum geht, Programmkonfigurationswerte zu speichern.
Bitte beachten Sie das Beispiel Env.java für den Umgang mit Hashtable und Properties.