Guide pour java.util.Formatter

Guide de java.util.Formatter

1. Vue d'ensemble

Dans cet article, nous aborderons le formatage deString en Java à l'aide de la classejava.util.Formatter, qui prend en charge la justification et l'alignement de la mise en page.

2. Comment utiliser lesFormatter

Souvenez-vous desprintf? de C Le formatage d'unString en Java est très similaire.

La méthodeformat() desFormatter est exposée via une méthode statique de la classeString. Cette méthode accepte un modèleString et une liste d'arguments pour remplir le modèle avec:

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

LeString résultant est:

"Hello Folks, welcome to example !"

Un modèle est unString qui contient du texte statique et un ou plusieurs spécificateurs de format, qui indiquent quel argument doit être placé à la position particulière.

Dans ce cas,there’s a single format specifier %s, which gets replaced by the corresponding argument.

3. Spécificateurs de format

3.1. Syntaxe générale

La syntaxe des spécificateurs de format pour les typesGeneral, Character, etNumeric est:

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

Les spécificateursargument_index, flag, width etprecision sont facultatifs.

  • La partieargument_index est un entieri - indiquant que l'argumentith de la liste d'arguments doit être utilisé ici

  • flags est un jeu de caractères utilisé pour modifier le format de sortie

  • width est un entier positif qui indique le nombre minimum de caractères à écrire dans la sortie

  • precision est un entier généralement utilisé pour restreindre le nombre de caractères, dont le comportement spécifique dépend de la conversion

  • est la partie obligatoire. Il s’agit d’un caractère indiquant la mise en forme de l’argument. L'ensemble des conversions valides pour un argument donné dépend du type de données de l'argument

Dans notre exemple ci-dessus, si nous voulons spécifier explicitement le numéro d'un argument, nous pouvons l'écrire en utilisant les indices d'argument1$ et2$.

Ceux-ci étant le premier et le deuxième argument, respectivement:

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

3.2. Pour la représentationDate/Time

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

Là encore, lesargument_index, flags etwidth sont facultatifs.

Prenons un exemple pour comprendre ceci:

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

Ici, pour chaque spécificateur de format, le 1er argument sera utilisé, donc1$. Ici, si nous sautons lesargument_index pour les 2ème et 3ème spécificateurs de format, il essaie de trouver 3 arguments, mais nous devons utiliser le même argument pour les 3 spécificateurs de format.

Donc, ce n’est pas grave si nous ne spécifions pasargument _index pour le premier, mais nous devons le spécifier pour les deux autres.

Leflag ici est composé de deux caractères. Où le premier caractère est toujours un‘t' ou‘T'. Le deuxième caractère dépend de la partie deCalendar à afficher.

Dans notre exemple, le premier spécificateur de formattm, indique le mois formaté en deux chiffres,te indique le jour du mois ettY indique l'année formatée en quatre chiffres.

3.3. Spécificateurs de format sans arguments

%[flags][width]conversion

Lesflags etwidth optionnels sont les mêmes que ceux définis dans les sections ci-dessus.

Leconversion requis est un caractère ouString indiquant le contenu à insérer dans la sortie. Actuellement, seuls les‘%' et la nouvelle ligne‘n' peuvent être imprimés en utilisant ceci:

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

    assertEquals("John scored 90% in Fall semester", s);
}

À l'intérieur deformat(), si nous voulons imprimer‘%' - nous devons l'échapper en utilisant‘%%'.

4. Conversions

Voyons maintenant tous les détails de la syntaxe du spécificateur de format, en commençant par unconversion. Notez que vous pouvez trouver tous les détails dans lesFormatter javadocs.

Comme nous l'avons remarqué dans les exemples ci-dessus, la partieconversion est requise dans tous les spécificateurs de format, et elle peut être divisée en plusieurs catégories.

Examinons chacun d’entre eux en prenant des exemples.

4.1. Général

Utilisé pour tout type d'argument. Les conversions générales sont:

  1. ‘b’ ou‘B' - pour les valeursBoolean

  2. ‘h’ ou‘H' - pourHashCode

  3. ‘s' ou‘S' - pourString, sinull, il affiche «null», sinonarg.toString()

Nous allons maintenant essayer d'afficher les valeursboolean etString, en utilisant les conversions correspondantes:

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

