Adloun

Chaînes de caractères et entrées

Cours · programmation Java (école d'ingénieur), chapitre 6 · école d'ingénieur, informatique · le début du chapitre, la suite sur Adloun

Presque tous les programmes manipulent du texte : un nom saisi au clavier, un mot de passe à vérifier, une ligne de fichier à découper, un message à afficher proprement. En Java, le texte est représenté par la classe String. Nous l'utilisons depuis le premier chapitre sans l'avoir étudiée ; il est temps de la connaître vraiment, ainsi que les caractères (char) qui la composent, et la classe Scanner, qui permet enfin à nos programmes de lire ce que l'utilisateur tape.

Objectifs du chapitre

  • Utiliser les méthodes de String : longueur, accès à un caractère, sous-chaînes, recherche, découpage, remplacement.
  • Comprendre qu'une String est un objet immuable, et comparer des chaînes avec equals et compareTo, jamais avec ==.
  • Manipuler les caractères et la classe Character.
  • Construire efficacement une chaîne avec StringBuilder, la mettre en forme avec printf.
  • Convertir entre chaînes et nombres ; lire au clavier avec Scanner ; utiliser les arguments du programme.

6.1 La classe String

6.1.1 Une chaîne est un objet

Définition 6.1Chaîne de caractères

Une chaîne de caractères est une suite de caractères, de type String. Une chaîne littérale s'écrit entre guillemets droits : "Bonjour". Les caractères sont numérotés à partir de , comme les cases d'un tableau ; s.length() donne leur nombre.

Contrairement à int ou double, String n'est pas un type primitif : c'est une classe, et chaque chaîne est un objet. On agit sur un objet en appelant ses méthodes avec la notation pointée : s.length(), s.toUpperCase(). Comme pour les tableaux, une variable de type String contient une référence vers l'objet, ou null.

length() contre length

Pour une chaîne, la longueur s'obtient par la méthode s.length(), avec des parenthèses ; pour un tableau, par l'attribut t.length, sans parenthèses. Le compilateur signale toute confusion par un « cannot find symbol ».

6.1.2 Les méthodes usuelles


/** Chapitre 6 — les méthodes usuelles de String. */
public class Chaines {
    public static void main(String[] args) {
        String s = "  Programmation Java  ";
        String t = s.trim();
        System.out.println("[" + t + "] longueur " + t.length());
        System.out.println(t.charAt(0) + " " + t.charAt(t.length() - 1));
        System.out.println(t.substring(0, 5) + " | " + t.substring(15));
        System.out.println(t.indexOf('a') + " " + t.indexOf("Java") + " " + t.indexOf('z'));
        System.out.println(t.contains("gram") + " " + t.startsWith("Pro") + " " + t.endsWith("java"));
        System.out.println(t.toUpperCase() + " / " + t.toLowerCase());
        System.out.println(t.replace('a', '@'));
        String[] mots = "le chat dort sur le tapis".split(" ");
        System.out.println(mots.length + " mots, le troisième est " + mots[2]);
        System.out.println(String.join("-", mots));
    }
}

[Programmation Java] longueur 18
P a
Progr | ava
5 14 -1
true true false
PROGRAMMATION JAVA / programmation java
Progr@mm@tion J@v@
6 mots, le troisième est dort
le-chat-dort-sur-le-tapis
AppelRésultat
s.length()nombre de caractères
s.charAt(i)caractère d'indice (un char)
s.substring(i, j)sous-chaîne des indices
s.substring(i)sous-chaîne de l'indice à la fin
s.indexOf(x)premier indice de x, ou
s.contains(x)contient x ?
s.startsWith(x)commence par x ?
s.endsWith(x)se termine par x ?
s.toUpperCase()tout en majuscules
s.toLowerCase()tout en minuscules
s.trim()sans les espaces de début et de fin
s.replace(a, b)chaque a remplacé par b
s.split(sep)tableau des morceaux, coupés à chaque sep
s.isEmpty()vrai si s.length() == 0
String.join(sep, t)cases de t reliées par sep

Quelques remarques sur l'exemple. t.substring(0, 5) donne les caractères d'indices à , soit Progr : comme pour Arrays.copyOfRange, le second indice est exclu, et la sous-chaîne a caractères. indexOf retourne le premier indice trouvé ( pour le 'a' de « Programmation ») et en cas d'absence. Enfin, endsWith("java") est faux : la casse compte, 'j' et 'J' sont deux caractères différents. Un indice hors de dans charAt ou substring provoque une StringIndexOutOfBoundsException.

L'argument de split est en réalité une expression régulière, un petit langage de description de motifs. Il suffit d'en connaître un cas : split(" +") découpe selon un ou plusieurs espaces, ce qui évite des morceaux vides quand les mots sont séparés par plusieurs espaces.

6.1.3 Les chaînes sont immuables

Proposition 6.2Immuabilité

Une String ne peut jamais être modifiée après sa création. Les méthodes qui semblent la transformer (toUpperCase, replace, trim…) retournent une nouvelle chaîne et laissent l'originale intacte.


/** Chapitre 6 — une String ne change jamais. */
public class Immuable {
    public static void main(String[] args) {
        String s = "java";
        s.toUpperCase();                         // résultat perdu : s ne change pas
        System.out.println(s);
        s = s.toUpperCase();                     // on garde la nouvelle chaîne
        System.out.println(s);
    }
}

java
JAVA

La première instruction calcule bien "JAVA", mais ne la range nulle part : le résultat est perdu. Il faut écrire s = s.toUpperCase();, qui fait pointer s vers la nouvelle chaîne. C'est une erreur fréquente, que le compilateur ne signale pas.

6.2 Comparer des chaînes

6.2.1 equals, jamais ==


/** Chapitre 6 — comparer des chaînes : equals, pas ==. */
public class Egalite {
    public static void main(String[] args) {
        String a = "java";
        String b = "ja" + "va";                  // calculée à la compilation
        String debut = "ja";
        String c = debut + "va";                 // calculée à l'exécution
        System.out.println("a == b : " + (a == b));
        System.out.println("a == c : " + (a == c));
        System.out.println("a.equals(c) : " + a.equals(c));
        System.out.println("equalsIgnoreCase : " + "Java".equalsIgnoreCase(a));
        System.out.println("compareTo : " + "abricot".compareTo("banane") + " "
                + "banane".compareTo("abricot") + " " + a.compareTo(c));
        System.out.println("compareTo majuscules : " + "Zoe".compareTo("anna"));
    }
}

a == b : true
a == c : false
a.equals(c) : true
equalsIgnoreCase : true
compareTo : -1 1 0
compareTo majuscules : -7

La suite du cours est sur Adloun

Le chapitre en entier, formules et figures comprises, avec le tuteur, les fiches, les QCM et les exercices.

Lire la suite du cours

En accès libre, sans inscription.

Exercices corrigés de ce chapitre

Lire la suite du cours →