La classe String
est une classe fondamentale sans laquelle il serait difficile d’écrire du code. Après tout, vous ne pouvez même pas écrire une méthode main()
sans utiliser la classe String
. Une chaîne de caractères est essentiellement une séquence de caractères; voici un exemple:
String nom = "Minou";
Comme vous l’avez appris dans le chapitre sur les “Blocs de construction”, il s’agit d’un exemple de type référence. Vous avez également appris que les types référence sont créés à l’aide du mot-clé new
. Attendez une minute. Quelque chose manque dans l’exemple précédent: il n’y a pas de new
! En Java, ces deux extraits créent tous deux un String
:
String nom = "Minou";
String nom = new String("Minou");
Les deux vous donnent une variable de référence nommée nom
pointant vers l’objet String
“Minou”. Ils sont subtilement différents, comme vous le verrez plus tard dans ce chapitre. Pour l’instant, rappelez-vous simplement que la classe String
est spéciale et n’a pas besoin d’être instanciée avec new
.
De plus, les blocs de texte sont une autre façon de créer un String
. Pour réviser, ce bloc de texte est le même que les variables précédentes:
String nom = """
Minou""";
Puisqu’un String
est une séquence de caractères, vous ne serez probablement pas surpris d’apprendre qu’il implémente l’interface CharSequence
. Cette interface est une façon générale de représenter plusieurs classes, y compris String
et StringBuilder
.
Dans cette section, nous examinerons la concaténation, les méthodes courantes et le chaînage de méthodes.
Concaténation des chaînes String Java
Dans le chapitre sur les “Opérateurs”, vous avez appris comment additionner des nombres. 1 + 2 est clairement 3. Mais qu’en est-il de “1” + “2”? C’est “12” parce que Java combine les deux objets String
. Placer une String
devant l’autre String
et les combiner s’appelle la concaténation de chaînes. Il n’y a pas beaucoup de règles à connaître pour cela, mais vous devez bien les connaître:
- Si les deux opérandes sont numériques, + signifie addition numérique.
- Si l’un des opérandes est une
String
, + signifie concaténation. - L’expression est évaluée de gauche à droite.
Maintenant, examinons quelques exemples:
System.out.println(1 + 2); // 3
System.out.println("a" + "b"); // ab
System.out.println("a" + "b" + 3); // ab3
System.out.println(1 + 2 + "c"); // 3c
System.out.println("c" + 1 + 2); // c12
System.out.println("c" + null); // cnull
Le premier exemple utilise la première règle. Les deux opérandes sont des nombres, donc nous utilisons l’addition normale. Le deuxième exemple est une simple concaténation de chaînes, décrite dans la deuxième règle. Les guillemets pour la String
ne sont utilisés que dans le code; ils ne sont pas affichés.
Le troisième exemple combine la deuxième et la troisième règle. Puisque nous commençons à gauche, Java détermine à quoi “a” + “b” s’évalue. Vous le savez déjà: c’est “ab”. Ensuite, Java examine l’expression restante “ab” + 3. La deuxième règle nous dit de concaténer puisque l’un des opérandes est une String
.
Dans le quatrième exemple, nous commençons par la troisième règle, qui nous dit de considérer 1 + 2. Les deux opérandes sont numériques, donc la première règle nous dit que la réponse est 3. Ensuite, nous avons 3 + “c”, qui utilise la deuxième règle pour nous donner “3c”. Remarquez que les trois règles sont utilisées dans une seule ligne!
Le cinquième exemple montre l’importance de la troisième règle. D’abord, nous avons “c” + 1, qui utilise la deuxième règle pour nous donner “c1”. Ensuite, nous avons “c1” + 2, qui utilise à nouveau la deuxième règle pour nous donner “c12”.
Enfin, le dernier exemple montre comment null
est représenté comme une chaîne lors de la concaténation ou de l’impression, nous donnant “cnull”.
Prenons un exemple plus complexe:
int trois = 3;
String quatre = "4";
System.out.println(1 + 2 + trois + quatre);
Quand vous voyez cela, prenez votre temps, rappelez-vous les trois règles et assurez-vous de vérifier les types de variables. Dans cet exemple, nous commençons par la troisième règle, qui nous dit de considérer 1 + 2. La première règle nous donne 3. Ensuite, nous avons 3 + trois. Puisque trois
est de type int
, nous utilisons toujours la première règle, ce qui nous donne 6. Ensuite, nous avons 6 + quatre. Puisque quatre
est de type String
, nous passons à la deuxième règle et obtenons une réponse finale de “64”. Lorsque vous voyez des questions comme celle-ci, prenez votre temps et vérifiez les types. Être méthodique paie.
Il y a une dernière chose à savoir sur la concaténation, mais c’est facile. Dans cet exemple, vous devez simplement vous rappeler ce que fait +=. Gardez à l’esprit que s += “2” signifie la même chose que s = s + “2”.
var s = "1"; // s contient actuellement "1"
s += "2"; // s contient actuellement "12"
s += 3; // s contient actuellement "123"
System.out.println(s); // 123
À la ligne 5, nous “ajoutons” deux chaînes, ce qui signifie que nous les concaténons. La ligne 6 essaie de vous piéger en ajoutant un nombre, mais c’est comme si nous avions écrit s = s + 3. Nous savons qu’une chaîne “plus” n’importe quoi d’autre signifie utiliser la concaténation.
Pour réviser les règles une dernière fois: utilisez l’addition numérique si deux nombres sont impliqués, utilisez la concaténation dans le cas contraire, et évaluez de gauche à droite.
Méthodes importantes de String en Java
La classe String
a des dizaines de méthodes. Heureusement, vous n’avez besoin d’en connaître qu’une poignée.
Pour toutes ces méthodes, vous devez vous rappeler qu’une chaîne est une séquence de caractères et que Java compte à partir de 0 lorsqu’elle est indexée. La figure 4.1 montre comment chaque caractère de la chaîne “animaux” est indexé.
0 | 1 | 2 | 3 | 4 | 5 | 6 |
a | n | i | m | a | u | x |
FIGURE 4.1 Indexation pour une chaîne
Vous devez également savoir qu’un String
est immuable, ou inchangeable. Cela signifie qu’appeler une méthode sur un String
retournera un objet String
différent plutôt que de changer la valeur de la référence.
Examinons un certain nombre de méthodes de la classe String
. Beaucoup d’entre elles sont simples, nous ne les discuterons donc pas en détail. Vous devez savoir comment utiliser ces méthodes.
Déterminer la longueur
La méthode length()
retourne le nombre de caractères dans la String
. La signature de la méthode est la suivante:
public int length()
Le code suivant montre comment utiliser length()
:
var nom = "animaux";
System.out.println(nom.length()); // 7
Attendez. Il affiche 7? N’avons-nous pas dit que Java compte à partir de 0? La différence est que le comptage à partir de zéro ne se produit que lorsque vous utilisez des index ou des positions dans une liste. Lors de la détermination de la taille ou de la longueur totale, Java utilise à nouveau le comptage normal.
Obtenir un seul caractère
La méthode charAt()
vous permet d’interroger la chaîne pour savoir quel caractère se trouve à un index spécifique. La signature de la méthode est la suivante:
public char charAt(int index)
Le code suivant montre comment utiliser charAt()
:
var nom = "animaux";
System.out.println(nom.charAt(0)); // a
System.out.println(nom.charAt(6)); // x
System.out.println(nom.charAt(7)); // exception
Puisque les index commencent à 0, charAt(0)
renvoie le “premier” caractère de la séquence. De même, charAt(6)
renvoie le “septième” caractère de la séquence. Cependant, charAt(7)
pose un problème. Il demande le “huitième” caractère de la séquence, mais il n’y a que sept caractères présents. Lorsque quelque chose ne va pas que Java ne sait pas comment gérer, il lance une exception, comme indiqué ici:
java.lang.StringIndexOutOfBoundsException: String index out of range: 7
Trouver un index
La méthode indexOf()
examine les caractères de la chaîne et trouve le premier index qui correspond à la valeur souhaitée. La méthode indexOf
peut fonctionner avec un caractère individuel ou une chaîne entière comme entrée. Elle peut également commencer à partir d’une position demandée. N’oubliez pas qu’un char
peut être passé à un paramètre de type int
. Les signatures des méthodes sont les suivantes:
public int indexOf(int ch)
public int indexOf(int ch, int fromIndex)
public int indexOf(String str)
public int indexOf(String str, int fromIndex)
Le code suivant vous montre comment utiliser indexOf()
:
var nom = "animaux";
System.out.println(nom.indexOf('a')); // 0
System.out.println(nom.indexOf("al")); // 4
System.out.println(nom.indexOf('a', 4)); // 4
System.out.println(nom.indexOf("al", 5)); // -1
Puisque les index commencent par 0, le premier ‘a’ correspond à cette position. La deuxième instruction recherche une chaîne plus spécifique, elle correspond donc plus tard. La troisième instruction dit à Java de ne même pas regarder les caractères jusqu’à ce qu’il arrive à l’index 4. La dernière instruction ne trouve rien car elle commence à chercher après que la correspondance s’est produite. Contrairement à charAt()
, la méthode indexOf()
ne lance pas d’exception si elle ne peut pas trouver de correspondance, renvoyant plutôt -1. Comme les index commencent par 0, l’appelant sait que -1 ne pourrait pas être un index valide. Cela en fait une valeur courante pour qu’une méthode signale à l’appelant qu’aucune correspondance n’est trouvée.
Obtenir une sous-chaîne (substring)
La méthode substring()
recherche également des caractères dans une chaîne. Elle renvoie des parties de la chaîne. Le premier paramètre est l’index par lequel commencer pour la chaîne renvoyée. Comme d’habitude, il s’agit d’un index à base zéro. Il y a un deuxième paramètre optionnel, qui est l’index de fin auquel vous voulez vous arrêter.
Notez que nous avons dit “s’arrêter à” plutôt que “inclure”. Cela signifie que le paramètre endIndex
est autorisé à être un au-delà de la fin de la séquence si vous voulez vous arrêter à la fin de la séquence. Ce serait redondant, cependant, puisque vous pourriez omettre complètement le deuxième paramètre dans ce cas. Les signatures des méthodes sont les suivantes:
public String substring(int beginIndex)
public String substring(int beginIndex, int endIndex)
Il est utile de penser aux index un peu différemment pour les méthodes substring. Faites comme si les index étaient juste avant le caractère auquel ils pointeraient. La figure 4.2 aide à visualiser cela. Notez comment la flèche avec le 0 pointe vers le caractère qui aurait l’index 0. La flèche avec le 1 pointe entre les caractères avec les index 0 et 1. Il y a sept caractères dans la chaîne. Puisque Java utilise des index à base zéro, cela signifie que le dernier caractère a un index de 6. La flèche avec le 7 pointe immédiatement après ce dernier caractère. Cela vous aidera à vous rappeler que endIndex
ne donne pas d’exception hors limites lorsqu’il est un au-delà de la fin de la chaîne.
a | n | i | m | a | u | x | |
↑ 0 | ↑ 1 | ↑ 2 | ↑ 3 | ↑ 4 | ↑ 5 | ↑ 6 | ↑ 7 |
Index pour une sous-chaîne
Le code suivant montre comment utiliser substring()
:
var nom = "animaux";
System.out.println(nom.substring(3)); // maux
System.out.println(nom.substring(nom.indexOf('m'))); // maux
System.out.println(nom.substring(3, 4)); // m
System.out.println(nom.substring(3, 7)); // maux
La méthode substring()
est la méthode String
la plus délicate. Le premier exemple dit de prendre les caractères commençant par l’index 3 jusqu’à la fin, ce qui nous donne “maux”. Le deuxième exemple fait la même chose, mais il appelle indexOf()
pour obtenir l’index plutôt que de le coder en dur. C’est une pratique courante lors de la programmation car vous ne connaissez peut-être pas l’index à l’avance.
Le troisième exemple dit de prendre les caractères commençant par l’index 3 jusqu’à, mais sans inclure, le caractère à l’index 4. C’est une façon compliquée de dire que nous voulons une String
avec un seul caractère: celui à l’index 3. Cela donne “m”. Le dernier exemple dit de prendre les caractères commençant par l’index 3 jusqu’à ce que nous arrivions à l’index 7. Puisque l’index 7 est identique à la fin de la chaîne, c’est équivalent au premier exemple.
Nous espérons que ce n’était pas trop déroutant. Les exemples suivants sont moins évidents:
System.out.println(nom.substring(3, 3)); // chaîne vide
System.out.println(nom.substring(3, 2)); // exception
System.out.println(nom.substring(3, 8)); // exception
Le premier exemple de cet ensemble imprime une chaîne vide. La demande concerne les caractères commençant par l’index 3 jusqu’à ce que nous arrivions à l’index 3. Puisque nous commençons et terminons avec le même index, il n’y a pas de caractères entre les deux. Le deuxième exemple de cet ensemble lance une exception parce que les index ne peuvent pas être en arrière. Java sait parfaitement qu’il n’atteindra jamais l’index 2 s’il commence par l’index 3. Le troisième exemple dit de continuer jusqu’au huitième caractère. Il n’y a pas de huitième position, donc Java lance une exception. Il n’y a pas non plus de septième caractère, mais au moins il y a la position “fin de chaîne” invisible.
Révisons encore une fois car substring()
est si délicat. La méthode renvoie la chaîne à partir de l’index demandé. Si un index de fin est demandé, elle s’arrête juste avant cet index. Sinon, elle va jusqu’à la fin de la chaîne.
Ajustement de la casse
Après cet exercice mental, il est agréable d’avoir des méthodes qui font exactement ce qu’elles semblent faire! Ces méthodes facilitent la conversion de vos données. Les signatures des méthodes sont les suivantes:
public String toLowerCase()
public String toUpperCase()
Le code suivant montre comment utiliser ces méthodes:
var nom = "animaux";
System.out.println(nom.toUpperCase()); // ANIMAUX
System.out.println("Abc123".toLowerCase()); // abc123
Ces méthodes font ce qu’elles disent. La méthode toUpperCase()
convertit tous les caractères minuscules en caractères majuscules dans la chaîne renvoyée. La méthode toLowerCase()
convertit tous les caractères majuscules en caractères minuscules dans la chaîne renvoyée. Ces méthodes laissent inchangés tous les caractères autres que les lettres. De plus, rappelez-vous que les chaînes sont immuables, donc la chaîne originale reste la même.
Vérification d’égalité
La méthode equals()
vérifie si deux objets String
contiennent exactement les mêmes caractères dans le même ordre. La méthode equalsIgnoreCase()
vérifie si deux objets String
contiennent les mêmes caractères, à l’exception qu’elle ignore la casse des caractères. Les signatures des méthodes sont les suivantes:
public boolean equals(Object obj)
public boolean equalsIgnoreCase(String str)
Vous avez peut-être remarqué que equals()
prend un Object
plutôt qu’une String
. C’est parce que la méthode est la même pour tous les objets. Si vous passez quelque chose qui n’est pas une String
, elle retournera simplement false
. En revanche, la méthode equalsIgnoreCase()
ne s’applique qu’aux objets String
, donc elle peut prendre le type plus spécifique comme paramètre.
En Java, les valeurs String
sont sensibles à la casse. Cela signifie que “abc” et “ABC” sont considérés comme des valeurs différentes. Avec cela à l’esprit, le code suivant montre comment utiliser ces méthodes:
System.out.println("abc".equals("ABC")); // false
System.out.println("ABC".equals("ABC")); // true
System.out.println("abc".equalsIgnoreCase("ABC")); // true
Cet exemple devrait être assez intuitif. Dans le premier exemple, les valeurs ne sont pas exactement les mêmes. Dans le second, elles sont exactement les mêmes. Dans le troisième, elles ne diffèrent que par la casse, mais c’est acceptable car nous avons appelé la méthode qui ignore les différences de casse.
Surcharge de toString(), equals(Object) et hashCode()
Savoir comment surcharger correctement toString()
, equals(Object)
et hashCode()
est toujours important pour un développeur Java professionnel. Voici au moins les règles de base pour surcharger chacune de ces méthodes:
- toString(): La méthode
toString()
est appelée lorsque vous essayez d’imprimer un objet ou de concaténer l’objet avec uneString
. Elle est généralement surchargée avec une version qui imprime une description unique de l’instance en utilisant ses champs d’instance. - equals(Object): La méthode
equals(Object)
est utilisée pour comparer des objets, l’implémentation par défaut utilisant simplement l’opérateur ==. Vous devez surcharger la méthodeequals(Object)
chaque fois que vous voulez comparer commodément des éléments pour l’égalité, surtout si cela nécessite de vérifier de nombreux champs. - hashCode(): Chaque fois que vous surchargez
equals(Object)
, vous devez surchargerhashCode()
pour être cohérent. Cela signifie que pour deux objets quelconques, sia.equals(b)
est vrai, alorsa.hashCode()==b.hashCode()
doit également être vrai. S’ils ne sont pas cohérents, cela pourrait conduire à des données invalides et des effets secondaires dans les collections basées sur le hachage commeHashMap
etHashSet
.
Toutes ces méthodes fournissent une implémentation par défaut dans Object
, mais si vous voulez en faire une utilisation intelligente, vous devriez les surcharger.
Recherche de sous-chaînes
Souvent, vous devez rechercher une chaîne plus grande pour déterminer si une sous-chaîne y est contenue. Les méthodes startsWith()
et endsWith()
vérifient si la valeur fournie correspond à une partie de la String
. La méthode contains()
n’est pas aussi particulière; elle recherche des correspondances n’importe où dans la String
. Les signatures des méthodes sont les suivantes:
public boolean startsWith(String prefix)
public boolean endsWith(String suffix)
public boolean contains(CharSequence charSeq)
Le code suivant montre comment utiliser ces méthodes:
System.out.println("abc".startsWith("a")); // true
System.out.println("abc".startsWith("A")); // false
System.out.println("abc".endsWith("c")); // true
System.out.println("abc".endsWith("a")); // false
System.out.println("abc".contains("b")); // true
System.out.println("abc".contains("B")); // false
Encore une fois, rien de surprenant ici. Java effectue une vérification sensible à la casse sur les valeurs fournies. Notez que la méthode contains()
est une méthode de commodité pour que vous n’ayez pas à écrire str.indexOf(autreChaine) != -1
.
Remplacement de valeurs
La méthode replace()
effectue une simple recherche et remplacement sur la chaîne. Il existe une version qui prend des paramètres char
ainsi qu’une version qui prend des paramètres CharSequence
. Les signatures des méthodes sont les suivantes:
public String replace(char oldChar, char newChar)
public String replace(CharSequence target, CharSequence replacement)
Le code suivant montre comment utiliser ces méthodes:
System.out.println("abcabc".replace('a', 'A')); // AbcAbc
System.out.println("abcabc".replace("a", "A")); // AbcAbc
Le premier exemple utilise la première signature de méthode, en passant des paramètres char
. Le deuxième exemple utilise la deuxième signature de méthode, en passant des paramètres String
.
Suppression des espaces blancs
Ces méthodes suppriment les espaces blancs du début et/ou de la fin d’une String
. Les méthodes strip()
et trim()
suppriment les espaces blancs du début et de la fin d’une String
. En termes de programmation, les espaces blancs consistent en espaces ainsi que les caractères \t (tabulation) et \n (nouvelle ligne). D’autres caractères, comme \r (retour chariot), sont également inclus dans ce qui est supprimé. La méthode strip()
fait tout ce que fait trim()
, mais elle prend en charge Unicode.
De plus, la méthode stripLeading()
supprime les espaces blancs du début d’une String
et les laisse à la fin. La méthode stripTrailing()
fait l’inverse. Elle supprime les espaces blancs de la fin de la String
et les laisse au début. Les signatures des méthodes sont les suivantes:
public String strip()
public String stripLeading()
public String stripTrailing()
public String trim()
Le code suivant montre comment utiliser ces méthodes:
System.out.println("abc".strip()); // abc
System.out.println("\t a b c\n".strip()); // a b c
String texte = " abc\t ";
System.out.println(texte.trim().length()); // 3
System.out.println(texte.strip().length()); // 3
System.out.println(texte.stripLeading().length()); // 5
System.out.println(texte.stripTrailing().length()); // 4
D’abord, rappelez-vous que \t est un seul caractère. La barre oblique inverse échappe le t pour représenter une tabulation. Le premier exemple imprime la chaîne originale car il n’y a pas de caractères d’espaces blancs au début ou à la fin. Le deuxième exemple se débarrasse de la tabulation initiale, des espaces suivants et du saut de ligne final. Il laisse les espaces qui sont au milieu de la chaîne.
Les exemples restants affichent simplement le nombre de caractères restants. Vous pouvez voir que trim()
et strip()
laissent les mêmes trois caractères “abc” car ils suppriment à la fois les espaces blancs de début et de fin. La méthode stripLeading()
ne supprime que le caractère d’espace blanc au début de la String
. Elle laisse la tabulation et l’espace à la fin. La méthode stripTrailing()
supprime ces deux caractères à la fin mais laisse le caractère au début de la String
.
Travail avec l’indentation
Maintenant que Java prend en charge les blocs de texte, il est utile d’avoir des méthodes qui traitent de l’indentation. Ces deux méthodes sont un peu délicates, alors lisez attentivement!
public String indent(int nombreEspaces)
public String stripIndent()
La méthode indent()
ajoute le même nombre d’espaces vides au début de chaque ligne si vous passez un nombre positif. Si vous passez un nombre négatif, elle essaie de supprimer ce nombre de caractères d’espace blanc du début de la ligne. Si vous passez zéro, l’indentation ne changera pas.
Si vous appelez indent()
avec un nombre négatif et essayez de supprimer plus de caractères d’espace blanc qu’il n’y en a au début de la ligne, Java supprimera tout ce qu’il peut trouver.
Cela semble assez simple. Cependant, indent()
normalise également les caractères d’espace blanc. Que signifie normaliser les espaces blancs, vous demandez-vous? Tout d’abord, un saut de ligne est ajouté à la fin de la chaîne s’il n’y en a pas déjà. Deuxièmement, tous les sauts de ligne sont convertis au format \n. Indépendamment du fait que votre système d’exploitation utilise \r\n (Windows) ou \n (Mac/Unix), Java standardisera sur \n pour vous.
La méthode stripIndent()
est utile lorsqu’une String
a été construite avec concaténation plutôt qu’en utilisant un bloc de texte. Elle se débarrasse de tous les espaces blancs parasites. Cela signifie que toutes les lignes non vides sont décalées vers la gauche de sorte que le même nombre de caractères d’espace blanc sont supprimés de chaque ligne et que le premier caractère qui reste n’est pas un espace blanc. Comme indent()
, \r\n est transformé en \n. Cependant, la méthode stripIndent()
n’ajoute pas de saut de ligne à la fin s’il manque.
Eh bien, c’était beaucoup de règles. Le tableau 4.1 fournit une référence pour les rendre plus faciles à mémoriser.
Méthode | Changement d’indentation | Normalise les sauts de ligne existants | Ajoute un saut de ligne à la fin si manquant |
---|---|---|---|
indent(n) où n > 0 | Ajoute n espaces au début de chaque ligne | Oui | Oui |
indent(n) où n == 0 | Pas de changement | Oui | Oui |
indent(n) où n < 0 | Supprime jusqu’à n espaces de chaque ligne où le même nombre de caractères est supprimé de chaque ligne non vide | Oui | Oui |
stripIndent() | Supprime tous les espaces blancs parasites principaux | Oui | Non |
Règles pour indent()
et stripIndent()
Le code suivant montre comment utiliser ces méthodes. Ne vous inquiétez pas si les résultats ne sont pas ceux que vous attendez. Nous expliquons chacun d’entre eux.
var bloc = """
a
b
c""";
var concat = " a\n"
+ " b\n"
+ " c";
System.out.println(bloc.length()); // 6
System.out.println(concat.length()); // 9
System.out.println(bloc.indent(1).length()); // 10
System.out.println(concat.indent(-1).length()); // 7
System.out.println(concat.indent(-4).length()); // 6
System.out.println(concat.stripIndent().length()); // 6
Les lignes 1-7 créent des chaînes similaires en utilisant un bloc de texte et une String
régulière, respectivement. Nous disons “similaires” car concat
a un caractère d’espace blanc au début de chaque ligne alors que bloc
n’en a pas.
La ligne 8 compte les six caractères dans bloc
, qui sont les trois lettres, l’espace vide avant b, et le \n après a et b. La ligne 9 compte les neuf caractères dans concat
, qui sont les trois lettres, un espace vide avant a, deux espaces vides avant b, un espace vide avant c, et le \n après a et b. Comptez-les vous-même. Si vous ne comprenez pas quels caractères sont comptés, cela deviendra encore plus déroutant.
À la ligne 10, nous demandons à Java d’ajouter un seul espace vide à chacune des trois lignes dans bloc
. Cependant, la sortie indique que nous avons ajouté 4 caractères plutôt que 3 puisque la longueur est passée de 6 à 10. Ce caractère supplémentaire mystérieux est dû à la normalisation des terminaisons de ligne. Comme le bloc de texte n’a pas de saut de ligne à la fin, indent()
en ajoute un!
À la ligne 11, nous supprimons un caractère d’espace blanc de chacune des trois lignes de concat
. Cela donne une longueur de sept. Nous avons commencé avec neuf, nous avons retiré trois caractères et nous avons ajouté une terminaison de ligne normalisée.
À la ligne 12, nous demandons à Java de supprimer quatre caractères d’espace blanc des mêmes trois lignes. Comme il n’y a pas quatre caractères d’espace blanc, Java fait de son mieux. L’espace unique est supprimé avant a et c. Les deux espaces sont supprimés avant b. La longueur de six devrait maintenant avoir du sens ici; nous avons supprimé un caractère de plus ici qu’à la ligne 11.
Enfin, la ligne 13 utilise la méthode stripIndent()
. Toutes les lignes ont au moins un caractère d’espace blanc. Comme elles n’ont pas toutes deux caractères d’espace blanc, la méthode ne se débarrasse que d’un caractère par ligne. Comme aucune nouvelle ligne n’est ajoutée par stripIndent()
, la longueur est de six, soit trois de moins que les neuf originaux.
Traduction des échappements
Lorsque nous échappons des caractères, nous utilisons une seule barre oblique inverse. Par exemple, \t est une tabulation. Si nous ne voulons pas ce comportement, nous ajoutons une autre barre oblique inverse pour échapper la barre oblique inverse, donc \\t est une chaîne littérale \t. La méthode translateEscapes()
prend ces littéraux et les transforme en caractère échappé équivalent. La signature de la méthode est la suivante:
public String translateEscapes()
Le code suivant montre comment utiliser ces méthodes:
var str = "1\\t2";
System.out.println(str); // 1\t2
System.out.println(str.translateEscapes()); // 1 2
La première ligne imprime la chaîne littérale \t car la barre oblique inverse est échappée. La deuxième ligne imprime une tabulation réelle puisque nous avons traduit l’échappement. Cette méthode peut être utilisée pour les séquences d’échappement telles que \t (tabulation), \n (nouvelle ligne), \s (espace), \” (guillemet double) et \’ (guillemet simple).
Vérification des chaînes vides ou blanches
Java fournit des méthodes pratiques pour savoir si une String
a une longueur de zéro ou ne contient que des caractères d’espace blanc. Les signatures des méthodes sont les suivantes:
public boolean isEmpty()
public boolean isBlank()
Le code suivant montre comment utiliser ces méthodes:
System.out.println(" ".isEmpty()); // false
System.out.println("".isEmpty()); // true
System.out.println(" ".isBlank()); // true
System.out.println("".isBlank()); // true
La première ligne imprime false
car la String
n’est pas vide; elle a un espace vide. La deuxième ligne imprime true
car cette fois, il n’y a pas de caractères dans la String
. Les deux dernières lignes impriment true
car il n’y a pas de caractères autres que des espaces blancs présents.
Formatage des valeurs avec String en Java
Il existe des méthodes pour formater les valeurs String
en utilisant des drapeaux de formatage. Deux des méthodes prennent la chaîne de format comme paramètre, et l’autre utilise une instance pour cette valeur. Une méthode prend un Locale
.
Les paramètres de la méthode sont utilisés pour construire une String
formatée en un seul appel de méthode, plutôt que via beaucoup d’opérations de format et de concaténation. Ils renvoient une référence à l’instance sur laquelle ils sont appelés afin que les opérations puissent être enchaînées. Les signatures des méthodes sont les suivantes:
public static String format(String format, Object args...)
public static String format(Locale loc, String format, Object args...)
public String formatted(Object args...)
Le code suivant montre comment utiliser ces méthodes:
var nom = "Camille";
var numeroCommande = 5;
// Tous impriment: Bonjour Camille, commande 5 est prête
System.out.println("Bonjour "+nom+", commande "+numeroCommande+" est prête");
System.out.println(String.format("Bonjour %s, commande %d est prête",
nom, numeroCommande));
System.out.println("Bonjour %s, commande %d est prête"
.formatted(nom, numeroCommande));
Dans les opérations format()
et formatted()
, les paramètres sont insérés et formatés via des symboles dans l’ordre où ils sont fournis dans le vararg. Le tableau 4.2 liste ceux que vous devriez connaître.
Symbole | Description |
---|---|
%s | S’applique à tout type, communément les valeurs String |
%d | S’applique aux valeurs entières comme int et long |
%f | S’applique aux valeurs à virgule flottante comme float et double |
%n | Insère un saut de ligne en utilisant le séparateur de ligne dépendant du système |
TABLE 4.2 Symboles de formatage courants
L’exemple suivant utilise les quatre symboles du tableau 4.2:
var nom = "Jules";
var score = 90.25;
var total = 100;
System.out.println("%s:%n Score: %f sur %d"
.formatted(nom, score, total));
Cela imprime:
Jules:
Score: 90.250000 sur 100
Le mélange de types de données peut provoquer des exceptions lors de l’exécution. Par exemple, ce qui suit lance une exception car un nombre à virgule flottante est utilisé lorsqu’une valeur entière est attendue:
var str = "Nourriture: %d tonnes".formatted(2.0); // IllegalFormatConversionException
Utilisation de format() avec des drapeaux
En plus de supporter des symboles, Java supporte également des drapeaux optionnels entre le % et le caractère du symbole. Dans l’exemple précédent, le nombre à virgule flottante a été imprimé comme 90.250000. Par défaut, %f affiche exactement six chiffres après la décimale. Si vous voulez n’afficher qu’un chiffre après la décimale, vous pouvez utiliser %.1f au lieu de %f. La méthode format()
s’appuie sur l’arrondi plutôt que sur la troncature lors du raccourcissement des nombres. Par exemple, 90.250000 sera affiché comme 90.3 (et non 90.2) lorsqu’il est passé à format()
avec %.1f.
La méthode format()
prend également en charge deux fonctionnalités supplémentaires. Vous pouvez spécifier la longueur totale de la sortie en utilisant un nombre avant le symbole décimal. Par défaut, la méthode remplira l’espace vide avec des espaces vides. Vous pouvez également remplir l’espace vide avec des zéros en plaçant un seul zéro avant le symbole décimal. Les exemples suivants utilisent des crochets, [], pour montrer le début/la fin de la valeur formatée:
var pi = 3.14159265359;
System.out.format("[%f]",pi); // [3.141593]
System.out.format("[%12.8f]",pi); // [ 3.14159265]
System.out.format("[%012f]",pi); // [00003.141593]
System.out.format("[%12.2f]",pi); // [ 3.14]
System.out.format("[%.3f]",pi); // [3.142]
La méthode format()
prend en charge beaucoup d’autres symboles et drapeaux.
Chaînage de méthodes avec String en Java
Prêt à mettre en pratique tout ce que vous venez d’apprendre? Il est courant d’appeler plusieurs méthodes comme montré ici:
var debut = "AniMaL ";
var coupe = debut.trim(); // "AniMaL"
var minuscule = coupe.toLowerCase(); // "animal"
var resultat = minuscule.replace('a', 'A'); // "AnimAl"
System.out.println(resultat);
Il s’agit simplement d’une série de méthodes String. Chaque fois que l’une est appelée, la valeur retournée est placée dans une nouvelle variable. Il y a quatre valeurs String en cours de route, et AnimAl est affiché.
Cependant, il y a une tendance à entasser autant de code que possible dans un petit espace. Vous verrez du code utilisant une technique appelée chaînage de méthodes. Voici un exemple:
String resultat = "AniMaL ".trim().toLowerCase().replace('a', 'A');
System.out.println(resultat);
Ce code est équivalent à l’exemple précédent. Il crée également quatre objets String et affiche AnimAl. Pour lire du code qui utilise le chaînage de méthodes, commencez par la gauche et évaluez la première méthode. Puis appelez la méthode suivante sur la valeur retournée de la première méthode. Continuez jusqu’à ce que vous arriviez au point-virgule.
Que pensez-vous que le résultat de ce code est?
String a = "abc";
String b = a.toUpperCase();
b = b.replace("B", "2").replace('C', '3');
System.out.println("a=" + a);
System.out.println("b=" + b);
À la ligne 1, nous définissons a pour pointer vers “abc” et nous n’avons jamais pointé a vers autre chose. Comme aucun code aux lignes 2 et 3 ne change a, la valeur reste “abc”.
Cependant, b est un peu plus difficile. La ligne 2 fait pointer b vers “ABC”, ce qui est simple. À la ligne 3, nous avons chaînage de méthodes. D’abord, “ABC”.replace(“B”, “2”) est appelé. Cela renvoie “A2C”. Ensuite, “A2C”.replace(‘C’, ‘3’) est appelé. Cela renvoie “A23”. Enfin, b change pour pointer vers cette String retournée. Lorsque la ligne 5 s’exécute, b est “A23”.