Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

 << zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren für die Java 2-Plattform in der Version 5
Java ist auch eine Insel

Java ist auch eine Insel
5., akt. und erw. Auflage
1454 S., mit CD, 49,90 Euro
Galileo Computing
ISBN 3-89842-747-1
gp Kapitel 4 Der Umgang mit Zeichenketten
  gp 4.1 Strings und deren Anwendung
    gp 4.1.1 String-Literale als String-Objekte für konstante Zeichenketten
    gp 4.1.2 String-Objekte neu anlegen
    gp 4.1.3 String-Länge
    gp 4.1.4 Gut, dass wir verglichen haben
    gp 4.1.5 String-Teile extrahieren
    gp 4.1.6 Suchen und Ersetzen
    gp 4.1.7 Veränderte Strings liefern
    gp 4.1.8 Unterschiedliche Typen in Zeichenketten konvertieren
  gp 4.2 Veränderbare Zeichenketten mit StringBuffer/StringBuilder
    gp 4.2.1 Anlegen von StringBuffer/StringBuilder-Objekten
    gp 4.2.2 Die Länge eines StringBuffer/Builder-Objekts lesen und setzen
    gp 4.2.3 Daten anhängen
    gp 4.2.4 Zeichen(folgen) setzen, erfragen, löschen und umdrehen
  gp 4.3 Vergleiche von Zeichenketten
    gp 4.3.1 equals() in String und StringBuffer/StringBuilder
    gp 4.3.2 equals() und hashCode() bei StringBuffer/StringBuilder
    gp 4.3.3 Sprachabhängiges Vergleichen mit der Collator-Klasse
    gp 4.3.4 Effiziente interne Speicherung für die Sortierung
  gp 4.4 Reguläre Ausdrücke
    gp 4.4.1 Die Klassen Pattern und Matcher
    gp 4.4.2 Mit MatchResult alle Ergebnisse einsammeln
    gp 4.4.3 Das alternative Paket org.apache.regexp
  gp 4.5 Zerlegen von Zeichenketten
    gp 4.5.1 Splitten von Zeichenketten mit split() aus Pattern
    gp 4.5.2 split() in String
    gp 4.5.3 Die Klasse Scanner
    gp 4.5.4 StringTokenizer
    gp 4.5.5 Der BreakIterator als Wort- und Satztrenner
  gp 4.6 Zeichenkodierungen
    gp 4.6.1 Kodierungen für unterschiedliche Codepages
    gp 4.6.2 Andere Klassen zur Konvertierung und das Paket java.nio.charset
    gp 4.6.3 Base64-Kodierung
  gp 4.7 Formatieren von Ausgaben
    gp 4.7.1 Zahlen, Prozente und Währungen mit NumberFormat formatieren
    gp 4.7.2 Dezimalzahlformatierung mit DecimalFormat
    gp 4.7.3 Formatieren mit format() aus String
    gp 4.7.4 Ausgaben formatieren mit MessageFormat


Galileo Computing

4.7 Formatieren von Ausgabedowntop

Zahlen, Datumsangaben und Text können auf verschiedenste Art und Weise formatiert werden. Dabei unterscheiden sich zwei Lösungen:

gp  Formatieren über Format-Klassen. Allgemeines Formatierungsverhalten wird in einer abstrakten Klasse Format fixiert. Sie definiert die Funktionalität, um zum einen (landes-) sprachabhängige Ausgaben zu erzeugen und zum anderen eingegebene Zeichenketten entsprechend zu zerlegen. Dazu stellt die Klasse Format die Methoden format() und parseObject() bereit. Jede Zeichenkette, die vom Format-Objekt erzeugt wurde, ist auch mit dem Parser wieder einlesbar.
gp  In Java 5 realisiert die format()-Funktion eine Ausgabe, so wie sie unter C mit printf() gesetzt wurde.

Die abstrakte Klasse Format wird erweitert von DateFormat, MessageFormat und NumberFormat. Die Unterklassen übernehmen die Ein-/Ausgabe für Datumsangaben, für allgemeine Programmmeldungen und für Zahlen.

Abbildung
Hier klicken, um das Bild zu Vergrößern

Das Beispiel in der Tabelle zeigt Anwendungen der Klassen.


Tabelle 4.1   Beispiele für konkrete Format-Klassen

Ergebnis Formatiert mit
02.09.2005 DateFormat.getDateInstance().format( new Date() )
15:25:16 DateFormat.getTimeInstance().format( new Date() )
02.09.2005 15:25:16 DateFormat.getDateTimeInstance().format( new Date() )
12.345,679 NumberFormat.getInstance().format( 12345.6789 )
12.345,68 € NumberFormat.getCurrencyInstance().format( 12345.6789 )
12  % NumberFormat.getPercentInstance().format( 0.123 )

Jede dieser Klassen implementiert auf jeden Fall die Methode zur Ausgabe format() und zur Erkennung parseObject().


abstract class java.text.  Format
  implements Serializable, Cloneable

gp  String format( Object obj ) Formatiert das Objekt obj und gibt eine Zeichenkette zurück.
gp  abstract StringBuffer format( Object obj, StringBuffer toAppendTo, FieldPosition pos ) Formatiert ein Objekt und hängt den Text an den angegebenen StringBuffer an. Kann die Zeichenkette nicht mit format() nach den Regeln des Format-Objekts ausgegeben werden, löst die Methode eine IllegalArgumentException aus. Ist die Formatierungsanweisung falsch, so gibt format() das Unicode-Zeichen \uFFFD zurück.
gp  Object parseObject( String source ) Analysiert den Text von Anfang an.
gp  abstract Object parseObject( String source, ParsePosition pos ) Der Text wird ab der Stelle pos umgewandelt. Konnte parseObject() die Zeichenkette nicht zurückübersetzen, so folgt eine ParseException. parseObject(String, Parse-Position) verändert das ParsePosition-Objekt nicht und gibt die Null-Referenz zurück.
gp  Object clone() Gibt eine Kopie zurück.

Die Mehrzahl der Format-Unterklassen implementiert Fabrikfunktionen der Art:

gp  static XXXFormat getYYYInstance() Für ein Formatierungsobjekt mit den Formatierungsregeln für das voreingestellte Land.
gp  static XXXFormat getYYYInstance( Locale l ) Für ein Formatierungsobjekt mit den Formatierungsregeln für das angegebene Land. So erlauben die Unterklassen von Format es dem Benutzer auch, weitere Objekte zu erzeugen, die an die speziellen Sprachbesonderheiten der Länder angepasst sind.

Galileo Computing

4.7.1 Zahlen, Prozente und Währungen mit NumberFormat formatieren  downtop

NumberFormat widmet sich der Ausgabe von Zahlen. Dabei unterstützt die Klasse mit Fabrikfunktionen vier Typen von Ausgaben.


abstract class java.text.  NumberFormat
  extends Format

gp  static NumberFormat getNumberInstance() Gewöhnlicher Formatierer für Zahlen.
gp  static NumberFormat getNumberInstance() Liefert einen Formatierer, der den Nachkommateil abschneidet und rundet.
gp  static NumberFormat getPercentInstance() Liefert einen Formatierer, der Fließkommazahlen über die format()-Methode im Bereich von 0 bis 1 annimmt und dann als Prozentzahl formatiert. Nachkommastellen werden abgeschnitten.
gp  static NumberFormat getCurrencyInstance() Liefert einen Formatierer für Währungen, der ein Währungszeichen der Ausgabe hinzufügt.

Die genannten vier Methoden gibt es jeweils in der parameterlosen Variante und in der Variante mit einem Locale-Objekt, um etwa das Währungszeichen oder das Kommazeichen anzupassen.


Beispiel   Gib eine Prozentzahl prozent im Bereich von 0 bis 100 aus.

Listing 4.10   ProzenteGeben.java

import java.text.NumberFormat;
public class ProzenteGeben
{
  public static void main( String[] args )
  {
    double prozent = 45.3;
    NumberFormat nf = NumberFormat.getPercentInstance();
    System.out.println( nf.format(prozent/100) );
  }
}


Galileo Computing

4.7.2 Dezimalzahlformatierung mit DecimalFormat  downtop

