Java Streams pour les débutants: une introduction à l’utilisation de Streams en Java

Les flux Java 8 permettent aux développeurs d'extraire des données précises d'une grande collection, à l'aide d'un ensemble d'opérations prédéfinies.

Avant la sortie de Java 8, l'utilisation du terme «flux» en Java serait automatiquement associée aux E / S. Cependant, Java 8 a introduit un flux que l'on peut appeler un ensemble d'étapes de calcul enchaînées dans ce que l'on appelle communément un «pipeline de flux».

Cet article vous présentera les flux Java 8 et vous montrera comment ils peuvent être utiles dans vos projets.

Qu'est-ce qu'un flux?

Un flux est une interface Java qui prend une source, effectue un ensemble d'opérations pour extraire des données spécifiques, puis fournit ces données à l'application pour utilisation. Essentiellement, il vous permet d'extraire des données spécialisées à partir d'une collection de données généralisées.

Comment fonctionnent les flux

Un pipeline de flux commence toujours par une source. Le type de source dépend du type de données avec lesquelles vous traitez, mais deux des plus populaires sont les tableaux et les collections.

Pour transformer la collection en un flux initial, vous devrez ajouter la fonction stream () à la source. Cela placera la source dans le pipeline de flux où plusieurs opérations intermédiaires différentes (telles que filter () et sort () ) peuvent y opérer.

Une fois toutes les opérations intermédiaires requises effectuées, vous pouvez introduire une opération de terminal (telle que forEach () ), qui produira les données précédemment extraites de la source.

La vie sans ruisseaux

Java 8 est sorti en 2014, mais avant cela, les développeurs Java devaient encore extraire des données spécialisées d'une collection de données générales.

Supposons que vous ayez une liste de caractères aléatoires qui sont combinés avec des nombres aléatoires pour former des valeurs de chaîne uniques, mais que vous ne voulez que les valeurs qui commencent par le caractère «C» et que vous souhaitez organiser le résultat dans l'ordre croissant. C'est ainsi que vous extrairiez ces données sans flux.

Connexes: ce que vous devez savoir sur l'utilisation des chaînes en Java

Exemple de filtrage et de tri des valeurs sans flux

 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "C13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "C16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//declare the array list will store needed values
List<String> requiredValues = new ArrayList<>();
//extracting the required values and storing them in reqquiredValues
randomValues.forEach(value -> {
if(value.startsWith("C")) {
requiredValues.add(value);
}
});
//sort the requiredValues in ascending order
requiredValues.sort((String value1, String value2) -> value1.compareTo(value2));
//print each value to the console
requiredValues.forEach((String value) -> System.out.println(value));
}
}

Vous devrez également déclarer et initialiser la liste des tableaux, que vous utilisiez des flux ou une autre méthode d'extraction. Ce que vous n'auriez pas besoin de faire si vous utilisiez des flux, c'est de déclarer une nouvelle variable contenant les valeurs requises, ni de créer les cinq autres lignes de code plus dans l'exemple ci-dessus.

Connexes: Comment créer et effectuer des opérations sur des baies en Java

Le code ci-dessus produit la sortie suivante dans la console:

 
C11
C12
C13
C14
C15
C16

La vie avec les ruisseaux

En programmation, l'efficacité signifie produire le même résultat avec beaucoup moins de code. C'est exactement ce que fait un pipeline de flux pour un programmeur. Alors, la prochaine fois que quelqu'un vous demandera: "Pourquoi est-il important d'utiliser des flux dans votre projet?" En termes simples: «les flux prennent en charge une programmation efficace.»

En continuant avec notre exemple ci-dessus, voici comment l'introduction de flux transforme l'ensemble du programme.

Filtrage et tri des valeurs avec un exemple de flux

 
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "C13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "C16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().filter(value->value.startsWith("C")).sorted().forEach(System.out::println);
}
}

Le code ci-dessus montre à quel point l'interface de flux est puissante. Il prend une liste de valeurs de tableau aléatoires et la transforme en un flux à l'aide de la fonction stream () . Le flux est ensuite réduit à une liste de tableaux contenant les valeurs requises (qui sont toutes les valeurs commençant par C ), à l'aide de la fonction filter () .

