Résumé du flux et scénarios d'utilisation
Résumé du flux
Stream est différent d'InputStream et de outputStream. Il est utilisé pour améliorer l'itérateur de collecte afin de lui permettre d'effectuer des opérations d'agrégation plus efficaces (filtrage, tri, regroupement statistique) ou des opérations de données à grande échelle. De plus, avec les expressions stream et lambada l'efficacité du codage après les vacances est grandement améliorée et la lisibilité est plus forte
Stream utilise une méthode intuitive similaire à l'interrogation de données à partir d'une base de données à l'aide d'instructions SQL pour fournir une abstraction de haut niveau des opérations et des expressions d'ensemble Java.
Avant d'apprendre le flux, vous devez avoir une certaine compréhension des expressions Lambda.
L'exemple suivant peut expliquer ce que Stream peut faire:
Dans l'exemple ci-dessus, des boules en plastique colorées sont obtenues comme source de données, et les rouges sont d'abord filtrées et fondues en triangles aléatoires. Filtrez à nouveau et supprimez les petits triangles. Enfin, calculez le périmètre des graphiques restants.
Comme le montre la figure ci-dessus, pour le traitement de flux, il existe principalement trois opérations clés: création de flux, opération intermédiaire et opération de terminal.
En termes plus concis, il est de mettre les éléments de la collection sur la ligne d'assemblage , et ajouter des conditions à chaque étape , filtrer certains éléments , et enfin laisser les éléments que vous voulez.
Processus de fonctionnement du flux
Pour le traitement de flux, il existe principalement trois opérations clés: création de flux, opération intermédiaire et opération de terminal.
- Création de flux: est la méthode stream ()
- Opérations intermédiaires: opérations de filtrage et de tri
- Opération finale: retirer et imprimer ces opérations
Ce qui suit donnera une introduction spécifique à ces trois types d'opérations
Création de source / flux de pipeline
Passer de la collection à la source du pipeline est simple, appelez le flux
heros.stream();
Mais le tableau n'a pas de méthode de flux, vous devez utiliser
Arrays.stream(hs);
ou
Stream.of(hs);
Ne confondez pas InputStream et OutputStream dans les opérations d'E / S. Les deux ne sont pas le même concept.
Fonctionnement intermédiaire
Chaque opération intermédiaire renverra un Stream. Par exemple, .filter () renvoie un Stream. L'opération intermédiaire est une opération "paresseuse" et ne sera pas parcourue.
Il existe de nombreuses opérations intermédiaires, principalement divisées en deux catégories
, filtrant les éléments et les convertissant en d'autres formes de flux
Eléments filtrants:
le filtre correspond
distinct pour supprimer les doublons (à en juger par égaux) // Remarque: equals dans Object juge s'il s'agit du même objet, voici le code source de equals () dans Object:public boolean equals(Object obj) { return this == obj; }
Mais equals in String juge si le contenu de la chaîne est le même (bien sûr, s'il s'agit du même objet string, il retournera true)
trié Tri naturel
trié (comparateur) Spécifiez la
limite de tri , continuez à
ignorer et ignorez
Convertir en d'autres formes de flux:
mapToDouble converti en double flux
similaire à mapToInt (), mapToLong ()la carte est convertie en tout type de flux
package lambda;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import charactor.Hero;
public class TestAggregate {
public static void main(String[] args) {
Random r = new Random();
List<Hero> heros = new ArrayList<Hero>();
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i, r.nextInt(1000), r.nextInt(100)));
}
//制造一个重复数据
heros.add(heros.get(0));
System.out.println("初始化集合后的数据 (最后一个数据重复):");
System.out.println(heros);
System.out.println("满足条件hp>100&&damage<50的数据");
heros
.stream()
.filter(h->h.hp>100&&h.damage<50)
.forEach(h->System.out.print(h));
System.out.println("去除重复的数据,去除标准是看equals");
heros
.stream()
.distinct()
.forEach(h->System.out.print(h));
System.out.println("按照血量排序");
heros
.stream()
.sorted((h1,h2)->h1.hp>=h2.hp?1:-1)
.forEach(h->System.out.print(h));
System.out.println("保留3个");
heros
.stream()
.limit(3)
.forEach(h->System.out.print(h));
System.out.println("忽略前3个");
heros
.stream()
.skip(3)
.forEach(h->System.out.print(h));
System.out.println("转换为double的Stream");
heros
.stream()
//这里虽然获取的是血量
//但是操作的还是对象
.mapToDouble(Hero::getHp)
.forEach(h->System.out.println(h));
System.out.println("转换任意类型的Stream");
heros
.stream()
.map((h)-> h.name + " - " + h.hp + " - " + h.damage)
.forEach(h->System.out.println(h));
}
}
Regardez un autre exemple
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis");
Stream s = strings.stream()
.filter(string -> string.length()<= 6)
.map(String::length)
.sorted()
.limit(3)
.distinct();
La figure suivante montre le processus de modification de l'objet Stream
Opération finale
Le résultat de l'opération intermédiaire de Stream est toujours un Stream, alors comment convertir un Stream dans le type dont nous avons besoin? Par exemple, calculer le nombre d'éléments dans le flux, remplacer le flux par un ensemble, etc. Cela nécessite une opération de terminal
L'opération finale consomme le flux et produit un résultat final. En d'autres termes, après l'opération finale, le flux ne peut plus être utilisé, ni aucune opération intermédiaire ne peut être utilisée, sinon une exception sera levée.
Les opérations de fin courantes sont les suivantes:
forEach () parcourt chaque élément
collect ()
toArray () est converti en un tableau
min (Comparator) prend le plus petit élément
max (Comparator) prend le plus grand nombre d'éléments
() est utilisé pour compter le nombre d'éléments dans le flux
findFirst () le premier élément
Voici un exemple d'utilisation de collect
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis","Hollis666", "Hello", "HelloWorld", "Hollis");
strings = strings
.stream()
.filter(string -> string.startsWith("Hollis"))
.collect(Collectors.toList());
//找出以“Hollis”开头的元素
System.out.println(strings);
//Hollis, HollisChuang, Hollis666, Hollis
Pour résumer
Stream en Java est comme une fonction de requête de base de données, ce qui peut nous aider à écrire du code plus efficace