Terminaison du flux Java

Il y avait pas mal de choses que je ne comprenais pas à propos du processus de terminaison de Stream ajouté dans Java8, alors je l'ai étudié.

Les opérations de flux sont effectuées dans l'ordre de génération de flux ⇒ traitement intermédiaire ⇒ traitement de fin. Génération de flux ⇒ Même si seul un traitement intermédiaire est exécuté, cela n'affecte pas la liste d'origine etc. et il n'y a pas de valeur de retour. Si vous voulez faire quelque chose ou si vous voulez obtenir le résultat, vous devez effectuer le processus de résiliation.

Je pense que j'augmenterai davantage si j'en ai envie, mais cette fois je vais énumérer ceux que j'ai choisis de manière appropriée.

count Il est facile à comprendre tel quel, mais il compte le nombre de Streams. Il est généralement utilisé en combinaison avec un traitement intermédiaire tel qu'un filtre.

count


/**
 *Vérifier le nombre de traitements de terminaison de flux
 */
@Test
public void count() {
    //Tel quel
    long count = IntStream.rangeClosed(1, 10).count();
    System.out.println(count); // ⇒ 10
    //Habituellement utilisé en combinaison avec un traitement intermédiaire
    long count2 = IntStream.rangeClosed(1, 10).filter(i -> i >  4).count();
    System.out.println(count2); // ⇒ 6
}

toArray Le nom de la méthode est le même, mais Stream est converti au format tableau et renvoyé. Deux modèles avec et sans arguments sont préparés pour toArray, et s'ils sont exécutés sans arguments, ils seront renvoyés sous forme de tableau d'objets. S'il y a un argument, l'argument doit spécifier une fonction "générateur" qui renvoie un tableau de taille entière passée en argument.

toArray


/**
 *Vérifier la terminaison du flux vers la baie
 */
@Test
public void toArray() {
    List<String> testList = new ArrayList<String> (Arrays.asList("ABC1", "ABD2", "DBC3", "CBC4"));

    //Puisqu'il n'y a pas d'argument, il est retourné comme un tableau d'Object
    Object[] streamToArray= testList.stream().toArray();
    System.out.println(Arrays.toString(streamToArray)); // ⇒ [ABC1, ABD2, DBC3, CBC4]

    //Si vous spécifiez la fonction de générateur qui renvoie un tableau de chaînes, la valeur sera définie dans le tableau renvoyé et elle sera renvoyée.
    String[] streamToArrayFunc = testList.stream().toArray(String[]::new);
    System.out.println(Arrays.toString(streamToArrayFunc)); // ⇒ [ABC1, ABD2, DBC3, CBC4]

    // String[]::nouveau est "i"->  new String[i]Est une abréviation.
    String[] streamToArrayFunc2 = testList.stream().toArray(i ->  new String[i]);
    System.out.println(Arrays.toString(streamToArrayFunc2)); // ⇒ [ABC1, ABD2, DBC3, CBC4]

    //Bien entendu, renvoyer un tableau d'une taille autre que la taille spécifiée entraînera une erreur.
    try {
        String[] streamToArrayFunc3 = testList.stream().toArray(i ->  new String[i - 1]);
    } catch (IllegalStateException e) {
        System.out.println(e.getClass().getName()); // ⇒ java.lang.IllegalStateException
    }
}

max, min Extrayez les valeurs maximum et minimum du Stream. Spécifiez Composer pour l'argument. Vous pouvez spécifier la fonction à comparer avec compareTo comme par le passé, mais il est recommandé d'utiliser la fonction dans Comparator comme Java8 car elle est plus facile à comprendre. L'exemple suivant utilise une fonction appelée compareInt pour le comparateur. Cette fonction prend chaque élément comme argument, renvoie une valeur numérique et calcule la valeur minimale en fonction de la valeur renvoyée.

MaxMin


/**
 *Traitement de terminaison de flux max,Vérifier min
 */
@Test
public void maxMin() {
    List<String> testList = new ArrayList<String> (Arrays.asList("ABC1", "ABD2", "DBC3", "CBC4"));

    Optional<String> streamMax = testList.stream().max((str1, str2) -> str1.substring(3, 4).compareTo(str2.substring(3,4)));
    System.out.println(streamMax); ⇒ Optional[CBC4]

    Optional<String> streamMin = testList.stream().min(Comparator.comparingInt(str -> Integer.parseInt(str.substring(3,  4))));
    System.out.println(streamMin); ⇒ Optional[ABC1]
}

reduce Effectue une opération de réduction sur chaque élément de Stream et renvoie le résultat. La valeur à renvoyer sera du même type que l'élément Stream. Qu'est-ce qu'une opération de réduction? Je pense qu'il y a beaucoup de gens qui disent cela. En fait, j'étais le même. En termes simples, une opération de réduction prend une série de valeurs, comme un tableau, et renvoie un seul résultat récapitulatif. C'est le nombre, le maximum, etc. qui sont sortis jusqu'à présent. En outre, les opérations suivantes en Java peuvent également être appelées opérations de réduction.

int sum = 0;
for (int i : new int[]{1, 5, 8}) {
    sum += i;
}

Il existe trois types de réduction selon le type d'argument.

Un paramètre

échantillon


List<String> testList = new ArrayList<String> (Arrays.asList("ABC1", "ABD2", "DBC3", "CBC4"));

Optional<String>  reduceValue1 = testList.stream().reduce((result, element) -> {
    //le résultat est le total jusqu'à présent
    //element est la valeur actuelle
    return String.join("/", result, element);
});
System.out.println(reduceValue1); // ⇒ Optional[ABC1/ABD2/DBC3/CBC4]

Si vous avez BinaryOperator comme argument, définissez une fonction qui a deux valeurs comme arguments. La valeur renvoyée par cette fonction la dernière fois est entrée comme premier argument. Le deuxième argument est la valeur de l'élément Stream. Dans ce cas, résultat = ABC1, élément = ABD2 pour la première fois, résultat = ABC1 / ABD2, élément = DBC3 pour la deuxième fois.

Deux paramètres

échantillon


String reduceValue2 = testList.stream().reduce("FIRST", (result, element) -> {
    //le résultat est le total jusqu'à présent
    //element est la valeur actuelle
    return String.join("/", str1, str2);
});
System.out.println(reduceValue2); // ⇒ FIRST/ABC1/ABD2/DBC3/CBC4

C'est presque le même que le cas d'un paramètre, mais ici vous pouvez définir la valeur initiale dans le premier argument. L'accumulateur spécifié dans le deuxième argument traite la valeur spécifiée dans le premier argument. Je pense que la raison pour laquelle la valeur de retour n'est pas optimale est que la valeur spécifiée dans le premier argument est retournée même si la liste est vide.

3 paramètres

échantillon


String reduceValue3 = testList.parallelStream().reduce("FIRST", (result, element) -> {
    //le résultat est le total jusqu'à présent
    //element est la valeur actuelle
    return String.join("/", result, element);
}, (result1, result2) -> {
    //result1 est le total jusqu'ici
    //result2 est la valeur actuelle
    return String.join("/", result1, result2);
});
System.out.println(reduceValue3); // ⇒ FIRST/ABC1-FIRST/ABD2-FIRST/DBC3-FIRST/CBC4

Lorsqu'il y a trois paramètres, les premier et deuxième arguments sont les mêmes que lorsqu'il y a deux paramètres, seul le troisième argument est différent. Le troisième argument est une fonction qui est appelée uniquement lorsqu'elle est exécutée en parallèle, et le résultat du deuxième argument est combiné et renvoyé.

collect Effectue une opération de réduction variable sur chaque élément du Stream. L'opération de réduction est comme expliqué dans réduire. Alors, qu'est-ce que la variable? Les opérations de réduction normales renvoient une valeur unique. Chaîne ou int. Une opération de réduction de variable consiste à stocker et renvoyer des valeurs dans ce que l'on appelle un conteneur de variables (Collection, StringBuilder, etc.). La différence entre le retour avec une valeur unique, le retour avec un conteneur variable et le retour est la différence entre une opération de réduction et une opération de réduction variable.

Revenez à la description de la fonction de collecte. Il existe deux types de fonctions de collecte, l'une qui prend Collector comme argument et l'autre qui en prend trois, Fournisseur, accumulateur et combineur. Tout d'abord, lors de la prise d'un Collector.

collect


/**
 *Vérifier le processus de terminaison du flux Collect Collector
 */
@Test
public void collect1() {
    List<String> testList = new ArrayList<String> (Arrays.asList("ABC1", "ABD2", "DBC3", "CBC4"));

    //Convertissez Stream en liste.
    List<String> list = testList.stream().map(s -> s.substring(0,  2)).collect(Collectors.toList());
    System.out.println(list); // ⇒ [AB, AB, DB, CB]

    //La mappe est renvoyée en utilisant la valeur renvoyée par la fonction spécifiée par groupingBy comme clé.
    Map<String, List<String>> groupingMap = testList.stream().collect(Collectors.groupingBy(s -> s.substring(0,1)));
    System.out.println(groupingMap); // ⇒ {A=[ABC1, ABD2], C=[CBC4], D=[DBC3]}
}

Une réduction variable peut être obtenue facilement de cette manière. Collectors a beaucoup de fonctions utiles. De plus, si j'ai le temps, je voudrais également présenter ceci.

Ensuite, en prenant trois arguments: fournisseur, accumulateur et combineur.

collect


/**
 *Vérifier la collecte du processus de terminaison du flux
 */