DecimalFormat ist eine Unterklasse von NumberFormat und ermöglicht individuellere Anpassungen an die Ausgabe. Dem Konstruktor kann ein Formatierungs-String übergeben werden, sozusagen eine Vorlage, wie die Zahlen zu formatieren sind. Die Formatierung einer Zahl durch DecimalFormat erfolgt mit Rücksicht auf die aktuell eingestellte Sprache.

Listing 4.11   DezimalFormatTest.java

import java.text.*;
public class DezimalFormatTest
{
  public static void main( String[] args )
  {
    double d = 12345.67890;
    DecimalFormat df =   new DecimalFormat  ( ",##0.00" );
    System.out.println(   df.format(d)   );           // 12.345,68
  }
}

Der Formatierungsstring kann eine Menge von Formatierungsanweisungen vertragen; im Beispiel kommen #, 0 und das Komma vor. Die beiden wichtigen Symbole sind jedoch 0 und #. Beide repräsentieren Ziffern. Der Unterschied tritt erst dann zu Tage, wenn weniger Zeichen zum Formatieren da sind, wie im Formatierungsstring genannt werden.


Tabelle 4.2   Formatierungsanweisungen für DecimalFormat

Symbol Bedeutung
0 Repräsentiert eine Ziffer – ist die Stelle nicht belegt, wird eine Null angezeigt.
# Repräsentiert eine Ziffer – ist die Stelle nicht belegt, bleibt sie leer, damit führende Nullen und unnötige Nullen hinter dem Komma nicht angezeigt werden.
. Dezimaltrenner. Trennt Vor- und Nachkommastellen.
, Gruppiert die Ziffern (eine Gruppe ist so groß wie der Abstand von "," zu ".").
; Trennzeichen. Links davon steht das Muster für positive, rechts das für negative Zahlen.
- Das Standardzeichen für das Negativpräfix
% Die Zahl wird mit 100 multipliziert und als Prozentwert ausgewiesen.
%% Genau wie %, nur mit Promille.
\u00A4 Nationales Währungssymbol (€ für Deutschland)
\u00A4\u00A4 Internationales Währungssymbol (EUR für Deutschland)
X Alle anderen Zeichen X können ganz normal benutzt werden.
' Ausmarkieren von speziellen Symbolen im Präfix oder Suffix

Hier ein Beispiel für die Auswirkungen der Formatanweisungen auf einige Zahlen:


Tabelle 4.3   Beispiel für verschiedene Formatanweisungen

Format Eingabezahl Ergebnis
0000 12 0012
0000 12,5 0012
0000 1234567 1234567
## 12 12
## 12.3456 12
## 123456 123456
.00 12.3456 12,35
.00 .3456 ,35
0.00 .789 0,79
#.000000 12.34 12,340000
,### 12345678.901 12.345.679
#.#;(#.#) 12345678.901 12345678,9
#.#;(#.#) –12345678.901 (12345678,9)
,###.## \u00A4 12345.6789 12.345,68 i
,#00.00 \u00A4\u00A4 –12345678.9 –12.345.678,90 EUR
,#00.00 \u00A4\u00A4 0.1 00,10 EUR


Galileo Computing

4.7.3 Formatieren mit format() aus String  downtop

Losgelöst von der Format-Hierarchie der Klassen aus dem Text-Paket stellt die Klasse String mit der statischen Funktion format() eine Möglichkeit bereit, Zeichenketten nach einer Vorgabe zu formatieren.


final class java.lang.  String
  implements CharSequence, Comparable<String>, Serializable

gp  static String format( Locale l, String format, Object... args ) Liefert einen formatierten String, der aus der gewünschten Sprache, dem String und Argumenten hervorgeht.
gp  static String format( String format, Object... args ) Liefert einen formatierten String, der aus dem String und den Argumenten hervorgeht.

Der String format nennt sich Format-String. Er enthält neben auszugebenden Zeichen so genannte Format-Spezifizierer, die dem Formatierer darüber Auskunft geben, wie das Argument formatiert werden soll. %s steht für eine unformatierte Ausgabe eines Strings.

String[] arg = { "Ulli""Tanja" };
String s = String.format( "Hallo %s. Es gab ein Anruf von %s."arg );
System.out.println( s );    // Hallo Ulli. Es gab ein Anruf von Tanja.

