L'API
Stream dans Java 8 est utilisé pour travailler avec les collections, pour pouvoir écrire le code dans le style fonctionnel. Grâce à sa simplicité
Stream est devenu très populaire entre les programmeurs. Selon la description officielle, la bibliothèque « Java.util.stream » - nous permet de faire plusieurs opérations dans le style fonctionnel avec des collections d'éléments, tels comme les transformations de
MapReduce, etc. L'API contient les opérations « intermédiaires », comme
Stream.map ou
Stream.filter, mais aussi les opérations « finales » comme
Stream.forEach ou
Stream.reduce. L'opération « intermédiaire » ne serait jamais exécutées avant l'opération « finale » (p.e.
Stream.map ne serait pas exécutée avant
Stream.reduce, mémé si vous le mettez avant dans le code). Un tel comportement s'appelle LAZY.
Une autre grande caractéristique de l'API
Stream c'est la parallélisation des sources -
parallelStream () qui vient utilisée pour améliorer les performances pour traiter des grandes quantités de données. Les flux parallèles peuvent accélérer l'exécution pour certains types de transactions. Je les utilise quand je sais que la collection est trop grande pour être gérée avec «
ForkJoin. » Plus d'informations sur la bibliothèque
ForkJoin peut lire ici:
http://www.baeldung.com/java-fork-join.
Retournons à nos moutons et nous considérerons un exemple pratique. Un exemple simple de recherche d'un valeur min et d'un valeur max dans une collection.
ArrayList testValues = new ArrayList();
testValues.add(0,15);
testValues.add(1,1);
testValues.add(2,2);
testValues.add(3,100);
testValues.add(4,50);
Optional maxValue = testValues.stream().max(Integer::compareTo);
System.out.println("MaxValue="+maxValue);
Optional minValue = testValues.stream().min(Integer::compareTo);
System.out.println("MinValue="+minValue);
Autre exemple un peu plus compliqué où l'on ajoute une exception (quand la valeur maximale est
null):
ArrayList testValuesNull = new ArrayList();
testValuesNull.add(0,null);
testValuesNull.add(1,1);
testValuesNull.add(2,2);
testValuesNull.add(3,70);
testValuesNull.add(4,50);
Optional maxValueNotNull = testValuesNull.stream().filter((p) -> p != null).max(Integer::compareTo);
System.out.println("maxValueNotNull="+maxValueNotNull);
On peut aller encore plus loin et créer une collection que s'appelle « camp sportif » composé des champs « Nom » « Nombre de jours passés dans le camp sportif »
public class SportsCamp
{
private String name;//Nom
private Integer day;//Nombre de jours
public SportsCamp(String name, int day)
{
this.name = name;
this.day = day;
}
public String getName() { return name;}
public void setName(String name)
{
this.name = name;
}
public Integer getDay()
{
return day;
}
public void setDay(Integer day)
{
this.day = day;
}
}
Avec les nouvelles données on pourrait exécuter plusieurs opérations, p.e. trouver qui a passé plus de jours dans le camp sportif.
import java.util.Arrays;
import java.util.Collection;
public class Start
{
public static void main(String[] args)
{
Collection<SportsCamp> sport = Arrays.asList( new SportsCamp("Jean", 5), new SportsCamp("Pierre", 7), new SportsCamp("Anne", 10) );
String name = sport.stream().max((p1,p2) -> p1.getDay().compareTo(p2.getDay())).get().getName();
System.out.println("Name="+name);
}
}
Cet exemple nous va retourner le nom d'Anne - cela qui a passé plus de jours dans le camp sportif. Comme j'ai déjà dit, les opérations sont divisés en « intermédiaire » et « finales ». Dans l'exemple ci-dessus, nous pouvons ajouter un nouveau filtre pour le nom « Jean» et obtenir la fréquence, avec laquelle ce nom apparaît dans la collection:
long countName = sport.stream().filter((p) -> p.getName() != null && p.getName().equals("Jean")).count();
System.out.println("countName="+countName);
Evidemment le résultat sera = à 1 (jusqu'à ce que vous ajoutez un autre « Jean» à notre collection).
On peut aussi utiliser parallelStream () pour compter les noms:
long countNameParallel = sport.parallelStream().filter((p) -> p.getName() != null && p.getName().equals("Jean")).count();
System.out.println("countNameParallel=" + countNameParallel);
L'efficacité de parallelStream () se voit mieux sur les serveurs haut-gamme (multi-core) avec de grandes quantités de données. Il est la question de tester et d'ajuster les paramètres du serveur.
L'autre exemple serait de regarder le Map / Reduce, ou pour le moment on va regarder juste le reduce. Reduce vient utilisée pour « construire » les composants , en termes simples, si on veut produir une nouvelle instance d'objet a la maniere "agrégée", en ajoutant d'autres éléments. P.e. calculer tous les jours de tous que les participants ont passé ensemble dans le domaine sportif.
Integer daySum = sport.stream().reduce(0, (sum, p) -> sum += p.getDay(), (sum1, sum2) -> sum1 + sum2);
System.out.println("DaySize=" + daySum);//résultat = 22
Avec ce mode de réalisation, reduce prend les trois valeurs: 1.identifieur, 2.accumulateur, 3.résultat.
Aucun commentaire:
Enregistrer un commentaire