@Test
public void collect2() {
    List<String> testList = new ArrayList<String> (Arrays.asList("ABC1", "ABD2", "DBC3", "CBC4"));
    Map<String, List<String>> groupingMap2 = testList.stream().collect(HashMap<String, List<String>>::new, (map, s) -> {
        String key = s.substring(0, 1);
        List<String> innerList = map.getOrDefault(key, new ArrayList<String>());
        innerList.add(s);
        map.put(key, innerList);
    }, (map1, map2) -> {});
    System.out.println(groupingMap2); // ⇒ {A=[ABC1, ABD2], C=[CBC4], D=[DBC3]}

    Map<String, List<String>> groupingMap3 = testList.parallelStream().collect(HashMap<String, List<String>>::new, (map, s) -> {
        String key = s.substring(0, 1);
        List<String> innerList = map.getOrDefault(key, new ArrayList<String>());
        innerList.add(s);
        map.put(key, innerList);
    }, (map1, map2) -> {});
    System.out.println(groupingMap3); // ⇒ {A=[ABC1]}La valeur est sujette à changement.

    Map<String, List<String>> groupingMap4 = testList.parallelStream().collect(HashMap<String, List<String>>::new, (map, s) -> {
        String key = s.substring(0, 1);
        List<String> innerList = map.getOrDefault(key, new ArrayList<String>());
        innerList.add(s);
        map.put(key, innerList);
    }, (map1, map2) -> {
        map2.forEach((key, list) -> {
            List<String> innerList = map1.getOrDefault(key, new ArrayList<String>());
            innerList.addAll(list);
            map1.put(key, innerList);
        });
    });
    System.out.println(groupingMap4); // ⇒ {A=[ABC1, ABD2], C=[CBC4], D=[DBC3]}
}

Renvoie la même valeur que dans l'exemple précédent en utilisant groupingBy. Chaque argument a la signification suivante. Supplier: Définissez une fonction qui renvoie un conteneur de variables à renvoyer par la fonction de collecte. accumulator: Le conteneur renvoyé par Supplier est passé comme premier argument et chaque élément de Stream est passé comme deuxième argument. Définissez la valeur du conteneur renvoyé par cette fonction. combiner: Si vous n'effectuez pas de traitement parallèle, vous n'avez rien à définir. Définit le processus de combinaison des valeurs renvoyées par le deuxième argument lors du traitement parallèle.

Ceci est la fin de l'explication du traitement de résiliation. Difficile à réduire et à collecter. Pour collecter, je préfère utiliser Collector car c'est plus simple. S'il vous plaît laissez-moi savoir s'il y a des erreurs.

Recommended Posts

Terminaison du flux Java
[Java] Stream API - Traitement de l'arrêt du flux
Essayez Java 8 Stream
API Java Stream
Étudier Java 8 (Stream)
[Java] Traitement de flux
Java 9 Facultatif :: stream
[Java] Génération de flux API-Stream
[Java] API / carte de flux
Pratique de l'API Java8 Stream
À propos de l'opération de réduction du flux Java8
Résumé approximatif du flux Java8
[Java11] Résumé du flux -Avantages du flux-
Aide-mémoire de l'API Java Stream
API Java Stream en 5 minutes
Flux Java8, résumé de l'expression lambda
[Java] Stream API - Traitement intermédiaire de flux
Java Stream ne peut pas être réutilisé.
[Java] Introduction à l'API Stream
Java
[Java11] Résumé de l'utilisation du flux -Basics-
Application Java pour les débutants: stream
[Java] Opération intermédiaire de l'API Stream
[Java 8] Suppression en double (et vérification en double) avec Stream
[Java] Stream (filtrer, mapper, forEach, réduire)
[java8] Pour comprendre l'API Stream
À propos de Lambda, Stream, LocalDate de Java8
[Introduction à Java] À propos de l'API Stream
[Java] Vérification de l'existence des éléments avec Stream
J'ai essayé d'utiliser l'API Java8 Stream
Flux de traitement de base de Java Stream
Java 8 ~ Stream API ~ pour commencer maintenant
Liste de conversion mutuelle de tableau / liste / flux Java
Conversion de liste Java8 avec Stream map
Utilisez-vous Stream en Java?
Apprendre Java (0)
Étudier Java ―― 3
[Java] tableau
Java protégé
[Java] Annotation
Tableau Java
Étudier Java ―― 9
Java scratch scratch
java (constructeur)
[Java] ArrayDeque
Traitement des données à l'aide de l'API de flux de Java 8
java (remplacement)
java (méthode)
Journée Java 2018
Chaîne Java
java (tableau)
Java statique
java débutant 4
Étudier Java ―― 4
Java (ensemble)
tri shell java
[Java] compareTo
Étudier Java -5
Essayez d'utiliser l'API Stream en Java
java réfléchissant 获 获 举