Comme vous pouvez le voir dans l'exemple ci-dessus, les valeurs C sont disposées de manière aléatoire dans la liste des tableaux. Si vous deviez imprimer le flux à ce stade du pipeline, la valeur C15 serait imprimée en premier. Par conséquent, la fonction sort () est introduite dans le pipeline de flux pour réorganiser le nouveau tableau dans l'ordre croissant.

La fonction finale du pipeline de flux est une fonction forEach () . Il s'agit d'une fonction de terminal utilisée pour arrêter le pipeline de flux et qui produit les résultats suivants dans la console:

 
C11
C12
C13
C14
C15
C16

Opérations intermédiaires de flux

Il existe une longue liste d'opérations intermédiaires pouvant être utilisées dans un pipeline de flux.

Un pipeline de flux commence toujours par une seule source et une fonction stream () , et se termine toujours par une seule opération de terminal (bien qu'il y en ait plusieurs parmi lesquelles choisir.) Mais entre ces deux sections se trouve une liste de six opérations intermédiaires qui vous pouvez utiliser.

Dans notre exemple ci-dessus, seules deux de ces opérations intermédiaires sont utilisées: filter () et sort () . L'opération intermédiaire que vous choisissez dépendra des tâches que vous souhaitez effectuer.

Si l'une des valeurs commençant par «C» dans notre liste de tableaux ci-dessus était en minuscules et que nous effectuions les mêmes opérations intermédiaires sur elles, nous obtiendrions le résultat suivant.

Exécution d'opérations de filtrage et de tri sur des valeurs minuscules Exemple

 
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "c13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "c16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().filter(value->value.startsWith("C")).sorted().forEach(System.out::println);
}
}

Le code ci-dessus produira les valeurs suivantes dans la console:

 
C11
C12
C14
C15

Le seul problème avec la sortie ci-dessus est qu'elle ne représente pas avec précision toutes les valeurs C de notre liste de tableaux. Un bon moyen de corriger cette petite erreur est d'introduire une autre opération intermédiaire dans le pipeline de flux; cette opération est connue sous le nom de fonction map () .

Utilisation de l'exemple de fonction de carte

 
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List<String> randomValues = Arrays.asList(
"E11", "D12", "A13", "F14", "C15", "A16",
"B11", "B12", "c13", "B14", "B15", "B16",
"F12", "E13", "C11", "C14", "A15", "c16",
"F11", "C12", "D13", "E14", "D15", "D16"
);
//transforms all lower case characters to upper case,
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().map(String::toUpperCase).filter(value->value.startsWith("C")).sorted().forEach(System.out::println);
}
}

La fonction map () transforme un objet d'un état à un autre; dans notre exemple ci-dessus, il transforme tous les caractères minuscules de la liste des tableaux en caractères majuscules.

Placer la fonction map () juste avant que la fonction filter () récupère toutes les valeurs commençant par C dans la liste des tableaux.

Le code ci-dessus produit le résultat suivant dans la console, représentant avec succès toutes les valeurs C de la liste de tableaux.

 
C11
C12
C13
C14
C15
C16

Les trois autres opérations intermédiaires que vous pouvez utiliser dans vos applications incluent:

  • coup d'oeil ()
  • limite()
  • sauter()

Les flux Java 8 facilitent la création d'un code efficace

Avec les flux Java 8, vous pouvez extraire des données supplémentaires spécifiques et pertinentes à partir d'une grande source avec une seule ligne de code. Tant que vous incluez la fonction stream () initiale et un opérateur de terminal, vous pouvez utiliser n'importe quelle combinaison d'opérations intermédiaires qui fournissent des sorties adaptées à votre objectif.

Si vous vous interrogez sur la ligne de code incluse dans notre fonction filter () ; c'est ce qu'on appelle une «expression lambda». Les expressions Lambda sont une autre fonctionnalité introduite avec Java 8, et elles contiennent de nombreuses pépites que vous pourriez trouver utiles.