Utilisé pour les types de base qui représentent des caractères Unicode:char, Character, byte, Byte, short, etShort. Cette conversion peut également être utilisée pour les typesint etInteger lorsque leCharacter.isValidCodePoint(int) renvoietrue pour eux.

Il peut être écrit sous la forme‘c’ ou’C’ selon le cas souhaité.

Essayons d'imprimer quelques caractères:

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

Prenons un autre exemple de point de code non valide:

@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. Numérique - Intégral

Ceux-ci sont utilisés pour les types intégraux Java:byte, Byte, short, Short, int etInteger, long, Long, etBigInteger. Il y a trois conversions dans cette catégorie:

  1. ‘d' - pour le nombre décimal

  2. ‘o' - pour un nombre octal

  3. ‘X' ou‘x' - pour un nombre hexadécimal

Essayons d'imprimer chacun de ces éléments:

@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. Numérique - Virgule flottante

Utilisé pour les types à virgule flottante Java:float, Float, double, Double, etBigDecimal

  1. ‘e' ou‘E' formaté en nombre décimal en notation scientifique informatisée

  2. ‘f' formaté en nombre décimal

  3. ‘g' ou‘G' en fonction de la valeur de précision après arrondi, cette conversion prend des formats en notation scientifique informatisée ou au format décimal

Essayons d'imprimer les nombres à virgule flottante:

@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. Autres conversions

  • Date/Time - pour les types Java capables d'encoder une date ou une heure:long, Long, Calendar,Date etTemporalAccessor. Pour cela, nous devons utiliser le préfixe‘t' ou‘T', comme nous l'avons vu précédemment

  • Percent - imprime un littéral‘%' (‘%')

  • Line Separator - imprime un séparateur de ligne spécifique à la plate-forme

Prenons un exemple simple:

@Test
public void whenLineSeparatorConversion_thenConvertedString() {
    String s = String.format("First Line %nSecond Line");

    assertEquals("First Line \n" + "Second Line", s);
}

5. Drapeaux

Les drapeaux, en général, sont utilisés pour formater la sortie. Tandis que dans le cas de la date et de l'heure, ils sont utilisés pour spécifier quelle partie de la date doit être affichée, comme nous l'avons vu dans l'exemple de la section 4.

Un certain nombre de drapeaux sont disponibles, dont une liste peut être trouvée dans la documentation.

Voyons un exemple de drapeau pour comprendre son utilisation. ‘-‘ est utilisé pour formater la sortie comme justifiée à gauche:

@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

Pour les conversions générales,precision is just the maximum number of characters to be written to the output. Tandis que, pour les conversions en virgule flottante, la précision est le nombre de chiffres après le point de base.

La première instruction est un exemple de précision avec des nombres à virgule flottante et la seconde avec des conversions générales:

@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. Index des arguments

Comme mentionné précédemment, lesargument_index is an integer that indicates the position of the argument in the argument list. 1$ indique le premier argument,2$ le deuxième argument, et ainsi de suite.

En outre, il existe une autre façon de référencer des arguments par position, en utilisant l'indicateur‘<‘ (‘<'), ce qui signifie que l'argument du spécificateur de format précédent sera réutilisé. Par exemple, ces deux instructions produiraient une sortie identique:

@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. Autres façons d'utiliserFormatter

Jusqu'à présent, nous avons vu l'utilisation de la méthodeformat() de la classeFormatter. Nous pouvons également créer une instanceFormatter, et l'utiliser pour invoquer la méthodeformat().

We can create an instance by passing in an Appendable, OutputStream, File or file name. Sur cette base, leString formaté est stocké dans unAppendable,OutputStream,File respectivement.

Voyons un exemple de son utilisation avec unAppendable. Nous pouvons l’utiliser avec d’autres de la même manière.

8.1. Utilisation deFormatter avecAppendable

Créons une instance de StringBuildersb, et créons unFormatter en l'utilisant. Ensuite, nous allons appelerformat() pour formater unString:

@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

Dans cet article, nous avons vu les fonctionnalités de formatage fournies par la classejava.util.Formatter. Nous avons vu diverses syntaxes pouvant être utilisées pour formater lesString et les types de conversion pouvant être utilisés pour différents types de données.

Comme d'habitude, le code des exemples que nous avons vus peut être trouvéover on Github.