Logo Wissenstransfer Gerhard at CichnaDotCom

>> Wissensdatenbank / Objektorientiertes Programmieren

Zeichenketten und Calendar

Zeichenketten

Zeichenketten gehören zu den am häufigsten verwendeten Datentypen in jeder Programmiersprache. Ihr Einsatzgebiet reicht von der Eingabe einzelner Werte über die Kommandozeile bis zur plattformunabhängigen Datenübermittlung zwischen verteilten Systemen. Anders als Wahrheitswerte und Zahlen gehören Zeichenketten nicht direkt zu den primitiven Datentypen. Da sie aber so essenziell für jegliche Datenverarbeitung im modernen Sinn sind, bietet Java einiges an, um eine besonders komfortable Verarbeitung zu ermöglichen.

Zeichenketten sind in Java Instanzen der Klasse java.lang.String. Es gibt verschiedene Wege, sie zu erzeugen. Zum einen gibt es die Literal-Schreibweise, die es ermöglicht, einen String als einen Wert, ähnlich wie eine Zahl oder einen Wahrheitswert, hinzuschreiben.
Literal-Schreibweise für Strings

Des Weiteren ist in Java der Plus-Operator für Zeichenketten definiert. So können Strings mit anderen Strings und primitiven Werten verknüpft werden.
Plus-Operator für Strings

Die Klasse "String" stellt mehrere Konstruktoren zur Verfügung, mit denen sich String-Instanzen erzeugen lassen. So gibt es den parameterlosen Konstruktor, der eine Instanz erzeugt, die einen leeren String repräsentiert. Der Copy-Konstruktor erzeugt eine Kopie eines übergebenen Strings. Es ist ebenfalls möglich, eine String-Instanz aus einem Char- oder Byte-Array von Bytes zu erzeugen.
Konstruktoren Strings

Es stehen allerdings keine Konstruktoren für die Erzeugung von Strings aus Wahrheitswerten oder Zahlen zur Verfügung. An dieser Stelle gibt es zwei Möglichkeiten: Zum einen kann man den jeweiligen primitiven Wert mit einem Leerstring verketten, um durch die implizite Konvertierung eine String-Repräsentation zu erhalten. Zum anderen definiert die Klasse "String" die statische Methode valueOf, die für alle primitiven Datentypen überladen ist und deren Werte als Zeichenkette interpretiert zurückgibt.
Umwandlung von primitive Datentypen in Strings

Oft kommt es aber vor, dass man auf den umgekehrten Fall stößt. Man hat einen String, der einen Wert darstellt (zum Beispiel "12.45"), und möchte mit dieser Zahl weiterrechnen. Dafür muss aus dem String aber erst wieder eine gültige Zahl gemacht werden. Für die Umwandlung von String-Repräsentationen in echte Werte verwendet man die statischen Methoden der Wrapper-Klassen für die primitiven Datentypen: Boolean, Byte, Short, Integer, Float und Double. Dabei ist es zwingend erforderlich, dass der eingelesene String ein gültiges Format besitzt, ansonsten wird bei der Umwandlung eine NumberFormatException geworfen.
Umwandlung von Strings in primitive Datentypen

Die Instanzen der Klasse "String" bieten einige Instanzmethoden an, mit denen man den Inhalt der Strings analysieren und verarbeiten kann.

Methoden für Teilstring-Vergleiche Beschreibung
boolean contains(String s) Gibt true zurück, wenn der String den Teilstring im Parameter s enthält,
ansonsten false.
boolean startsWith(String prefix) Gibt true zurück, falls der String mit dem String im Parameter prefix beginnt,
ansonsten false.
boolean endsWith(String suffix) Gibt true zurück, falls der String mit dem String im Parameter suffix endet,
ansonsten false.
int indexOf(char c)
int indexOf(String s)
Gibt die Stelle im String zurück, an der das Zeichen bzw. der String im Parameter
zum ersten Mal auftaucht. Gibt -1 zurück, falls das Zeichen bzw. der String nicht
auftaucht.
int lastIndexOf(char c)
int lastIndexOf(String s)
Gibt die Stelle im String zurück, an der das Zeichen bzw. der String im Parameter
zum letzten Mal auftaucht. Gibt -1 zurück, falls das Zeichen bzw. der String nicht
vorkommt.

