0% ont trouvé ce document utile (0 vote)
2 vues10 pages

Java Avance

Le document présente un guide avancé sur Java, couvrant des concepts tels que les generics, les collections, les lambdas, les streams, la concurrence, et les design patterns. Il inclut également des sections sur les entrées/sorties, les bonnes pratiques modernes, et les fonctionnalités récentes de Java. Chaque chapitre fournit des exemples pratiques et des explications détaillées pour aider les développeurs à maîtriser ces concepts.

Transféré par

Gégélekon
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
2 vues10 pages

Java Avance

Le document présente un guide avancé sur Java, couvrant des concepts tels que les generics, les collections, les lambdas, les streams, la concurrence, et les design patterns. Il inclut également des sections sur les entrées/sorties, les bonnes pratiques modernes, et les fonctionnalités récentes de Java. Chaque chapitre fournit des exemples pratiques et des explications détaillées pour aider les développeurs à maîtriser ces concepts.

Transféré par

Gégélekon
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

■ Java

Concepts &
Développeurs
Avancé
Patterns pour
Suite du guide — Niveau intermédiaire / avancé

Generics · Collections · Streams · Lambdas · Concurrence · Design Patterns

10 chapitres · Volume 2
Table des matières
11. Generics (Types génériques) p. 3

12. Collections — List, Set, Map p. 3

13. Itérateurs & for-each avancé p. 4

14. Lambdas & Interfaces fonctionnelles p. 5

15. Streams API p. 6

16. Optional — Éviter NullPointerException p. 7

17. Concurrence & Threads p. 7

18. Design Patterns essentiels p. 8

19. Entrées / Sorties (I/O & NIO) p. 9

20. Bonnes pratiques & Java moderne p. 10


11. Generics (Types génériques)
Les generics permettent d'écrire du code réutilisable et type-safe sans duplication. On utilise des
paramètres de type entre chevrons <T>.
// Classe générique public class Boite { private T contenu; public Boite(T contenu) {
[Link] = contenu; } public T getContenu() { return contenu; } } Boite s = new
Boite<>("Bonjour"); Boite n = new Boite<>(42); [Link]([Link]()); //
Bonjour [Link]([Link]()); // 42 // Méthode générique public static >
T max(T a, T b) { return [Link](b) >= 0 ? a : b; } [Link](max(10,
25)); // 25 [Link](max("chat","zoo")); // zoo

■ Wildcard : <?> = type inconnu, <? extends X> = sous-type de X, <? super X> = super-type de X.

12. Collections — List, Set, Map


Le Java Collections Framework fournit des structures de données dynamiques et performantes,
toutes génériques.
import [Link].*; // LIST — éléments ordonnés, doublons autorisés List liste = new
ArrayList<>(); [Link]("Alice"); [Link]("Bob"); [Link]("Alice");
[Link]([Link]()); // 3 [Link]([Link](0)); // Alice
[Link]("Bob"); // SET — pas de doublons Set set = new HashSet<>([Link](1,
2, 2, 3)); [Link](set); // [1, 2, 3] // MAP — clé → valeur Map scores =
new HashMap<>(); [Link]("Alice", 95); [Link]("Bob", 80);
[Link]([Link]("Alice")); // 95 [Link]("Eve", 0); // 0 si
absent
13. Itérateurs & for-each avancé
Toute collection implémentant Iterable peut être parcourue avec for-each ou un Iterator explicite
(utile pour supprimer des éléments en cours de boucle).
List noms = new ArrayList<>([Link]("Alice","Bob","Charlie","Dave")); //
Iterator explicite — suppression sécurisée Iterator it = [Link](); while
([Link]()) { String nom = [Link](); if ([Link]("C")) { [Link](); //
sûr contrairement à [Link]() dans for-each } } [Link](noms); //
[Alice, Bob, Dave]

Parcourir une Map


Map ages = [Link]("Alice", 30, "Bob", 25, "Charlie", 35); // Parcours des entrées for
([Link] e : [Link]()) { [Link]([Link]() + " → " +
[Link]()); } // Méthode forEach (Java 8+) [Link]((nom, age) ->
[Link](nom + " a " + age + " ans"));

