Cet article explique comment utiliser l'API Stream. De nombreux exemples et explications de code source sont fournis afin que même ceux qui ne connaissent pas l'API Stream puissent le comprendre. Il introduit également une utilisation appliquée telle que le modèle de stratégie à l'aide de l'API Stream.
――Parce que le traitement se fait comme des mots, la lisibilité est améliorée.
Il peut être utilisé dans les endroits où le traitement en boucle, comme les instructions for, est le plus souvent effectué.
Le flux de base consiste à créer une instance Stream, à effectuer autant de processus que vous le souhaitez (opération intermédiaire) et à l'amener finalement à l'état souhaité (opération de point final).
Comparons ** si vous n'avez pas utilisé l'API Stream ** et ** si vous avez utilisé ** pour imaginer ce processus.
Le code écrit ci-dessous montre le code source qui convertit la chaîne de caractères stockée dans la liste en majuscules et extrait et affiche uniquement la chaîne de 4 caractères.
//Code écrit sans utiliser l'API Stream
List<String> list2 = Arrays.asList("hoge", "foo", "bar","hoga");
List<String> stream2 = new ArrayList<String>();
for(String s :list2){
String sUpperCase = s.toUpperCase();
if(sUpperCase.length() == 4){
stream2.add(sUpperCase);
}
}
for(int i = 0; i < stream2.size(); i++){
System.out.println(stream2.get(i));
}
/*
Le résultat est le suivant
HOGE
HOGA
*/
//Lors de l'utilisation de l'API Stream
List<String> list1 = Arrays.asList("hoge", "foo", "bar","hoga");
List<String> stream1 = list1.stream()
.map(String::toUpperCase)
.filter(s -> s.length() == 4)
.collect(Collectors.toList());
stream1.forEach(System.out::println);
/*
Le résultat est le suivant
HOGE
HOGA
*/
L'utilisation de l'API Stream comme celle-ci est plus facile à lire car vous n'avez qu'à écrire ce que vous voulez faire de manière déclarative. (Il y a un avantage car il n'y a pas d'autre changement d'état et le traitement inutile ne s'exécute pas en raison d'un retard de traitement)
Maintenant que vous avez une idée de la façon d'utiliser l'API Stream, je vais vous expliquer en détail comment l'utiliser.
Je vais expliquer le flux de Stream séparément comme suit. ** 1. Création d'une instance de flux ** ** 2. Fonctionnement intermédiaire ** ** 3. Fonctionnement du point final **
Il existe de nombreuses façons de créer une instance Stream, mais en voici quatre que vous pouvez utiliser le plus souvent.
Classe / interface | Méthode | Aperçu |
---|---|---|
Collection |
stream() | Génération d'instance de flux à partir d'une classe qui hérite de l'interface Collection |
Arrays | stream (T[] array) | Créer une instance Stream à partir d'un tableau |
Stream | of(T… values) | Créer une instance Stream basée sur la valeur directe |
Stream | iterate(T seed, UnaryOperator f) | Créer une instance de Stream infinie ordonnée |
Comment écrire du code source
// Collection#stream()
List<String> list = Arrays.asList("hoge", "foo", "bar");
Stream<String> stream = list.stream();
// Arrays#stream (T[] array)
String[] array = {"hoge", "foo", "bar"};
Stream<String> stream2 = Arrays.stream(array);
// Stream#of (T[] array)
Stream<String> stream3 = Stream.of("hoge", "foo", "bar");
// Stream#iterate (T seed, UnaryOperator f)
Stream<Integer> stream4 = Stream.iterate(2, x -> x * 2);
Les opérations intermédiaires sont grossièrement divisées en trois méthodes de traitement.
--Réduire les éléments --Traitement des éléments --Trier les éléments
** 1. Je pense que vous comprenez comment créer une instance Stream **, je vais donc restreindre les opérations intermédiaires pour l'instance Stream générée.
Puisqu'il est réduit, le nombre d'entrées et de sorties changera.
Méthode | Aperçu |
---|---|
filter(Predicate<? super T> predicate) | Flux défini dans Predicate avec uniquement de vrais éléments |
limit(long maxSize) | Renvoie un flux d'éléments du début de l'élément à maxSize |
skip(long maxSize) | Renvoie un Stream qui ignore les éléments du début de l'élément à maxSize |
distinct() | Compare les éléments avec la méthode equals et renvoie un Stream excluant les doublons |
Comment écrire du code source
List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Extraction d'une chaîne de 4 caractères uniquement à l'aide d'un filtre
System.out.println("****↓ filter****");
list.stream()
.filter(s -> s.length() == 4)
.forEach(System.out::println);
/*
Résultat de sortie
hoge
hoga
hoga
*/
List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Extrait jusqu'à 3 chaînes du premier caractère en utilisant la limite
list.stream()
.limit(3)
.forEach(System.out::println);
/*
Résultat de sortie
hoge
foo
bar
*/
List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//J'ai utilisé skip pour ignorer l'élément th string de la première lettre
list.stream()
.skip(1)
.limit(2)
.forEach(System.out::println);
/*
Résultat de sortie
foo
bar
*/
List<String> list = Arrays.asList("hoge", "foo", "bar","hoga","hoga");
//Suppression des chaînes en double à l'aide de distinct
list.stream()
.distinct()
.forEach(System.out::println);
/*
Résultat de sortie
hoge
foo
bar
hoga
*/
Le nombre d'entrées et de sorties ne change pas car il est uniquement traité. Par exemple, vous pouvez passer de inférieur à supérieur ou de chaîne à nombre de caractères dans la chaîne.
Méthode | Aperçu |
---|---|
map(Function<? super T, ? extends R> function) | Renvoie R de T reçu par la fonction comme argument, et Stream généré avec ce R comme élément |
Comment écrire du code source
List<String> list = Arrays.asList("hoge", "foo", "bar","hoga");
list.stream()
.map(String::length)
.forEach(System.out::println);
/*
Résultat de sortie
4
3
3
4
*/
Méthode | Aperçu |
---|---|
sorted(Comparator<? super T> comparator) | Stream comparé et trié par comparateur |
Comment écrire du code source
List<Person> people = Arrays.asList(
new Person("Suzuki",24),
new Person("Yamada",53),
new Person("Jean Baljan",9),
new Person("Yokouchi",39));
//Une fois triés par âge
people.stream()
.sorted(comparing(Person::getAge))
.forEach(s -> System.out.println(s.toString()));
/*
Résultat de sortie
Jean Baljan:9
Suzuki:24
Yokouchi:39
Yamada:53
*/
//Trier par nom.reversed()Lors de l'utilisation dans l'ordre décroissant
people.stream()
.sorted(comparing(Person::getName).reversed())
.forEach(s -> System.out.println(s.toString()));
}
/*
Résultat de sortie
Suzuki:24
Yokouchi:39
Yamada:53
Jean Baljan:9
*/
//Classe de personne utilisée ci-dessus
public class Person {
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public String toString(){
return name + ":" + age;
}
}
L'opération de point final est la dernière opération qui crée une instance Stream et termine les opérations intermédiaires.
Méthode | Type de retour | Contenu |
---|---|---|
forEach(Consumer<? super T> consumer) | void | Le consommateur reçoit chaque élément de Stream comme argument et le traite. Lorsqu'il est utilisé dans un traitement parallèle, l'ordre n'est pas garanti même si les données d'origine sont un agrégat tel que List. |
forEachOrdered(Consumer<? super T> consumer) | void | Si chaque élément de Stream garantit la commande, le consommateur reçoit chaque élément comme argument dans l'ordre et le traite. |
toArray() | Object[] | Renvoie les éléments de Stream sous la forme d'un tableau d'objets |
reduce(T unit, BinaryOperator acc) | T | réduction(Plier).. Renvoie le résultat de la combinaison d'éléments avec la fonction cumulative acc pour l'unité d'élément unitaire. |
collect(Supplier factory, BiConsumer acc, BiConsumer combiner) | Conteneur de résultats | Réduction variable. Conteneur variable généré par l'usine(Par exemple ArrayList)D'autre part, ajoutez un élément avec acc et combinez chaque récipient avec le combineur. |
min(Comparator<? super T> comparator) | Optional |
Renvoie le plus petit des éléments. Utilisez le comparateur d'arguments pour comparer la taille. Renvoie une option vide s'il n'y a pas d'élément |
max(Comparator<? super T> comparator) | Optional |
Renvoie le plus grand des éléments. Utilisez le comparateur d'arguments pour comparer la taille. Renvoie une option vide s'il n'y a pas d'élément |
count() | long | Renvoie le nombre d'éléments que Stream a |
anyMatch(Predicate<? super T> predicate) | boolean | Si tous les éléments de Stream retournent True dans le jugement de prédicat, True est retourné comme valeur de retour. |
allMatch(Predicate<? super T> predicate) | boolean | Si tous les éléments de Stream retournent True dans le jugement de prédicat, True est retourné comme valeur de retour. |
noneMatch(Predicate<? super T> predicate) | boolean | Si aucun des éléments Stream ne renvoie True sur la décision de prédicat, True est renvoyé comme valeur de retour. |
findFirst() | Optional |
Renvoie le premier élément des éléments. Renvoie une option vide s'il n'y a pas d'élément |
findAny() | Optional |
Renvoie un élément des éléments. Renvoie une option vide s'il n'y a pas d'élément |
sum() | int / long /double | Renvoie la somme des éléments de Stream. La valeur de retour sera ce que représente le Stream. Renvoie 0 s'il n'y a aucun élément |
average() | OptionalDouble | Renvoie la valeur moyenne. S'il n'y a aucun élément, Empty OptionalDouble est renvoyé. S'il n'est pas divisible, il est arrondi à une valeur qui peut être représentée par une valeur double. |
Comment écrire du code source Comme le montant est important cette fois, j'ai écrit un exemple en extrayant environ 3 de manière appropriée. Il existe une valeur de retour facultative, qui sera expliquée plus tard.
List<Person> people = Arrays.asList(
new Person("Suzuki",24),
new Person("Yamada",53),
new Person("Jean Baljan",9),
new Person("Yokouchi",39));
//Trier par âge et stocker dans la liste
List<Person> sortedPeople = people.stream()
.sorted(comparing(Person::getAge))
.collect(Collectors.toList());
System.out.println(sortedPeople);
/*
Résultat de sortie
[Jean Baljan:9,Suzuki:24,Yokouchi:39,Yamada:53]
*/
//Trier par âge dans l'ordre décroissant et obtenir la première personne
Optional<Person> firstPerson = people.stream()
.sorted(comparing(Person::getAge).reversed())
.findFirst();
System.out.println(firstPerson);
/*
Résultat de sortie
Optional[Yamada:53]
*/
//Vrai si toutes les personnes ont 10 ans ou plus, faux sinon
boolean ss = people.stream()
.allMatch(p -> p.getAge() > 10);
System.out.println(ss);
/*
Résultat de sortie
false
*/
Un objet conteneur qui peut être stocké avec ou sans valeurs non nulles. Il n'est pas nécessaire d'effectuer un traitement null-po tel que if (xxx == null). Veuillez le lire car il est organisé dans un document facile à comprendre. https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html
Ceci est un exemple utilisant la méthode ifPresent (Consumer <? Super T> consumer). Ce programme génère la première valeur trouvée lorsque le nombre de caractères dans le nom de famille est de 3 ou plus.
//Si facultatif n'est pas utilisé
List<String> people = Arrays.asList("Yamada","Tanaka","Suzuki");
String firsPerson = null;
for(String s : people){
if(s.length() == 3){
firsPerson = s;
break;
}
}
//chèque nul
if(firsPerson != null){
System.out.println(firsPerson);
}
//Utilisez facultatif et exécutez uniquement lorsque la valeur existe
Optional<String> firstPerson = Stream.of("Yamada","Tanaka","Suzuki")
.filter(s -> s.length() == 3)
.findFirst();
firstPerson.ifPresent(System.out::println);
Appelle le consommateur spécifié avec cette valeur s'il existe, sinon il ne fait rien.
Predicate
Renvoie le booléen du résultat du traitement. De plus, le traitement peut être connecté, donc s'il y a un traitement qui connecte un grand nombre d'instructions if, Il peut être utilisé efficacement.
Implémentez un processus qui prend une valeur de type T comme argument et renvoie une valeur booléenne. La valeur de boolean est renvoyée en donnant l'argument T à la méthode de test.
Predicate<String> predicate = s -> s.length() == 5;
System.out.println(predicate.test("tarou"));
Function
Représente une fonction qui prend un argument et produit un résultat.
Implémentez le processus de réception d'un argument de type T et de renvoi d'une valeur de type R. Il peut être exécuté en donnant l'argument T à la méthode apply.
Function<String,String> toUpper = s -> s.toUpperCase();
System.out.println(toUpper.apply("tarou"));
Consumer
Reçoit une valeur de type T comme argument et implémente le traitement sans valeur de retour. Il peut être exécuté en donnant l'argument T à la méthode accept.
Consumer<String> consumer = string -> System.out.println("Cunsumer : " + string);
consumer.accept("tarou");
comming soon
comming soon
Recommended Posts