Beispiele für Teilstring-Vergleiche:
Teilstring-Vergleich

Neben der Frage nach der bloßen Existenz eines Teilstrings kann auch nach der Position der Teilstrings in einem gegebenen String gefragt werden. Die Methode indexOf liefert die Position des ersten Auftretens eines bestimmten Strings zurück, während die Methode lastIndexOf die Position des letzten Auftretens liefert.
Teilstring-Positionen

Die Klasse "String" stellt einige Methoden bereit, um Zeichenketten zu manipulieren.

Methoden für die Maipulation von Strings Beschreibung
char charAt(int index) Gibt das Zeichen an der durch index bezeichneten Stelle im String zurück.
String substring(int anfang, int ende) Gibt den Teilstring zwischen der Stelle anfang (einschließlich) und ende (ausschließlich)
zurück.
String replace(char alt, char neu)
String replace(String alt, String neu)
Gibt einen String zurück, in dem alle Vorkommnisse des Zeichens bzw. der Zeichenkette
alt durch das Zeichen bzw. die Zeichenkette neu ersetzt wurden.
String toLowerCase() Gibt einen String zurück, in dem alle Zeichen des Originalstrings klein geschrieben sind.
String toUpperCase() Gibt einen String zurück, in dem alle Zeichen des Originalstrings groß geschrieben sind.
String trim() Gibt einen String zurück, bei dem alle nicht-druckbaren Zeichen (Leerzeichen, Umbrüche,
Tabulatoren etc.) am Anfang und am Ende des Originalstrings entfernt wurden.

Teilstring extrahieren

Mit der Methode replace können alle Vorkommnisse eines Zeichens bzw. einer Zeichenkette durch ein neues Zeichen bzw. eine neue Zeichenkette ersetzt werden.
Teilstring ersetzen

Diese Methode verändert den ursprünglichen Wert nicht, sondern gibt einen neuen String zurück, denn Strings sind in Java unveränderlich. Es ist nicht möglich einen String direkt zu manipulieren, alle verändernden Methoden liefern immer ein neues String-Objekt zurück. Strings sind echte Objekte, deren interner Zustand (die einzelnen Zeichen, aus denen sie bestehen) aber nicht mehr geändert werden kann.

Da Strings echte Objekte sind, verwendet man zum Vergleichen von Strings die Methoden equals und compareTo. Die Methode equals gibt true zurück, wenn zwei Strings exakt dieselben Zeichen in derselben Reihefolge enthalten. Dabei wird auch auf Groß- und Kleinschreibung geachtet. Eine Variante der equals-Methode, equalsIgnoreCase, vergleicht hingegen nur die Reihefolge der Buchstaben, unabhängig von deren Groß- und Kleinschreibung.
Anwendung der Methode equalsIgnoreCase

Die Methode compareTo der Klasse "String" vergleicht zwei Strings anhand ihrer lexikografischen Ordnung. Das funktioniert wie bei der Sortierung im Telefonbuch, wo ein Name vor einer Person eingeordnet wird, wenn dieser mit einem Buchstaben anfängt, der früher im Alphbet auftaucht. Auch hier gibt es wieder eine Variante der Methode, die die Groß-/Kleinschreibung ignoriert.
Anwendung der Methode compareToIgnoreCase

Zeichenketten sind ein vielseitiger Datentyp; so gut wie alle Informationen lassen sich als Text ausdrücken. Gerade für die Übertragung von Informationen werden häufig Textdaten verwendet, der größte Teil des Internets basiert auf der Übertragung von Seiteninhalten mittels eines Textformats (HTML). Zeichenketten haben in Java einen besonderen Stellenwert und bieten einen reichhaltigen Methodenvorrat für die Verarbeitung an.

StringBuffer

Strings sind in Java unveränderlich und jede Veränderung erfordert die Erzeugung eines neuen String-Objektes. Das gilt besonders für die Verkettung von Strings. Bei einer String-Verkettung werden zusätzliche temporäre String-Objekte erzeugt, eines für jede Verkettungoperation.
Temporäre Objekte beim Verketten von Strings

Die zusätzlich erzeugten Strings sind nur kurzlebige Objekte, belegen aber trotzdem Speicherplatz und müssen irgendwann vom Laufzeitsystem gelöscht werden. Mit steigender Länge der verketteten Strings und Anzahl an Verkettungsoperationen wächst auch der Speicherverbrauch. Die Erzeugung der temporären Strings lässt sich nicht verhindern, denn sie ist eine Konsequenz der Tatsache, dass Strings in Java unveränderlich sind.