Collections utilitaires
import [Link]; List nums = new ArrayList<>([Link](5, 2, 8, 1,
9)); [Link](nums); // [1, 2, 5, 8, 9] [Link](nums); // [9, 8,
5, 2, 1] [Link](nums); // ordre aléatoire int min =
[Link](nums); int max = [Link](nums); // Trier avec Comparator
[Link]([Link]()); // Trier une liste d'objets par champ List mots
= [Link]("banane","abricot","cerise");
[Link]([Link](String::length)); [Link](mots); //
[banane, cerise, abricot]

■■ ConcurrentModificationException : Ne jamais modifier une collection avec [Link]() à l'intérieur


d'une boucle for-each — utiliser un Iterator ou un Stream avec filter.
14. Lambdas & Interfaces fonctionnelles
Introduites en Java 8, les expressions lambda sont des fonctions anonymes concises. Elles
implémentent une interface fonctionnelle (interface avec une seule méthode abstraite).

Syntaxe lambda
// Forme complète (int a, int b) -> { return a + b; } // Forme abrégée (types inférés,
return implicite) (a, b) -> a + b // Sans paramètre () -> [Link]("Hello
!") // Un seul paramètre (parenthèses optionnelles) x -> x * x

Interfaces fonctionnelles du package [Link]


Interface Signature Usage typique
Runnable () → void Thread, tâche sans retour

Supplier<T> () → T Fournir une valeur

Consumer<T> T → void Consommer/afficher

Function<T,R> T→R Transformer T en R

Predicate<T> T → boolean Filtrer / tester

BiFunction<T,U,R> (T, U) → R Deux entrées, un résultat

Exemples concrets
import [Link].*; Predicate estLong = s -> [Link]() > 5;
[Link]([Link]("Bonjour")); // true
[Link]([Link]("Hi")); // false Function longueur = String::length;
// référence de méthode [Link]([Link]("Java")); // 4 Consumer
afficher = [Link]::println; [Link]("Hello Lambda !"); Supplier aleatoire
= Math::random; [Link]([Link]()); // ex: 0.7342...
15. Streams API
L'API Stream (Java 8+) permet de traiter des collections de manière fonctionnelle, déclarative et
chainable. Un Stream ne stocke pas de données — il les traite à la volée.

Pipeline Stream : source → opérations intermédiaires → opération terminale


import [Link].*; List noms =
[Link]("Alice","Bob","Charlie","David","Eve","Anna"); // Exemple complet List
resultat = [Link]() .filter(n -> [Link]("A")) // intermédiaire : filtre
.map(String::toUpperCase) // intermédiaire : transformation .sorted() // intermédiaire
: tri .collect([Link]()); // terminale : collecte
[Link](resultat); // [ALICE, ANNA]

Opérations intermédiaires (lazy)


List nombres = [Link](1, 2, 3, 4, 5, 6, 7, 8, 9, 10); [Link]() .filter(n -> n
% 2 == 0) // garde les pairs .map(n -> n * n) // met au carré .limit(3) // prend les 3
premiers .forEach([Link]::println); // 4, 16, 36

