Accès rapide :
La vidéo
Rappels sur les standards d'encodage de caractères
Utilisation du type java.lang.String
Séquences de caractères particulières
Comparaison de chaînes de caractères
Quelques méthodes de traitement de chaînes de caractères
Conversions types primitifs / chaînes de caractères
Cette vidéo vous montre comment utiliser les chaînes de caractères en Java. On y insiste sur l'aspect immuable des chaînes de caractères Java ainsi que sur la manière de correctement comparer deux chaînes. Quelques méthodes de la classe String vous sont aussi présentées.
Pour un rappel sur les standards d'encodage de caractères, je vous renvoie vers le chapitre précédent qui traite de ce sujet : activez ce lien pour consulter ce chapitre.
Une chaîne de caractères s'introduit par le type String. L'ensemble des caractères de la chaîne sont compris entre deux double-guillemets. Voici un exemple de déclaration de chaînes de caractères.
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Demo { public static final void main( String [] args ) { String firstName = "Diego"; String lastName = "De La Vega"; System.out.println( firstName + " - " + lastName ); } } |
En fait le type String
peut aussi s'écrire java.lang.String
. Bien entendu, l'informaticien (étant fainéant),
préferera le plus souvent la première approche. Voici un exemple de code montrant cette seconde écriture faisant apparaître le paquetage
java.lang
(la classe String
est contenu dans le paquetage java.lang
).
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Demo { public static final void main( String [] args ) { java.lang.String firstName = "Diego"; java.lang.String lastName = "De La Vega"; System.out.println( firstName + " - " + lastName ); } } |
import
.
Néanmoins, le paquetage java.lang
est visible par défaut. D'où le fait que vous puissiez utiliser la notation courte sans
utilisation du mot clé import
.
Contrairement aux types étudiés précédemment (int
, long
, float
, double
, boolean
, ...),
vous aurez noté que le type String commence par une majuscule. Cette remarque est pertinente. Les types commençant par une minuscule (int
, ...)
sont appelés types primitifs (ou parfois types scalaires). Les types commençant par des majuscules sont appelés types objets
(classes, interfaces, enums, ...). Dans le cas de String
, nous avons plus précisément à faire à une classe.
Pour l'heure, nous noterons qu'une seule différence entre types primitifs et types objets : les types objets exposent des méthodes, en quelques sortes
des fonctions, alors que les types primitifs n'en exposent pas.
A titre d'exemple, notez l'utilisation des méthodes toLowerCase
et toUpperCase
dans le code suivant.
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Demo { public static final void main( String [] args ) { String firstName = "Diego"; String lastName = "De La Vega"; System.out.println( firstName.toLowerCase() + " - " + lastName.toUpperCase() ); } } |
Comme vous le constatez sur l'exemple ci-dessus, il est possible de concaténer des chaînes de caractères avec l'opérateur +
.
Il est aussi possible d'utiliser l'opérateur +=
, comme le montre ce nouvel exemple.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Demo { public static final void main( String [] args ) { String firstName = "Diego".toLowerCase(); String lastName = "De La Vega".toUpperCase(); String fullString = firstName + " " + lastName; fullString += " !"; System.out.println( fullString ); // Affiche : diego DE LA VEGA ! } } |
Tout comme nous l'avons vu, dans le chapitre précédent sur l'utilisation de caractères, il existe des séquences particulières permettant d'utiliser des caractères spéciaux ou non accessibles à partir de votre clavier.
Un retour à la ligne : \n | String str = "Hello\n"; |
---|---|
Une tabulation : \t | String str = "First\tSecond"; |
Une double guillemet : \" | String str = "Un \" au milieu"; |
Un caractère : \\ | String str = "C:\\Folder\\file.txt"; |
Utilisation de la notation unicode de Java (sur 4 digits et en hexadécimal) |
String str = "\u03c0 vaut environ 3.141592654"; // Un caractère PI en minuscule |
Utilisation de caractères spéciaux | char c1 = '\n'; // Un retour à la ligne char c2 = '\t'; // Une tabulation char c3 = '\\'; // Tout simplement un \ char c4 = '\''; // Un caractère ' |
L'opérateur ==
peut être utilisé entre deux chaînes de caractères. Pour autant il ne va pas forcément calculer ce à quoi vous vous attendez.
A titre d'exemple, exécutez ce code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public class Demo { public static void main( String [] args ) { String first = "toto"; String temp = "to"; String second = temp + temp; if ( first == second ) { System.out.println( "Les deux chaînes sont identiques" ); } } } |
Comme vous l'avez certainement constaté, aucun affichage n'est produit : c'est normal. L'opérateur ==
utilisé sur des types objets
(ici nos chaînes de caractères) ne regarde pas si les caractères des deux chaînes sont égaux deux à deux. Ce qu'il vérifie, c'est si les
deux pointeurs (les deux adresses en mémoire) des deux variables first
et second
sont égaux ou non. Dit autrement
on regarde si les deux variables pointent au même endroit en mémoire, si c'est le même objet.
En effet, toutes les variables basées sur des types objets (des types qui commencent par une majuscule, comme String) sont en fait des pointeurs
(des adresses en mémoire) qui référencent des objets. Le meilleur moyen de valider qu'une chaîne de caractères est un pointeur et de compiler le
programme suivant qui initialise str
à l'adresse 0 (le pointeur nul). On spécifie une adresse initialisée à 0 en utilisant le mot clé
réservé null
. Comme tout mot clé réservé du langage, null
doit s'écrire en minuscule.
1 2 3 4 5 6 7 8 9 10 |
public class Demo { public static void main( String [] args ) { String str = null; System.out.println( str ); } } |
Du coup, la question que vous devez avoir en tête est la suivante : ok, mais comment comparer deux chaînes de caractères entre elles ?
En fait, il vous faut utiliser une méthode de la classe String
: la méthode equals
.
Analysez le code suivant et essayez de déduire les affichages qu'il produit.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class Demo { public static void main( String [] args ) { String temp = "to"; String first = "toto"; String second = temp + temp; String third = first; // Copie de pointeur (aucune duplication de chaîne) String fourth = "toto"; System.out.println( first == second ); System.out.println( first.equals( second ) ); System.out.println( first == third ); System.out.println( first.equals( third ) ); System.out.println( first == fourth ); System.out.println( first.equals( fourth ) ); System.out.println( first == "Java" ); System.out.println( first.equals( "Java" ) ); } } |
Nous allons maintenant vérifier vos déductions, avec l'affichage produit par le programme ci-dessus.
$> javac Demo.java $> java Demo false true true true true true false false $>
third
et first
pointent donc au même endroit en mémoire. On compare donc
first à lui-même sur les lignes 15 et 16.
.class
en un unique exemplaire. Cela explique que l'opérateur ==
renvoie true
sur la comparaison considérée. Du coup, l'appel à equals
renverra aussi true
car on compare la même donnée en mémoire.
equals
et non pas l'opérateur ==
.
String
est implémentée de manière à produire des objets (des chaînes de caractères) immuables (on dit aussi parfois immutables).
Une fois une chaîne produite, il n'est plus possible de changer son état (son contenu). Par contre, diverses méthodes permettent de produire de nouvelles
chaînes de caractères modifiées à partir d'une chaîne originale. Notez enfin, qu'une variable de type String
peut être réaffectée sur une
nouvelle chaîne modifiée.
La conséquence directe de la remarque précédente, est que toute méthode de transformation de chaînes de caractères proposé par la classe String
renvoient un résultat de type String
: la nouvelle chaîne de caractère modifiée.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public class Demo { public static void main( String [] args ) { String original = "Diego De La Vega"; String transformation = original.toUpperCase(); System.out.println( transformation ); // Affiche : DIEGO DE LA VEGA System.out.println( "Compact Sample".toLowerCase() ); // Affiche : compact sample } } |
Comme indiqué dans la note, il est possible de réaffecter le résultat d'une transformation à la variable, comme le montre l'exemple suivant.
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Demo { public static void main( String [] args ) { String zorro = "Diego De La Vega"; zorro = zorro.toLowerCase(); System.out.println( zorro ); // Affiche : diego de la vega } } |
Le tableau suivant propose quelques méthodes utiles proposées par la classe String
.
Nom de la méthode | Description | Exemple d'utilisation |
---|---|---|
int indexOf( String subString ); | Recherche de la présence d'une sous-chaîne dans la chaîne d'origine. Renvoie -1 si la sous chaine n'est pas présente. Sinon, l'indice de la première occurrence trouvée est renvoyé. Attention, les indices commencent à 0 (d'où le -1 en cas d'échec). | int l = "abcdef".indexOf( "cd" ); // 2 int l = "abcdef".indexOf( "gh" ); // -1 |
int lastIndexOf( String subString ); | Recherche de la présence d'une sous-chaîne dans la chaîne d'origine. Renvoie -1 si la sous chaine n'est pas présente. Sinon, l'indice de la dernière occurrence trouvée est renvoyé. Attention, les indices commencent à 0 (d'où le -1 en cas d'échec). | int l = "abcdab".lastIndexOf( "ab" ); // 4 int l = "abcdab".lastIndexOf( "ij" ); // -1 |
int length(); | Calcule la taille de la chaîne de caractères | int l = "toto".length(); // 4 |
String replace( CharSequence target, CharSequence replacement ); | Remplace toutes les occurrences de target par replacement . |
String str = "abcdabcd".replace( "b", "e" ); System.out.println( str ); // aecdaecd |
String [] split( String pattern ); | Découpe une chaîne de caractères en sous-chaînes à partir d'un séparateur (plus ou moins complexe). | String [] parts = "19/01/2018".split( "/" ); System.out.println( parts[0] ); // 19 System.out.println( parts[1] ); // 01 System.out.println( parts[2] ); // 2018 |
String substring( int first, int afterLast ); | Extrait une sous chaîne de caractères. Attention, le second paramètre doit être fixé à 1 de plus que l'indice de dernier caractère à extraire. Les indices doivent commencer à 0. | String str = "abcdef".substring( 2, 4 ); // cd |
String trim(); | Enlève les blancs (espaces, tabulations) devant et derrière la chaîne. | String str = " Toto ".trim(); // Toto |
String toLowerCase(); | Transforme la chaîne de caractères en minuscules | String str = "Toto".toLowerCase(); // toto |
String toUpperCase(); | Transforme la chaîne de caractères en majuscules | String str = "Toto".toUpperCase(); // TOTO |
Voici un petit exemple d'utilisation de méthodes de la classe String
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Demo { public static void main( String [] args ) { String message = "This is a String with Unicode characters (\u03c0)"; System.out.println( message ); String upper = message.toUpperCase(); System.out.println( upper ); String lower = message.toLowerCase(); System.out.println( lower ); System.out.println( message ); String subPart = message.substring( 22, 29 ); System.out.println( subPart + "!" ); String [] parts = message.split( " " ); for (String str : parts) { System.out.print( str + " - " ); } System.out.println(); String replacement = message.replace( "String", "Truc" ); System.out.println( replacement ); } } |
java.lang.String
, consultez notre
documentation de l'API Java.
Il est possible de convertir des valeurs numériques (de type int
, long
, float
, double
, ...) en
chaînes de caractères et réciproquement. Idem pour les booléen. Pour ce faire, il faut utiliser les méthodes statiques proposées par la classe
enveloppante (Wrapped Class) associée à chaque type primitif. Le tableau suivant précise le nom de ces classes
Nom du type primitif | Nom de la classe associée |
---|---|
byte | java.lang.Byte |
short | java.lang.Short |
int | java.lang.Integer |
long | java.lang.Long |
float | java.lang.Float |
double | java.lang.Double |
char | java.lang.Character |
boolean | java.lang.Boolean |
java.lang
est importé par défaut, l'utilisation du préfixe n'est pas obligatoire.
Voici un exemple d'utilisation de ces classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
public class Demo { public static void main( String [] args ) { String strValue = "123"; int value = Integer.parseInt( strValue ); strValue = "3.141592654"; double value2 = Double.parseDouble( strValue ); System.out.println( value + " - " + value2 ); String finalString = value + ""; finalString += " "; finalString += Double.toString( value2 ); System.out.println( finalString ); // Exemple d'affichage formaté : les différents formats seront vus dans un prochain chapitre String strFinal2 = String.format( "%05d [%05.2f]", value, value2 ); System.out.println( strFinal2 ); } } |
Et voici le résultat produit par cet exemple.
$> javac Demo.java $> java Demo 123 - 3.141592654 123 3.141592654 00123 [03,14] $>
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :