Qu'est-ce que l'API Stream ?
L'API Stream est une nouvelle façon de travailler avec des structures de données dans un style fonctionnel. Une API Stream (une description de la manière dont un programme informatique peut communiquer avec un autre programme) est, à la base, un flux de données. Le terme « thread » lui-même est assez vague en programmation en général et en Java en particulier.List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
list.add("Five");
list.add("Six");
list.add("Seven");
list.add("Eight");
list.add("Nine");
list.add("Ten");
Stream stream = list.stream();
Comme mentionné ci-dessus, l'API Stream permet de réduire le nombre de lignes de code. Exemple avec un flux :
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
Exemple sans fil :
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
int count = 0;
for (int x : arr) {
if (x >= 90) continue;
x += 10;
count++;
if (count > 3) break;
System.out.print(x);
}
Méthodes possibles pour créer un flux :
- Flux vide :
Stream.empty()
- Flux à partir de la liste :
list.stream()
- Flux depuis la carte :
map.entrySet().stream()
- Flux depuis le tableau :
Arrays.stream(array)
- Flux à partir des éléments spécifiés :
Stream.of("1", "2", "3")
- Intermédiaire (également appelé « paresseux ») - traite les éléments entrants et renvoie le flux. Il peut y avoir de nombreux opérateurs intermédiaires dans la chaîne de traitement des éléments.
- Terminal (« terminal », également appelé « impatient ») - traite les éléments et termine le flux, il ne peut donc y avoir qu'un seul opérateur de terminal dans la chaîne.
1.List<String> list = new ArrayList<String>();
2.list.add("One");
…
11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
Que se passe t-il ici:
- 1 - créer une liste
list
; - 2-11 - remplissez-le avec les données de test ;
- 12 - créer un objet
Stream
; - 13 - méthode
filter
(filtre) - opérateur intermédiaire,x
est assimilé à un élément de la collection pour l'énumération (comme avecfor each
) et après -> nous indiquons comment notre collection est filtrée et comme il s'agit d'un opérateur intermédiaire, la collection filtrée va plus loin vers le méthode,forEach
qui à son tour est un analogue terminal (final) de l'énumérationfor each
(expressionSystem.out::println
abrégée pour :,x-> System.out.println(x))
qui à son tour parcourt tous les éléments de la collection qui lui sont transmis et les affiche)
- Le traitement ne commencera que lorsque l'opérateur du terminal sera appelé.
list.stream().filter(s -> s > 5)
(ne prendra pas un seul élément de la liste) ; - Une instance d'un flux ne peut pas être utilisée plus d'une fois =( ;
Donc à chaque fois c’est nouveau :
list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
list.stream().forEach(x -> System.out.println(x));
Il peut y avoir plusieurs opérateurs intermédiaires appelés sur un même flux, alors qu'il n'y a qu'un seul opérateur terminal :
stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
filter(Predicate predicate)
filtre le flux, en transmettant uniquement les éléments qui satisfont à la condition (Predicate est une interface fonctionnelle intégrée ajoutée au package dans Java SE 8.java.util.function
Vérifie la valeur de « true » et « false »);map(Function mapper)
permet de créer une fonction avec laquelle on va changer chaque élément et le sauter plus loin (L'interface fonctionnelleFunction<T,R>
représente la fonction de transition d'un objet de type T à un objet de type R)flatMap(Function<T, Stream<R>> mapper)
- comme dans le cas demap
, ils sont utilisés pour convertir en flux primitif.
[stream1,stream2,stream3,stream4] => stream
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
.collect(Collectors.toList()).forEach(System.out::println);
Pendant qu'il map
se convertit en une liste de threads (plus précisément <Stream>
de threads)[stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4)
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.map(Arrays::stream).distinct() //Make the array into a separate thread
.collect(Collectors.toList()).forEach(System.out::println);
Autre différence par rapport à map
, vous pouvez convertir un élément en zéro, un ou plusieurs autres. Afin de convertir un élément en zéro élément, vous devez renvoyer null
un flux vide. Pour convertir en un seul élément, vous devez renvoyer un flux à partir d'un élément, par exemple via Stream.of(x)
. Pour renvoyer plusieurs éléments, vous pouvez créer un flux avec ces éléments par n'importe quel moyen. La même méthode flatMap, mais pour Double, Integer et Long :
- flatMapToDouble (Mappeur de fonctions)
- flatMapToInt (Mappeur de fonctions)
- flatMapToLong (Mappeur de fonctions)
Stream.of(2, 3, 0, 1, 3)
.flatMapToInt(x -> IntStream.range(0, x))
.forEach(System.out::print);// 010120012
-
IntStream.range(0,x) – génère des éléments de 0 (inclus) à x (non inclus) dans le flux ;
carte:
Stream.of(2, 3, 0, 1, 3) .map(x -> IntStream.range(0, x)) .forEach(System.out::print);//list of streams (streams);
-
limit(long maxSize) – limite le flux par le nombre d'éléments :
stream.limit(5).forEach(x -> System.out.println(x));
-
skip(long n) – sauter n éléments :
stream.skip(3).forEach(x -> System.out.println(x));
-
trié()
- trié (Comparator comparator) – trie le flux (tri comme TreeMap) :
stream.sorted().forEach(x -> System.out.println(x));
-
distinct() — vérifie le flux pour l'unicité des éléments (supprime les répétitions d'éléments) ;
-
dropWhile (Predicate predicate) - ignore les éléments qui satisfont à la condition (apparu dans Java 9, l'interface fonctionnelle Predicate<T> vérifie si une condition est remplie. Si elle est remplie, alors true est renvoyé. L'expression lambda prend un objet de type T en paramètre :
Predicate<Integer> isPositive = x -> x > 0; System.out.println(isPositive.test(3)); // true System.out.println(isPositive.test(-9)); // false
-
forEach(Consumer action) – analogue à for each (Consumer<T> effectue une action sur un objet de type T sans rien renvoyer) ;
-
count() – renvoie le nombre d'éléments du flux :
System.out.println(stream.count());
-
collect(Collector collector) – la méthode collecte tous les éléments dans une liste, un ensemble ou une autre collection, regroupe les éléments selon certains critères, combine le tout dans une chaîne, etc. :
List<String> list = Stream.of(“One”, “Two”, “Three”).collect(Collectors.toList());
-
collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
— comme ,collect(collector)
seuls les paramètres sont décomposés pour plus de commodité (supplier
fournit de nouveaux objets (conteneurs), par exemplenew ArrayList()
,accumulator
ajoute un élément au conteneur,combiner
combine des parties du flux ensemble) ; -
réduire(identité T, accumulateur BinaryOperator) - convertit tous les éléments du flux en un seul objet (calculer la somme de tous les éléments ou trouver l'élément minimum), prendre d'abord l'objet
identity
et le premier élément du flux, appliquer la fonctionaccumulator
etidentity
devenir son résultat. Ensuite tout continue pour les éléments restants.int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
-
reduce(BinaryOperator accumulator)
— la même méthode que ci-dessus mais la première est manquanteidentity
, c'est le premier élément du fluxOptional min(Comparator comparator)
Facultatif max(Comparator comparator) recherche l'élément minimum/maximum en fonction du comparateur transmis ; -
findFirst()
– extrait le premier élément du flux :Stream.of(1, 2, 3, 4, 9).findFirst();
-
allMatch(Predicate predicate)
— renvoie vrai si tous les éléments du flux satisfont à la condition. Si un élément est rencontré pour lequel le résultat de l'appel de la fonction de prédicat est false , alors l'opérateur arrête d'analyser les éléments et renvoie false :Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
-
anyMatch(Predicate predicate)
— retournera true si au moins un élément du flux satisfait à la conditionpredicate
:Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
-
noneMatch(Predicate predicate)
— retournera vrai si, après avoir parcouru tous les éléments du flux, aucun d'entre eux ne satisfait à la conditionpredicate
:Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Collectors
:
-
toList()
— rassemble les éléments dansList
:List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
-
toSet()
— rassemble des éléments dans un ensemble :Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
-
counting()
— Compte le nombre d'éléments :Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
-
joining()
-
joining(CharSequence delimiter)
-
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
— rassemble les éléments sur une seule ligne. De plus, vous pouvez spécifier un séparateur, ainsi qu'un préfixe et un suffixe pour l'ensemble de la séquence :String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining()); System.out.println(a); // super String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-")); System.out.println(b); // s-u-p-e-r String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]")); System.out.println(c); // [ s -> u -> p -> e -> r ]
-
summingInt(ToIntFunction mapper)
-
summingLong(ToLongFunction mapper)
-
summingDouble(ToDoubleFunction mapper)
- un collecteur qui convertit les objets en int/long/double et calcule la somme.
GO TO FULL VERSION