Opérations terminales
List nums = [Link](3, 1, 4, 1, 5, 9, 2, 6); long count = [Link]().filter(n -> n
> 3).count(); // 4 int sum = [Link]().mapToInt(Integer::intValue).sum(); // 31
int max = [Link]().mapToInt(x->x).max().getAsInt(); // 9 double avg =
[Link]().mapToInt(x->x).average().getAsDouble(); // 3.875 // Réduction
personnalisée int produit = [Link]().reduce(1, (a, b) -> a * b); // 6480 //
Groupement Map> parMod3 = [Link]() .collect([Link](n -> n % 3));
// {0=[3,9,6], 1=[1,1,4], 2=[2,5]} // Jointure de chaînes String joined =
[Link]().collect([Link](", ")); // "Alice, Bob, Charlie, ..."
16. Optional — Éviter NullPointerException
Optional<T> est un conteneur qui peut contenir ou non une valeur. Il force à gérer explicitement les
cas null, rendant le code plus sûr et expressif.
import [Link]; // Créer un Optional Optional present =
[Link]("Java"); Optional vide = [Link](); Optional nullable =
[Link](null); // safe // Vérifier et obtenir
[Link]([Link]()); // true [Link]([Link]());
// true [Link]([Link]()); // Java // Valeur par défaut String val =
[Link]("Défaut"); // "Défaut" String val2 = [Link](() -> "Calculé"); //
Chaînage fonctionnel Optional longueur = present .filter(s -> [Link]() > 2)
.map(String::length); [Link](l -> [Link]("Longueur : " + l));
// 4 // orElseThrow String result = [Link](() -> new
IllegalStateException("Valeur absente !"));

17. Concurrence & Threads


Java supporte nativement le multithreading via la classe Thread, l'interface Runnable, et depuis
Java 5 le package [Link].
// 1. Créer un thread avec Runnable (lambda) Thread t1 = new Thread(() -> { for (int i
= 0; i < 3; i++) { [Link]("Thread 1 - étape " + i); } }); [Link](); //
2. ExecutorService — pool de threads (recommandé) import [Link].*;
ExecutorService pool = [Link](3); [Link](() ->
[Link]("Tâche A dans " + [Link]().getName()));
[Link](() -> [Link]("Tâche B")); [Link](); // 3. Future —
résultat asynchrone Future future = [Link](() -> { [Link](100); return 42;
}); [Link]([Link]()); // bloque jusqu'au résultat : 42 // 4.
synchronized — section critique private int compteur = 0; public synchronized void
incrementer() { compteur++; }
18. Design Patterns essentiels
Les design patterns sont des solutions éprouvées à des problèmes récurrents de conception. Voici
les 4 patterns les plus utilisés en Java.

① Singleton — une seule instance


public class Config { private static Config instance; private Config() {} //
constructeur privé public static synchronized Config getInstance() { if (instance ==
null) instance = new Config(); return instance; } public String getEnv() { return
"production"; } } // Usage Config cfg = [Link]();

② Builder — construction étape par étape


public class Requete { private final String url, methode; private final int timeout;
private Requete(Builder b) { [Link] = [Link]; [Link] = [Link]; [Link]
= [Link]; } public static class Builder { private String url, methode = "GET";
private int timeout = 30; public Builder url(String url) { [Link] = url; return
this; } public Builder methode(String m) { [Link] = m; return this; } public
Builder timeout(int t) { [Link] = t; return this; } public Requete build() {
return new Requete(this); } } } Requete r = new
[Link]().url("[Link]

③ Observer — notification d'événements


import [Link].*; interface Observateur { void notifier(String event); } class
BoutonCliquable { private List obs = new ArrayList<>(); public void
ajouter(Observateur o) { [Link](o); } public void cliquer() { [Link](o ->
[Link]("CLIC")); } } BoutonCliquable btn = new BoutonCliquable(); [Link](e ->
[Link]("Logger: " + e)); [Link](e -> [Link]("Analytics: "
+ e)); [Link](); // Logger: CLIC / Analytics: CLIC

④ Factory — déléguer la création d'objets


interface Forme { double aire(); } record Cercle(double r) implements Forme { public
double aire(){ return [Link]*r*r; } } record Carre(double c) implements Forme {
public double aire(){ return c*c; } } class FormeFactory { public static Forme
creer(String type, double val) { return switch (type) { case "cercle" -> new
Cercle(val); case "carre" -> new Carre(val); default -> throw new
IllegalArgumentException("Type inconnu"); }; } } Forme f =
[Link]("cercle", 5); [Link]("Aire : %.2f%n", [Link]()); //
78.54
19. Entrées / Sorties (I/O & NIO)
Java propose deux APIs : l'ancienne [Link] et la moderne [Link] (recommandée depuis Java
7) via la classe utilitaire Files et Path.

