JavaRush /Blog Java /Random-FR /API de flux

API de flux

Publié dans le groupe Random-FR
API de flux - 1

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.
API de flux - 1
Avec l'avènement de Java 8, l'API Stream a permis aux programmeurs d'écrire beaucoup plus brièvement ce qui nécessitait auparavant de nombreuses lignes de code, à savoir simplifier le travail avec des ensembles de données, en particulier pour simplifier le filtrage, le tri et d'autres opérations de manipulation de données. Si vous n'avez pas d'opérations intermédiaires, vous pouvez et devez souvent vous passer d'un flux, sinon le code sera plus compliqué que sans flux.
API de flux - 2
Par où dois-je commencer exactement ? De la création d'une instance Stream, qui est basée sur la collection, le tableau ou la méthode dont nous avons besoin et d'où les données seront extraites en conséquence :
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 :
API de flux - 3
  • 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")
Il existe ensuite les opérateurs (essentiellement des méthodes de la classe Stream). Les opérateurs peuvent être divisés en deux groupes :
  • 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.
Exemple:
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, xest assimilé à un élément de la collection pour l'énumération (comme avec for 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, forEachqui à son tour est un analogue terminal (final) de l'énumération for each(expression System.out::printlnabré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)
API de flux - 5
Les points importants:
  • 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 =( ;
  • API de flux - 6

    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));
Examinons ensuite quelques opérateurs intermédiaires :
API de flux - 7
  • 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.functionVé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 fonctionnelle Function<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 de map, ils sont utilisés pour convertir en flux primitif.
Lorsque vous travaillez, par exemple, avec un tableau de flux (tableaux, listes, etc.), il les convertit en un seul flux (tableau, liste, etc.) [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 mapse 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 nullun 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)
Et un autre exemple de comparaison, flatMap :
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
Opérateurs de terminaux :
API de flux - 8
  • 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é ( supplierfournit de nouveaux objets (conteneurs), par exemple new ArrayList(), accumulatorajoute un élément au conteneur, combinercombine 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 identityet le premier élément du flux, appliquer la fonction accumulatoret identitydevenir 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 manquante identity, c'est le premier élément du flux

    Optional 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 condition predicate:

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Et enfin, j'aimerais examiner quelques méthodesCollectors :
  • 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.

Liens utiles: PS : n'hésitez pas à nous combler de likes ^ : ^
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION