Java >> Java tutorial >  >> Tag >> java.util

Guide til java.util.Formatter

1. Oversigt

I denne artikel vil vi diskutere strengen formatering i Java ved hjælp af java.util.Formatter klasse, som giver støtte til layout-begrundelse og justering.

2. Sådan bruger du Formater

Husker du C's printf? Formatering af en streng i Java føles meget ens.

format() metoden for Formater eksponeres via en statisk metode fra strengen klasse. Denne metode accepterer en skabelon String og en liste over argumenter til at udfylde skabelonen med:

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

Den resulterende streng er:

"Hello Folks, welcome to Baeldung !"

En skabelon er en streng der indeholder noget statisk tekst og en eller flere formatspecifikationer, som angiver, hvilket argument der skal placeres på den bestemte position.

I dette tilfælde er der en enkelt formatspecifikation %s , som bliver erstattet af det tilsvarende argument.

3. Formatspecifikationer

3.1. Generel syntaks

Syntaksen af ​​formatspecifikationer for Generelt, Tegn, og Numerisk typen er:

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

Specifikatorer argument_index, flag, width og præcision er valgfri.

  • argument_index del er et heltal i – angiver, at ith argument fra argumentlisten skal bruges her
  • flag er et sæt tegn, der bruges til at ændre outputformatet
  • bredde er et positivt heltal, der angiver det mindste antal tegn, der skal skrives til output
  • præcision er et heltal, der normalt bruges til at begrænse antallet af tegn, hvis specifikke adfærd afhænger af konverteringen
  • er den obligatoriske del. Det er et tegn, der angiver, hvordan argumentet skal formateres. Sættet af gyldige konverteringer for et givet argument afhænger af argumentets datatype

I vores eksempel ovenfor, hvis vi ønsker at angive nummeret på et argument eksplicit, kan vi skrive det ved hjælp af 1$ og 2$ argumentindekser.

Begge disse er henholdsvis det første og det andet argument:

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

3.2. For Dato/Tid Repræsentation

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

Igen argument_index, flag og bredde er valgfri.

Lad os tage et eksempel for at forstå dette:

@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);
}

Her vil det 1. argument blive brugt for hver formatspecifikation, derfor 1$ . Her hvis vi springer argument_index over for 2. og 3. formatspecifikation forsøger den at finde 3 argumenter, men vi skal bruge det samme argument for alle 3 formatspecifikationer.

Så det er ok, hvis vi ikke specificerer argument _index for den første, men vi skal specificere den for de to andre.

flaget her består af to karakterer. Hvor det første tegn altid er et 't' eller 'T' . Det andet tegn afhænger af, hvilken del af Kalender skal vises.

I vores eksempel angiver det første format tm , angiver måned formateret som to cifre, te angiver dagen i måneden og tY angivet Årstal formateret som fire cifre.

3.3. Formatspecifikationer uden argumenter

%[flags][width]conversion

De valgfrie flag og bredde er de samme som defineret i ovenstående afsnit.

Den påkrævede konvertering er et tegn eller streng angiver indhold, der skal indsættes i outputtet. I øjeblikket er det kun '%' og nylinje 'n' kan udskrives ved hjælp af denne:

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

Inde i format() , hvis vi vil udskrive ‘%' – vi skal undslippe det ved at bruge ‘%%' .

4. Konverteringer

Lad os nu grave i alle detaljer i Format Specifier-syntaksen, begyndende med en konvertering . Bemærk, at du kan finde alle detaljerne i Formater javadocs.

Som vi bemærkede i ovenstående eksempler, konvertering del er påkrævet i alle formatspecifikationer, og den kan opdeles i flere kategorier.

Lad os tage et kig på hver enkelt ved at tage eksempler.

4.1. Generelt

Bruges til enhver argumenttype. De generelle konverteringer er:

  1. 'b' eller 'B' – for Boolsk værdier
  2. 'h' eller 'H' – for HashCode
  3. 'er' eller 'S' – for String , hvis null , udskriver den "null", ellers arg.toString()

Vi vil nu prøve at vise boolesk og streng værdier ved hjælp af de tilsvarende konverteringer:

