Principes
Les principes de fonctionnement de l'API Stream reposent sur des concepts clés de la programmation fonctionnelle et de l'évaluation paresseuse. Examen des principaux principes de l'API Stream.
Évaluation paresseuse
L'un des principes fondamentaux de l'API Stream est l'évaluation paresseuse.
Cela signifie que les opérations intermédiaires telles que filter() ou map() ne sont pas exécutées immédiatement. Elles forment simplement une chaîne d'actions qui ne sera exécutée que lorsqu'une opération terminale, telle que collect() ou forEach(), sera invoquée.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); long count = names.stream() .filter(name -> name.startsWith("A")) // Forming the operation .count(); // Triggering execution System.out.println(count); // Output: 1 } }
Ce code crée un flux à partir d'une liste de chaînes de caractères, filtre les éléments pour ne conserver que ceux qui commencent par la lettre A, et compte combien remplissent cette condition. Le résultat (1) est affiché car seul Alice satisfait la condition.
Style de programmation fonctionnelle
L'API Stream utilise des expressions lambda et des interfaces fonctionnelles pour le traitement des données. Au lieu de l'approche impérative avec des boucles, il s'agit de décrire ce qui doit être fait avec les données :
Main.java
1234567891011121314package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> fruits = List.of("apple", "banana", "cherry", "apricot", "blueberry"); List<String> result = fruits.stream() .map(String::toUpperCase) // Convert all strings to uppercase .skip(3) .toList(); // Collect the result into a new list System.out.println(result); } }
Ce code crée un flux à partir d'une liste de fruits, convertit les chaînes en majuscules à l'aide de map(), et ignore les trois premiers éléments avec skip(). Le résultat est collecté dans une nouvelle liste et affiché, en commençant par le quatrième élément.
Immuabilité des données
L'API Stream ne modifie pas les données originales. Toutes les opérations créent un nouveau flux ou retournent un résultat sans modifier la collection ou le tableau. Cela améliore la sécurité des données et prévient les effets secondaires inattendus.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); List<String> updateNames = names.stream() .filter(name -> name.startsWith("A")) .toList(); System.out.println(names); // Output: [Alice, Bob, Charlie] } }
L'API Stream filtre la liste names pour créer un nouveau flux, updateNames, qui contient uniquement les éléments commençant par la lettre A. Cependant, la liste names d'origine reste inchangée, car l'API Stream ne modifie pas les données directement, garantissant ainsi la sécurité des données et évitant les effets secondaires.
Les flux sont consommables une seule fois
Un flux ne peut être utilisé qu'une seule fois. Après l'exécution d'une opération terminale, le flux devient indisponible pour tout traitement ultérieur.
Main.java
123456789101112package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream<String> stream = List.of("Alice", "Bob").stream(); stream.forEach(System.out::println); stream.forEach(System.out::println); // Error: Stream has already been used } }
Ici, création d’un flux à partir d’une liste de chaînes de caractères et affichage de chaque élément dans la console. Après la première utilisation du flux, il ne peut plus être réutilisé, ce qui provoque une erreur si une nouvelle tentative d’appel à forEach() est effectuée.
Traitement parallèle
L’API Stream prend en charge les flux parallèles, permettant un traitement des données plus rapide sur les systèmes multi-cœurs. Ce sujet est approfondi ici
Main.java
1234567891011package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> numbers = List.of(1, 2, 3, 4, 5); numbers.parallelStream() .forEach(System.out::println); // Elements are processed in parallel } }
Ce code crée un flux parallèle à partir d'une liste de nombres et affiche chaque élément dans la console. L'utilisation de parallelStream() permet un traitement parallèle des éléments de la liste, ce qui peut accélérer l'exécution lors du traitement de grandes quantités de données.
Propreté et lisibilité du code
L'utilisation de la Stream API rend le code plus déclaratif. Au lieu de décrire comment effectuer une tâche (comme avec des boucles), il s'agit de décrire ce qui doit être fait. Cela améliore la lisibilité et simplifie la maintenance du code.
Exemple avec une boucle :
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Exemple utilisant l’API Stream :
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
Dans le premier exemple de boucle, la méthode d’itération de la liste et d’affichage des éléments est explicitement décrite, tandis que dans le second exemple avec l’API Stream, seule l’action à effectuer est spécifiée : itérer sur les éléments et les afficher. Cela rend le code plus déclaratif et lisible.
Merci pour vos commentaires !
Demandez à l'IA
Demandez à l'IA
Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion
Awesome!
Completion rate improved to 2.33
Principes
Glissez pour afficher le menu
Les principes de fonctionnement de l'API Stream reposent sur des concepts clés de la programmation fonctionnelle et de l'évaluation paresseuse. Examen des principaux principes de l'API Stream.
Évaluation paresseuse
L'un des principes fondamentaux de l'API Stream est l'évaluation paresseuse.
Cela signifie que les opérations intermédiaires telles que filter() ou map() ne sont pas exécutées immédiatement. Elles forment simplement une chaîne d'actions qui ne sera exécutée que lorsqu'une opération terminale, telle que collect() ou forEach(), sera invoquée.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); long count = names.stream() .filter(name -> name.startsWith("A")) // Forming the operation .count(); // Triggering execution System.out.println(count); // Output: 1 } }
Ce code crée un flux à partir d'une liste de chaînes de caractères, filtre les éléments pour ne conserver que ceux qui commencent par la lettre A, et compte combien remplissent cette condition. Le résultat (1) est affiché car seul Alice satisfait la condition.
Style de programmation fonctionnelle
L'API Stream utilise des expressions lambda et des interfaces fonctionnelles pour le traitement des données. Au lieu de l'approche impérative avec des boucles, il s'agit de décrire ce qui doit être fait avec les données :
Main.java
1234567891011121314package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> fruits = List.of("apple", "banana", "cherry", "apricot", "blueberry"); List<String> result = fruits.stream() .map(String::toUpperCase) // Convert all strings to uppercase .skip(3) .toList(); // Collect the result into a new list System.out.println(result); } }
Ce code crée un flux à partir d'une liste de fruits, convertit les chaînes en majuscules à l'aide de map(), et ignore les trois premiers éléments avec skip(). Le résultat est collecté dans une nouvelle liste et affiché, en commençant par le quatrième élément.
Immuabilité des données
L'API Stream ne modifie pas les données originales. Toutes les opérations créent un nouveau flux ou retournent un résultat sans modifier la collection ou le tableau. Cela améliore la sécurité des données et prévient les effets secondaires inattendus.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); List<String> updateNames = names.stream() .filter(name -> name.startsWith("A")) .toList(); System.out.println(names); // Output: [Alice, Bob, Charlie] } }
L'API Stream filtre la liste names pour créer un nouveau flux, updateNames, qui contient uniquement les éléments commençant par la lettre A. Cependant, la liste names d'origine reste inchangée, car l'API Stream ne modifie pas les données directement, garantissant ainsi la sécurité des données et évitant les effets secondaires.
Les flux sont consommables une seule fois
Un flux ne peut être utilisé qu'une seule fois. Après l'exécution d'une opération terminale, le flux devient indisponible pour tout traitement ultérieur.
Main.java
123456789101112package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream<String> stream = List.of("Alice", "Bob").stream(); stream.forEach(System.out::println); stream.forEach(System.out::println); // Error: Stream has already been used } }
Ici, création d’un flux à partir d’une liste de chaînes de caractères et affichage de chaque élément dans la console. Après la première utilisation du flux, il ne peut plus être réutilisé, ce qui provoque une erreur si une nouvelle tentative d’appel à forEach() est effectuée.
Traitement parallèle
L’API Stream prend en charge les flux parallèles, permettant un traitement des données plus rapide sur les systèmes multi-cœurs. Ce sujet est approfondi ici
Main.java
1234567891011package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> numbers = List.of(1, 2, 3, 4, 5); numbers.parallelStream() .forEach(System.out::println); // Elements are processed in parallel } }
Ce code crée un flux parallèle à partir d'une liste de nombres et affiche chaque élément dans la console. L'utilisation de parallelStream() permet un traitement parallèle des éléments de la liste, ce qui peut accélérer l'exécution lors du traitement de grandes quantités de données.
Propreté et lisibilité du code
L'utilisation de la Stream API rend le code plus déclaratif. Au lieu de décrire comment effectuer une tâche (comme avec des boucles), il s'agit de décrire ce qui doit être fait. Cela améliore la lisibilité et simplifie la maintenance du code.
Exemple avec une boucle :
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Exemple utilisant l’API Stream :
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
Dans le premier exemple de boucle, la méthode d’itération de la liste et d’affichage des éléments est explicitement décrite, tandis que dans le second exemple avec l’API Stream, seule l’action à effectuer est spécifiée : itérer sur les éléments et les afficher. Cela rend le code plus déclaratif et lisible.
Merci pour vos commentaires !