Für die Verkettung von vielen langen Strings stellt die Java-Klassenbibliothek die Klasse "StringBuffer" zur Verfügung. An eine Instanz der Klasse "StringBuffer" können mittels der Methode append beliebig viele Strings angefügt werden, ohne dass unnötig zusätzliche Objekte erzeugt werden. Die hinzugefügten Strings werden in einem temporären Puffer gehalten und erst beim Aufrufen der toString-Methode wird der resultierende String zusammengebaut.
StringBuffer
Auf diese Weise können auch große Textmengen, zum Beispiel für die automatische Generierung von HTML-Quelltext einer Webseite, performant erzeugt werden.

Aufteilen von Zeichenketten

Ein relativ einfaches Format zur Repr&aml;sentation von Daten in Dateien ist das CSV-Format ("Comma-Separated Values"). Attribute im CSV-Format sind mit einem Komma voneinander getrennt.
Beispiel einer CSV-Datei:
'bah90131','Titel 1','Hersteller 1','12,56'
'bah90256','Titel 2','Hersteller 1','45,26'
'bah90556','Titel 3','Hersteller 1','5,22'

Die Methode split teilt einen String anhand einer Trennzeichenkette auf und gibt die einzelnen Teile als einen Array von Strings zurück.
Vewendung der Methode split

Mittels split ist es relativ einfach, strukturierte Zeichenketten aufzuteilen und Informationen zu entnehmen. Die Verarbeitung ist natürlich sehr stark darauf angewiesen, dass die Struktur stets eingehalten wird. Außerdem müssen alle Werte auch immer in der richtigen Reihenfolge in der Zeile stehen, damit sie den richtigen Variablen zugewiesen werden.

Datum und Uhrzeit

Die grundlegendste Klasse zur Repräsentation von Datumsangaben ist die Klasse "java.util.Date". Objekte der Klasse "Date" stellen einen Zeitpunkt dar. Das bedeutet, sie umfassen sowohl ein Datum (z.B. 24.12.2013) als auch einen genauen Zeitpunkt an diesem Datum (z.B. 17:45 Uhr und 15,1235 Sekunden). Die kleinste Auflösung des Zeitpunkts sind Millisekunden.

Der Default-Konstruktor der Klasse "Date" erzeugt ein Objekt, das den genauen Zeitpunkt seiner Erzeugung repräsentiert. Es existieren überladene Kontruktoren, mit denen sich die einzelnen Attribute eines Datums (Tag, Monat, Jahr, Stunde etc.) gezielt setzen lassen. Die Millisekunden lassen sich weder per Konstruktor noch per Setter setzen.
Erzeugung von Date-Instanzen

Date-Objekte bieten nicht viele Methoden an. Man kann sie miteinander vergleichen und dafür entweder die bekannte compareTo-Methode oder die komfortableren Methoden before und after verwenden, um zu entscheiden, wie zwei Datumsangaben zueinander in Relation stehen. Darüber hinaus kann man einzelne Werte eines Datums mit den entsprechenden Setter-Methoden setzen, diese sind jedoch als deprecated, also veraltet, markiert.
Standardformatierung bei der Ausgabe von Date-Objekten

In Java wird das formatierte Ausgeben und Einlesen eines Datums über die Klasse "java.tex.SimpleDateFormat" ermöglicht. Ein SimpleDateFormat formatiert ein Datum anhand eines Musters, mit dem der Benutzer genau angeben kann, wie ein Datum als String dargestellt werden soll: Reihenfolge der Attribute, Trennzeichen zwischen Attributen etc.

Im folgenden Beispiel wird ein SimpleDateFormat-Objekt mit einem Muster für die deutsche Formatierung von Datumsangaben erzeugt. Die Buchstaben in dem Muster stehen dabei für die Attribute des Datums und geben an, wie viele Stellen jeweils für die Ausgabe verwendet werden dürfen. Die vier y sagen aus, dass das Jahr-Attribut des Datums mit maximal vier Stellen ausgegeben werden soll. Die Buchstaben M und d stehen für das Monats- bzw. das Tages-Attribut des Datums. Die Punkte stehen nicht für ein bestimmtes Attribut und werden deswegen einfach in der Ausgabe wiederholt.
SimpleDateFormat
Für die Definition des Formatierungsmusters stehen einige spezielle Buchstaben zur Verfügung, die komplette Liste lässt sich in der Java-Dokumentation nachschlagen.
SimpleDateFormat in Java Doc

