Structures de contrôle

Structures de contrôle #

Les structures de contrôle permettent de modifier le flux d’exécution d’un programme. Vous avez déjà abordé ces concepts lors de précédents cours. Ce chapitre propose de parcourir la syntaxe et de découvrir quelques nouveautés de Java.

Branchement conditionnel #

Syntaxe générale de l’instruction if #

1
2
3
4
5
6
7
8
9
if (condition1) {
  ...
} else if (condition2) {
  ...
} else if (condition3) {
  ...
} else {
  ...
}

Syntaxe générale de l’instruction switch #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
switch (expression) {
  case constant1:
    ...
    break;
  case constant2:
    ...
    break;
  case constant3:
    ...
    break;
  default:
    ...
}   

Dans l’exemple d’utilisation ci-dessous, le mot-clé break a été omis. Il est rarement utile de ne pas l’indiquer. Le code devient difficile à comprendre.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int i = 2;
switch (i) {
  case 1:
    System.out.println("Un");
  case 2: 
    System.out.println("Deux");
  case 3: 
    System.out.println("Trois");
  default:
    System.out.println("...");
}

Même exemple corrigé:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
int i = 2;
switch (i) {
  case 1:
    System.out.println("Un");
    break;
  case 2: 
    System.out.println("Deux");
    break;
  case 3: 
    System.out.println("Trois");
    break;
  default:
    System.out.println("...");
}

Syntaxe générale de l’expression switch #

Le switch peut s’utiliser en tant qu’expressions, par opposition à une instruction. C’est-à-dire qu’elle peut retourner une valeur. Introduite dans la version 14 de Java (2020), aucune ambiguïté n’est possible avec le break. Celui-ci est implicite.

1
2
3
4
5
6
7
int i = 2;
String hello = switch (i) {
  case 1 -> "Un";
  case 2 -> "Deux";
  case 3 -> "Trois";
  default -> "...";
}

L’expression switch peut également être employée avec une syntaxe proche des anciennes versions à l’aide du mot-clé yield, évitant les défauts lié au break.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int i = 2;
String hello = switch (i) {
  case 1:
    yield "Un";
  case 2:
    yield "Deux";
  case 3:
    yield "Trois";
  default: {
    /* les blocs sont possibles */
    yield "...";
  }
}

Expression conditionnelle #

Syntaxe générale: valeur = condition ? valeur_si_vrai : valeur_si_faux;

L’instruction:

1
2
3
4
5
6
String type;
if (age >= 18) {
  type = "Majeur";
} else {
  type = "Mineur";
}

devient, à l’aide d’une expression conditionnelle:

String type = age >= 18 ? "Majeur" : "Mineur";

Conseil
Evitez le code inutile dans vos fonctions. Le motif ci-dessous est un exemple que je vois couramment chez les étudiants lorsqu’il est nécessiare de vérifier une condition :

1
2
3
4
5
6
7
boolean isAdult(int age) {
  if (age >= 18) {
    return true;
  } else {
    return false;
  }
}

La condition peut directement être retournée:

1
2
3
boolean isAdult(int age) {
  return age >= 18;
}

Autre exemple où l’expression ternaire peut raccourcir le code:

1
2
3
4
5
6
7
int min(int a, int b) {
  if (a < b) {
    return a;
  } else {
    return b;
  }
}

Peut être remplacé par:

1
2
3
int min(int a, int b) {
  return a < b ? a : b;
}

Les boucles #

Boucle préconditionnelle #

Répétition d’instruction tant qu‘une condition est vérifiée a priori

1
2
3
while ( condition ){
  ...
}

Voici un exemple

1
2
3
4
5
int i = ???;
while ( i < 4 ){
  System.out.format("Valeur de i: %d", i);
  i += 1;
}

Boucle post-conditionnelle #

Répétition d’instruction tant qu‘une condition est vérifiée a posteriori. Le bloc est exécuté au moins une fois.

1
2
3
do {
  ...
} while ( condition );

Voici un exemple:

1
2
3
4
5
int i = ???; 
do {
  System.out.format("Valeur de i: %d", i);
  i += 1;
} while ( i < 4 );

Boucle d’itération #

Cette boucle reste une boucle préconditionnelle.

1
2
3
for (initialisation; condition; iteration) {
  ...
} 

Exemple de parcours d’un tableau statique:

1
2
3
4
5
6
String[] greetings = {"Bonjour", "Coucou", "Salut"};

// Affiche les trois chaînes de caractères du tableau
for (int i = 0; i < greetings.length; i+=1) {
  System.out.println( greetings[i] );
} 

Boucle de parcours #

Cette boucle est à privilégier lorsque vous parcourez des collections. Elle garantit que chaque élément est traité et elle permet de référencer l’élément directement et avec le bon type. Elle est donc plus sûre que les boucles précédentes et moins sujette aux erreurs.

Syntaxe:

1
2
3
4
for (type identifiant: collection) {
  // identifiant va prendre successivement toutes les valeurs
  // de la collection
} 

Exemple d’utilisation:

1
2
3
4
5
6
List<String> greetings = List.of("Bonjour", "Coucou", "Salut"); 

// Affiche les trois chaînes de caractères du tableau
for (String hello: greetings) {
  System.out.println( hello );
} 

Style déclaratif #

Ce style sera petit à petit privilégié pour la manipulation des collections. Si vous êtes à l’aise avec, vous pouvez déjà les utiliser.

1
2
3
4
5
List<String> greetings = List.of("Bonjour", "Coucou", "Salut");

// le forEach n'existe pas sur les tableaux statiques. Il faut 
// le transformer en une liste
greetings.forEach( hello -> System.out.println(hello) );











comments powered by Disqus