Anleitung zu java.util.Formatter

1. Übersicht

In diesem Artikel werden wir die Diskussion String Formatierung in Java unter Verwendung der java.util.Formatter - Klasse, die Unterstützung für das Layout Begründung und Ausrichtung zur Verfügung stellt.

2. Verwendung des Formatierers

Erinnerst du dich an Cs printf? Das Formatieren eines Strings in Java fühlt sich sehr ähnlich an.

Die format () -Methode des Formatierers wird über eine statische Methode aus der String- Klasse verfügbar gemacht . Diese Methode akzeptiert eine Vorlage String und eine Liste von Argumenten mit der Vorlage zu füllen:

String greetings = String.format( "Hello Folks, welcome to %s !", "Baeldung");

Die resultierende Zeichenfolge lautet:

"Hello Folks, welcome to Baeldung !"

Eine Vorlage ist eine Zeichenfolge , die statischen Text und einen oder mehrere Formatbezeichner enthält, die angeben, welches Argument an der jeweiligen Position platziert werden soll.

In diesem Fall gibt es einen einzelnen Formatbezeichner % s , der durch das entsprechende Argument ersetzt wird.

3. Formatspezifizierer

3.1. Allgemeine Syntax

Die Syntax der Formatbezeichner für den Typ " Allgemein", "Zeichen" und " Numerisch " lautet:

%[argument_index$][flags][width][.precision]conversion

Die Bezeichner argument_index, flag, width und präzise sind optional.

  • Der Teil argument_index ist eine Ganzzahl i , die angibt, dass hier das i-te Argument aus der Argumentliste verwendet werden soll
  • flags ist eine Reihe von Zeichen, die zum Ändern des Ausgabeformats verwendet werden
  • width ist eine positive Ganzzahl, die die Mindestanzahl von Zeichen angibt, die in die Ausgabe geschrieben werden sollen
  • Genauigkeit ist eine Ganzzahl, die normalerweise verwendet wird, um die Anzahl der Zeichen zu beschränken, deren spezifisches Verhalten von der Konvertierung abhängt
  • ist der obligatorische Teil. Es ist ein Zeichen, das angibt, wie das Argument formatiert werden soll. Die Menge der gültigen Konvertierungen für ein bestimmtes Argument hängt vom Datentyp des Arguments ab

Wenn wir in unserem obigen Beispiel die Nummer eines Arguments explizit angeben möchten, können wir es mit den Argumentindizes 1 $ und 2 $ schreiben .

Beides ist das erste bzw. zweite Argument:

String greetings = String.format( "Hello %2$s, welcome to %1$s !", "Baeldung", "Folks");

3.2. Für Datum / Uhrzeit Darstellung

%[argument_index$][flags][width]conversion

Auch hier sind argument_index, Flags und width optional.

Nehmen wir ein Beispiel, um dies zu verstehen:

@Test public void whenFormatSpecifierForCalendar_thenGotExpected() { Calendar c = new GregorianCalendar(2017, 11, 10); String s = String.format( "The date is: %tm %1$te,%1$tY", c); assertEquals("The date is: 12 10,2017", s); }

Hier wird für jeden Formatbezeichner das 1. Argument verwendet, also 1 $ . Wenn wir hier den argument_index für den 2. und 3. Formatbezeichner überspringen , wird versucht, 3 Argumente zu finden, aber wir müssen für alle 3 Formatbezeichner dasselbe Argument verwenden.

Es ist also in Ordnung, wenn wir das Argument _index für das erste nicht angeben , aber es für die anderen beiden angeben müssen.

Die Flagge hier besteht aus zwei Zeichen. Wobei das erste Zeichen immer ein 't' oder 'T' ist . Das zweite Zeichen hängt davon ab, welcher Teil des Kalenders angezeigt werden soll.

In unserem Beispiel geben die ersten Formatbezeichner tm den als zwei Ziffern formatierten Monat an, te den Tag des Monats und tY das als vier Ziffern formatierte Jahr.

3.3. Formatbezeichner ohne Argumente

%[flags][width]conversion

Die optionalen Flags und die Breite entsprechen denen, die in den obigen Abschnitten definiert wurden.

Die erforderliche Umwandlung ist ein Zeichen oder String angibt Inhalt in der Ausgabe eingefügt werden. Derzeit können nur '%' und Zeilenumbruch 'n' wie folgt gedruckt werden:

@Test public void whenNoArguments_thenExpected() { String s = String.format("John scored 90%% in Fall semester"); assertEquals("John scored 90% in Fall semester", s); } 

Innen - Format () , wenn wir drucken möchten ‚%‘ - wir brauchen es zu entkommen , indem Sie ‚%%‘ .

4. Konvertierungen

Lassen Sie uns nun jedes Detail der Format Specifier-Syntax untersuchen, beginnend mit einer Konvertierung . Beachten Sie, dass Sie alle Details in den finden Formatter javadocs.

Wie wir in den obigen Beispielen festgestellt haben, ist in allen Formatspezifizierern ein Konvertierungsteil erforderlich, der in mehrere Kategorien unterteilt werden kann.

Schauen wir uns jeden einzelnen anhand von Beispielen an.

4.1. Allgemeines

Wird für jeden Argumenttyp verwendet. Die allgemeinen Umrechnungen sind:

  1. 'b' oder 'B' - für Boolesche Werte
  2. 'h' oder 'H' - für HashCode
  3. 's' oder 'S' - für String wird , wenn null , "null" ausgegeben , andernfalls arg.toString ()

Wir werden nun versuchen, Boolesche und String- Werte mit den entsprechenden Konvertierungen anzuzeigen :

@Test public void givenString_whenGeneralConversion_thenConvertedString() { String s = String.format("The correct answer is %s", false); assertEquals("The correct answer is false", s); s = String.format("The correct answer is %b", null); assertEquals("The correct answer is false", s); s = String.format("The correct answer is %B", true); assertEquals("The correct answer is TRUE", s); }

4.2. Charakter

Wird für die Grundtypen verwendet, die Unicode-Zeichen darstellen: char, Character, byte, Byte, short und Short . Diese Konvertierung kann auch für die Typen int und Integer verwendet werden, wenn Character.isValidCodePoint (int) für sie true zurückgibt .

Es kann je nach gewünschtem Fall als 'c' oder 'C' geschrieben werden .

Versuchen wir einige Zeichen zu drucken:

@Test public void givenString_whenCharConversion_thenConvertedString() { String s = String.format("The correct answer is %c", 'a'); assertEquals("The correct answer is a", s); s = String.format("The correct answer is %c", null); assertEquals("The correct answer is null", s); s = String.format("The correct answer is %C", 'b'); assertEquals("The correct answer is B", s); s = String.format("The valid unicode character: %c", 0x0400); assertTrue(Character.isValidCodePoint(0x0400)); assertEquals("The valid unicode character: Ѐ", s); }

Nehmen wir noch ein Beispiel für einen ungültigen Codepunkt:

@Test(expected = IllegalFormatCodePointException.class) public void whenIllegalCodePointForConversion_thenError() { String s = String.format("The valid unicode character: %c", 0x11FFFF); assertFalse(Character.isValidCodePoint(0x11FFFF)); assertEquals("The valid unicode character: Ā", s); }

4.3. Numerisch - Integral

Diese werden für Java-Integraltypen verwendet: Byte, Byte, Short, Short, Int und Integer, Long, Long und BigInteger . In dieser Kategorie gibt es drei Conversions:

  1. 'd' - für Dezimalzahl
  2. 'o' - für Oktalzahl
  3. 'X' oder 'x' - für Hexadezimalzahl

Versuchen wir, jedes dieser Elemente auszudrucken:

@Test public void whenNumericIntegralConversion_thenConvertedString() { String s = String.format("The number 25 in decimal = %d", 25); assertEquals("The number 25 in decimal = 25", s); s = String.format("The number 25 in octal = %o", 25); assertEquals("The number 25 in octal = 31", s); s = String.format("The number 25 in hexadecimal = %x", 25); assertEquals("The number 25 in hexadecimal = 19", s); }

4.4. Numerisch - Gleitkomma

Wird für Java-Gleitkommatypen verwendet: float, Float, double, Double und BigDecimal

  1. 'e' oder 'E' - formatiert als Dezimalzahl in computergestützter wissenschaftlicher Notation
  2. 'f' - als Dezimalzahl formatiert
  3. 'g' oder 'G' - basierend auf dem Genauigkeitswert nach dem Runden wird diese Konvertierung in eine computergestützte wissenschaftliche Notation oder ein Dezimalformat formatiert

Versuchen wir, die Gleitkommazahlen zu drucken:

@Test public void whenNumericFloatingConversion_thenConvertedString() { String s = String.format( "The computerized scientific format of 10000.00 " + "= %e", 10000.00); assertEquals( "The computerized scientific format of 10000.00 = 1.000000e+04", s); String s2 = String.format("The decimal format of 10.019 = %f", 10.019); assertEquals("The decimal format of 10.019 = 10.019000", s2); }

4.5. Andere Konvertierungen

  • Datum / Uhrzeit - für Java-Typen, die ein Datum oder eine Uhrzeit codieren können: long, Long, Calendar, Date und TemporalAccessor. Dazu müssen wir das Präfix 't' oder 'T' verwenden , wie wir zuvor gesehen haben
  • Prozent - Gibt ein Literal '%' ('\ u0025') aus.
  • Line - Separator - druckt eine plattformspezifischen Zeilentrenn

Schauen wir uns ein einfaches Beispiel an:

@Test public void whenLineSeparatorConversion_thenConvertedString() { String s = String.format("First Line %nSecond Line"); assertEquals("First Line \n" + "Second Line", s); }

5. Flaggen

Flags, in general, are used to format the output. Whereas in case of date and time, they are used to specify which part of the date is to be displayed, as we saw in the Section 4 example.

A number of flags are available, a list of which can be found in the documentation.

Let’s see a flag example to understand it’s usage. ‘-‘ is used to format the output as left justified:

@Test public void whenSpecifyFlag_thenGotFormattedString() { String s = String.format("Without left justified flag: %5d", 25); assertEquals("Without left justified flag: 25", s); s = String.format("With left justified flag: %-5d", 25); assertEquals("With left justified flag: 25 ", s); }

6. Precision

For general conversions, precision is just the maximum number of characters to be written to the output. Whereas, f or the floating-point conversions the precision is the number of digits after the radix point.

The first statement is an example of precision with floating-point numbers, and the second one with general conversions:

@Test public void whenSpecifyPrecision_thenGotExpected() { String s = String.format( "Output of 25.09878 with Precision 2: %.2f", 25.09878); assertEquals("Output of 25.09878 with Precision 2: 25.10", s); String s2 = String.format( "Output of general conversion type with Precision 2: %.2b", true); assertEquals("Output of general conversion type with Precision 2: tr", s2); }

7. Argument Index

As mentioned previously, theargument_index is an integer that indicates the position of the argument in the argument list. 1$ indicates the first argument, 2$ the second argument, and so on.

Also, there is another way to reference arguments by position, by using the ‘<‘ (‘\u003c') flag, which means the argument from the previous format specifier will be re-used. For example, these two statements would produce the identical output:

@Test public void whenSpecifyArgumentIndex_thenGotExpected() { Calendar c = Calendar.getInstance(); String s = String.format("The date is: %tm %1$te,%1$tY", c); assertEquals("The date is: 12 10,2017", s); s = String.format("The date is: %tm %
    

8. Other Ways of Using Formatter

Till now we saw the use of format() method of the Formatter class. We can also create a Formatter instance, and use that to invoke the format() method.

We can create an instance by passing in an Appendable, OutputStream, File or file name. Based on this, the formatted String is stored in an Appendable, OutputStream, File respectively.

Let's see an example of using it with an Appendable. We can use it with others in the same way.

8.1. Using Formatter With Appendable

Let's create a StringBuilder instance sb, and create a Formatter using it. Then we'll invoke format() to format a String:

@Test public void whenCreateFormatter_thenFormatterWithAppendable() { StringBuilder sb = new StringBuilder(); Formatter formatter = new Formatter(sb); formatter.format("I am writting to a %s Instance.", sb.getClass()); assertEquals( "I am writting to a class java.lang.StringBuilder Instance.", sb.toString()); }

9. Conclusion

In this article, we saw the formatting facilities provided by the java.util.Formatter class. We saw various syntax that can be used to format the String and the conversion types that can be used for different data types.

As usual, the code for the examples we saw can be found over on Github.