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.
é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.
é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.
é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