Neben der formatierten Ausgabe ist mit der Klasse "SimpleDateFormat" auch das Einlesen von Datumsangaben und deren Umwandlung in echte Date-Objekte möglich. Dafür verwendet man anstelle der format-Methode eines SimpleDateFormat-Objektes dessen parse-Methode.
parse-Methode von SimpleDateFormat

Beim Aufruf der Methode parse können ParseExceptions auftreten, falls die übergebene Zeichenkette nicht das in der SimpleDateFormat-Instanz angegebene Format hat.

Bestimmte Muster einzelner Datumsformate sind bereits vordefiniert, sodass man auch ohne die explizite Angabe eines Musters auf sie zugreifen kann. Die Muster sind in der Klasse "DateFormat" (Oberklasse von "SimpleDateFormat") definiert und können über eine statische Methode und die Angabe entsprechender Konstanten erreicht werden. Für die Formatierung von Datumsangaben, Zeitpunktangaben und der Kombination aus beiden stehen entsprechende DateFormat-Instanzen zur Verfügung, auf die über die jeweiligen Methoden getDateInstance, getTimeInstance und getDateTimeInstance zugegriffen werden kann. Jeder Aufruf der Methoden nimmt einen weiteren Parameter entgegen, der die Ausführlichkeit der Formatierung einstellt.
DateFormat

Kalender

Java bietet mit der Klasse "java.util.Calendar" eine abstrakte Klasse für die Darstellung von Datumsangaben in beliebigen Kalendersystemen an. Im europäischen Raum wird der Gregorianische Kalender verwendet. Deswegen steht in der Java-Klassenbibliothek auch eine entsprechende Klasse zur Verfügung, die von "java.util.Calendar" ableitet und diesen Kalender implementiert: "java.util.GregorianCalendar".

Die Verwendung von GregorianCalendar ähnelt der von Date. Bei der Instanziierung erhält man ein Objekt, das den Zeitpunkt der Erstellung repräsentiert. Wie auch bei Date stehen weitere Konstruktoren zur Verfügung, mit denen sich bestimmte Attribute setzen lassen.
GregorianCalendar-Objekte

Das Setzen einzelner Attribute funktioniert allerdings viel allgemeiner als bei Date-Objekten. Das liegt daran, dass die GregorianCalendar-Klasse wesentlich mehr Attribute als die Date-Klasse zur Verfügung stellt. Der erste Parameter der set-Methode bestimmt, welches Attribut verändert wird. Die setzbaren Attribute sind als Klassenkonstanten in der Oberklasse "Calendar" definiert. Der zweite Parameter liefert den neuen Wert des Attributs. Auch hier sind für einige Werte schon Konstanten in der Klasse "Calendar" vordefiniert, zum Beispiel für die Angabe von Wochentagen oder Monaten.
Attribute von GregorianCalendar-Objekten

Für das Abfragen von Attributen existiert eine allgemeine get-Methode, die ähnlich wie die set-Methode funktioniert. Man verwendet dieselben Konstanten, um den Wert eines Attributs abzufragen.
Attribute von GregorianCalendar-Objekten abfragen

Zu den wichtigsten Methoden eines GregorianCalendar-Objektes gehört die Methode roll, mit der einzelne Attribute (Jahre, Monate, Tage, Stunden,...) einfach weitergeschaltet werden können. Die roll-Methode funktioniert ebenfalls wie die set- und die get-Methode. Man gibt das Attribut, das weitergeschaltet werden soll, als ersten Parameter an und im zweiten Parameter wird angegeben, wie oft das Attribut weitergeschaltet werden soll. Positive Zahlen schalten das Attribut weiter, negative Zahlen schalten es zurück.
Methode roll von GregorianCalendar

Schlussendlich ist es auch immer möglich, mittels der getTime-Methode ein "normales" Date-Objekt aus einem GregorianCalendar zu bekommen, um es zum Beispiel mittels SimpleDateFormat zu formatieren.