@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. Karakter

Bruges til de grundlæggende typer, der repræsenterer Unicode-tegn:char, Character, byte, Byte, short, og Kort . Denne konvertering kan også bruges til typerne int og Heltal når Character.isValidCodePoint(int) returnerer sand for dem.

Det kan skrives som 'c' eller 'C' ud fra den sag, vi ønsker.

Lad os prøve at udskrive nogle tegn:

@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);
}

Lad os tage endnu et eksempel på et ugyldigt kodepunkt:

@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. Numerisk – Integral

Disse bruges til Java-integraltyper:byte, Byte, short, Short, int og Heltal, langt, langt, og BigInteger . Der er tre konverteringer i denne kategori:

  1. 'd' – for decimaltal
  2. 'o' – for oktaltal
  3. 'X' eller 'x' – for hexadecimalt tal

Lad os prøve at udskrive hver af disse:

@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. Numerisk – Floating Point

Bruges til Java-flydende kommatyper:float, Float, double, Double, og BigDecimal

  1. 'e' eller 'E' formateret som et decimaltal i computeriseret videnskabelig notation
  2. 'f' formateret som et decimaltal
  3. 'g' eller 'G' baseret på præcisionsværdien efter afrunding formateres denne konvertering til computeriseret videnskabelig notation eller decimalformat

Lad os prøve at udskrive de flydende decimaltal:

@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. Andre konverteringer

  • Dato/klokkeslæt – for Java-typer, der er i stand til at kode en dato eller tid:lang, lang, kalender, Dato og TemporalAccessor. Til dette skal vi bruge præfikset 't' eller 'T' , som vi så tidligere
  • Procent – udskriver et bogstaveligt '%' ('\u0025')
  • Linjesskiller – udskriver en platformsspecifik linjeseparator

Lad os se på et simpelt eksempel:

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

5. Flag

Flag bruges generelt til at formatere outputtet. Mens de i tilfælde af dato og klokkeslæt bruges til at angive, hvilken del af datoen der skal vises, som vi så i afsnit 4-eksemplet.

En række flag er tilgængelige, en liste over hvilke kan findes i dokumentationen.

Lad os se et flageksempel for at forstå dets brug. ‘-‘ bruges til at formatere output som venstrejusteret:

@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. Præcision

For generelle konverteringer er præcision kun det maksimale antal tegn, der skal skrives til outputtet . Hvorimod præcisionen for flydende kommakonverteringer er antallet af cifre efter radixpunktet.

Den første sætning er et eksempel på præcision med flydende kommatal, og den anden med generelle konverteringer:

@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. Argumentindeks

Som tidligere nævnt er argument_index er et heltal, der angiver argumentets position i argumentlisten . 1$ angiver det første argument, 2$ det andet argument, og så videre.

Der er også en anden måde at henvise til argumenter efter position ved at bruge '<' ('\u003c') flag, hvilket betyder, at argumentet fra den forrige formatspecifikation vil blive genbrugt. For eksempel ville disse to udsagn producere det identiske 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 %<te,%<tY", c);
    assertEquals("The date is: 12 10,2017", s);
}

8. Andre måder at bruge Formatter

Indtil nu har vi set brugen af ​​format() metoden for Formater klasse. Vi kan også oprette en Formater instans, og brug den til at kalde format() metode.

Vi kan oprette en instans ved at sende en tilføjelig ind , OutputStream , Fil eller filnavn . Baseret på dette, den formaterede streng er gemt i en tilføjelig , OutputStream , Fil hhv.

Lad os se et eksempel på at bruge det med en Appendable. Vi kan bruge det sammen med andre på samme måde.

8.1. Brug af Formatter Med tilføjelig

Lad os oprette en StringBuilder forekomst sb , og opret en Formater bruger det. Så kalder vi format() for at formatere en streng :

@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. Konklusion

I denne artikel så vi formateringsfaciliteterne fra java.util.Formatter klasse. Vi så forskellige syntakser, der kan bruges til at formatere strengen og de konverteringstyper, der kan bruges til forskellige datatyper.

Som sædvanlig kan koden til de eksempler, vi så, findes på Github.


Java tag