Lire et écrire un fichier — [Link] (recommandé)


import [Link].*; import [Link]; // Écrire dans un fichier Path
fichier = [Link]("[Link]"); String contenu = "Ligne 1\nLigne 2\nLigne 3";
[Link](fichier, contenu); // Lire tout le fichier d'un coup String texte =
[Link](fichier); [Link](texte); // Lire ligne par ligne (Stream)
[Link](fichier) .filter(l -> [Link]("1")) .forEach([Link]::println); //
Ligne 1 // Lister les fichiers d'un dossier [Link]([Link](".")) .filter(p ->
[Link]().endsWith(".txt")) .forEach([Link]::println); // Copier / Déplacer
[Link]([Link]("[Link]"), [Link]("[Link]"),
StandardCopyOption.REPLACE_EXISTING); [Link]([Link]("[Link]"),
[Link]("[Link]"), StandardCopyOption.ATOMIC_MOVE); // Vérifications
[Link](fichier); // true / false [Link](fichier); // false
[Link](fichier); // taille en octets

Lecture interactive — Scanner


import [Link]; Scanner sc = new Scanner([Link]);
[Link]("Entrez votre nom : "); String nom = [Link]();
[Link]("Entrez votre âge : "); int age = [Link]();
[Link]("Bonjour " + nom + ", vous avez " + age + " ans."); [Link]();

Sérialisation — Persister un objet


import [Link].*; // La classe doit implémenter Serializable public class Personne
implements Serializable { private static final long serialVersionUID = 1L; String nom;
int age; Personne(String nom, int age){ [Link]=nom; [Link]=age; } } // Écrire try
(ObjectOutputStream out = new ObjectOutputStream( new
FileOutputStream("[Link]"))) { [Link](new Personne("Alice", 30)); } //
Lire try (ObjectInputStream in = new ObjectInputStream( new
FileInputStream("[Link]"))) { Personne p = (Personne) [Link]();
[Link]([Link] + " / " + [Link]); // Alice / 30 }
20. Bonnes pratiques & Java moderne
Java évolue rapidement. Voici les fonctionnalités modernes (Java 14–21) et les meilleures pratiques
à adopter dès maintenant.

Records — classes de données immuables (Java 16+)


// Équivaut à une classe avec constructeur, getters, equals, hashCode, toString record
Point(double x, double y) { // Méthode personnalisée possible public double
distance(Point autre) { return [Link]([Link](x-autre.x,2) +
[Link](y-autre.y,2)); } } Point p1 = new Point(0, 0), p2 = new Point(3, 4);
[Link](p1.x()); // 0.0 [Link]([Link](p2)); // 5.0

Sealed Classes — hiérarchie contrôlée (Java 17+)


sealed interface Forme permits Cercle, Rectangle, Triangle {} record Cercle(double r)
implements Forme {} record Rectangle(double l, double h) implements Forme {} record
Triangle(double b, double h) implements Forme {}

Pattern Matching switch (Java 21)


double aire = switch (forme) { case Cercle c -> [Link] * c.r() * c.r(); case
Rectangle r -> r.l() * r.h(); case Triangle t -> 0.5 * t.b() * t.h(); };

Text Blocks — chaînes multilignes (Java 15+)


String json = """ { "nom": "Alice", "age": 30 } """; [Link](json);

Meilleures pratiques — synthèse


Pratique Pourquoi ?
Préférer var (Java 10+) Inférence de type, code plus court

Utiliser final autant que possible Immutabilité, moins de bugs

Favoriser les interfaces sur les classes concrètes Découplage, testabilité

Éviter null — utiliser Optional Prévient NullPointerException

Logger avec SLF4J, pas [Link] Logs configurables en production

Écrire des tests unitaires (JUnit 5) Confiance dans le code, refactoring sûr

Respecter les principes SOLID Architecture maintenable à long terme

■ Félicitations ! Vous maîtrisez désormais les concepts avancés de Java. Prochaine étape : Spring
Boot, Quarkus, architecture microservices.

Vous aimerez peut-être aussi