Die Anzahl der Format-Spezifizierer ist so groß und vielfältig, dass ein Blick in die API-Dokumentation auf jeden Fall nötig ist. Wichtige Format-Spezifizierer sind:


%n Neue Zeile %b Boolean
%% Prozentzeichen %s String
%c Unicode-Zeichen %d Dezimalzahl
%x Hexadezimalschreibweise %t Datum und Zeit
%f Fließkommazahl %e Wissenschaftliche Notation

Intern werkeln java.util.Formatter (keine java.text.Format-Objekte), die sich auch direkt verwenden lassen; dort ist auch die Dokumentation festgemacht.

Praktischerweise ist das Formatieren und Ausgeben zu einer neuen Funktion printf() in den PrintWriter und PrintStream (das System.out-Objekt ist vom Typ PrintStream) gewandert, so dass sich jetzt auch schreiben lässt:

String[] arg = { "Ulli""Tanja" };
System.out.printf( "Hallo %s. Es gab ein Anruf von %s."arg );

Mit der Schreibweise von Java 5 für variable Argumentlisten ist das eigene arg-Feld nicht nötig, sodass sich der Funktionsaufruf vereinfacht zu:

System.out.printf( "Hallo %s. Es gab ein Anruf von %s.""Ulli""Tanja" );

Auch bei printf() ist als erstes Argument eine Locale möglich.

Listing 4.12   PrintfDemo.java

import static java.lang.System.out;
public class PrintfDemo
{
  public static void main( String[] args )
  {
    int i = 123;
    out.printf( "|%d|   |%d|\n" ,     i-i);    // |123|   |-123|
    out.printf( "|%5d| |%5d|\n" ,     i-i);    // |  123| | –123|
    out.printf( "|%-5d| |%-5d|\n" ,   i-i);    // |123  | |-123 |
    out.printf( "|%+-5d| |%+-5d|\n" , i-i);    // |+123 | |-123 |
    out.printf( "|%05d| |%05d|\n\n",  i-i);    // |00123| |-0123|
    out.printf( "|%X| |%x|\n"0xabc0xabc );   // |ABC| |abc|
    out.printf( "|%08x| |%#x|\n\n"0xabc0xabc ); // |00000abc| |0xabc|
    double d = 1234.5678;
    out.printf( "|%f| |%f|\n" ,         d-d);  // |1234,567800| |-1234,567800|
    out.printf( "|%.2f| |%.2f|\n" ,     d-d);  // |1234,57| |-1234,57|
    out.printf( "|%10f| |%10f|\n" ,     d-d);  // |1234,567800| |-1234,567800|
    out.printf( "|%10.2f| |%10.2f|\n" , d-d);  // |   1234,57| |  –1234,57|
    out.printf( "|%010.2f| |%010.2f|\n",d-d);  // |0001234,57| |-001234,57|
    String s = "Monsterbacke";
    out.printf( "\n|%s|\n"s );                 // |Monsterbacke|
    out.printf( "|%20s|\n"s );                 // |        Monsterbacke|
    out.printf( "|%-20s|\n"s );                // |Monsterbacke        |
    out.printf( "|%7s|\n"s );                  // |Monsterbacke|
    out.printf( "|%.7s|\n"s );                 // |Monster|
    out.printf( "|%20.7s|\n"s );               // |             Monster|
  }
}

Galileo Computing

4.7.4 Ausgaben formatieren mit MessageFormat  toptop

Da es die Methode format() und die Klasse Formatter erst seit Java 5 gibt, soll an dieser Stelle noch eine andere Klasse genannt werden, die schon länger in der Bibliothek zu Hause ist. MessageFormat ist eine konkrete Unterklasse der abstrakten Klasse Format und dient dazu, Nachrichten sprachunabhängig zu erzeugen. Das heißt, die tatsächliche sprachabhängige Ausgabe wird so weit wie möglich nach hinten geschoben und erst dann erzeugt, wenn die Nachricht dem Benutzer angezeigt werden soll. Durch MessageFormat werden nur Formatierungsanweisungen gegeben, und die wirklichen Informationen (also die Objekte als Informationsträger) werden zur Laufzeit eingesetzt. Dabei enthalten die Formatierungsanweisungen Platzhalter für diese Objekte. In der Regel werden Daten (die Argumente) erst zur Laufzeit ermittelt, wie etwa die Zeilennummer einer Fehlerstelle in einer Eingabedatei.


Beispiel   Eine Anwendung des Formatierers. Der format()-Befehl formatiert die Argumente, die in einem Objekt-Feld abgelegt sind, mit dem Aussehen, wie es im Konstruktor des MessageFormat-Objekts angegeben wurde.
Object[] testArgs = { new Long(31415), "SchnelleLotte" };
MessageFormat form = new MessageFormat(
    "Anzahl Dateien auf der Festplatte \"{1}\": {0}." );
System.out.println( form.format(testArgs) );
Die Ausgabe mit unterschiedlichen testArgs ist:
Anzahl Dateien auf der Festplatte "SchnelleLotte": 0.
Anzahl Dateien auf der Festplatte "SchnelleLotte": 1.
Anzahl Dateien auf der Festplatte "SchnelleLotte": 31,415.

Die Argumente aus dem Array werden über die Platzhalter wie {0} in die Nachricht eingefügt. Die Nummern entsprechen der Reihenfolge der Argumente im Array. Einträge im Array können ungenutzt bleiben. Fehlt allerdings das einem Platzhalter entsprechende Element im Feld, so wird eine ParseException geworfen.


class java.text.  MessageFormat
  extends Format

gp  MessageFormat( String pattern ) Erzeugt ein MessageFormat-Objekt mit dem angegebenen Pattern.

Gegenüber anderen Format-Klassen zeigt die Klasse MessageFormat eine Besonderheit im Erzeugen. MessageFormat-Objekte werden über ihren Konstruktor erzeugt und nicht über getInstance(). Der Grund ist, dass üblicherweise die Erzeugungsmethoden – damit sind die getInstance()-Varianten gemeint – eine komplexe Initialisierung durchlaufen, die die landesspezifischen Einstellungen festlegen. MessageFormat ist aber an keine bestimmte Sprache gebunden und benötigt folglich auch keine Initialisierung.

Bildungsgesetz für Message-Formate

Die Zeichenkette für MessageFormat enthält die Format-Elemente, die in geschweiften Klammern gesetzt sind. Steht dort nur der Index – wie {0} –, ist das der einfachste Fall. Die API-Dokumentation von MessageFormat zeigt jedoch, dass die Angaben auch präziser ausfallen können:

gp  { ArgumentIndex, FormatType }: Element wird nach gegebenem Format-Typ number, date, time oder choice formatiert. MessageFormat besorgt sich zum Beispiel im Fall vom Format-Typ number über NumberFormat.getInstance(getLocale()) einen passenden Formatierer.
gp  { ArgumentIndex, FormatType, FormatStyle }: Neben dem Format-Typ lässt sich der Stil festlegen. Vordefiniert sind short, medium, long, full, integer, currency, percent. Ein eigener Formatierungs-Stil lässt sich auch angeben, der aber zur Unterscheidung in einfachen Hochkommata eingeschlossen werden muss.

Abschließend sei ein Beispiel mit MessageFormat gegeben, welches das gleiche Argument unterschiedlich formatiert.

Listing 4.13   MessageFormatDemo.java

import java.text.*;
import java.util.*;
public class MessageFormatDemo
{
  public static void main( String[] args )
  {
    Object[] arguments = {
      new Date(System.currentTimeMillis()),
      "die Antwort auf alle Fragen",
      new Integer(42)
    };
    String result = MessageFormat.format(
      "Am {0,date} um {0,time} ist {1} wie immer {2,number,integer}.",
      arguments );
    System.out.println( result );
  }
}

Dies erzeugt die Ausgabe:

Am 22.07.2005 um 19:05:42 ist die Antwort auf alle Fragen wie immer 42.


Hinweis   Bei den geschweiften Klammern besteht Verwechslungsgefahr zwischen Message-Platzhalter und normalem Zeichen. Das ist insbesondere ein Problem, wenn die Nachricht mit den Platzhaltern eine beliebige Datei ist (etwa ein Java-Programm, in dem der Name der Klasse durch einen Platzhalter angedeutet ist). Dann muss jede normale geschweifte Klammer { durch \'{' ersetzt werden.

 << zurück




Copyright © Galileo Press GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de