Fonctions essentielles de l'API Stream en Java

0. Exemple de classe et de données


class Etudiant {
    private int echecs;
    private String nom;
    private String profChinois;
    private String profPrincipal;

    public Etudiant(int echecs, String nom, String profChinois, String profPrincipal) {
        this.echecs = echecs;
        this.nom = nom;
        this.profChinois = profChinois;
        this.profPrincipal = profPrincipal;
    }

    public int getEchecs() { return echecs; }
    public String getNom() { return nom; }
    public String getProfChinois() { return profChinois; }
    public String getProfPrincipal() { return profPrincipal; }

    public void setEchecs(int echecs) { this.echecs = echecs; }
    public void setNom(String nom) { this.nom = nom; }
    public void setProfChinois(String profChinois) { this.profChinois = profChinois; }
    public void setProfPrincipal(String profPrincipal) { this.profPrincipal = profPrincipal; }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (!(obj instanceof Etudiant)) return false;
        Etudiant autre = (Etudiant) obj;
        return echecs == autre.echecs &&
               Objects.equals(nom, autre.nom) &&
               Objects.equals(profChinois, autre.profChinois) &&
               Objects.equals(profPrincipal, autre.profPrincipal);
    }

    @Override
    public int hashCode() {
        return Objects.hash(echecs, nom, profChinois, profPrincipal);
    }

    @Override
    public String toString() {
        return "Etudiant{echecs=" + echecs + ", nom='" + nom + "', profChinois='" + profChinois + "', profPrincipal='" + profPrincipal + "'}";
    }
}


List<Etudiant> listeEtudiants = new ArrayList<>();
listeEtudiants.add(new Etudiant(5, "zhangsan", "prof1", "prof2"));
listeEtudiants.add(new Etudiant(1, "lisi", "prof1", "prof2"));
listeEtudiants.add(new Etudiant(3, "wangwu", "prof2", "prof1"));
listeEtudiants.add(new Etudiant(10, "zhaoliu", "prof2", "prof1"));
listeEtudiants.add(new Etudiant(10, "zhaoqi", "prof2", "prof1"));

1. Opérations intermédiaires

filter : Filtre les éléments en fonction d'un prédicat défini par une expression lambda.


listeEtudiants.stream()
    .filter(etudiant -> etudiant.getEchecs() >= 3)
    .forEach(System.out::println);

map : Transforme chaque élément en appliquant une fonction de mapping.


listeEtudiants.stream()
    .map(etudiant -> etudiant.getNom().length())
    .forEach(System.out::println);

Il est courant d'utiliser map pour modifier les éléments, par exemple en ajoutant une propriété :


listeEtudiants.stream()
    .map(etudiant -> {
        if (etudiant.getEchecs() == 0) {
            etudiant.setEstExcellent(true);
        } else {
            etudiant.setEstExcellent(false);
        }
        return etudiant;
    })
    .map(etudiant -> etudiant.isEstExcellent())
    .forEach(System.out::println);

sorted : Trie les éléments selon un comparateur fourni.


listeEtudiants.stream()
    .map(Etudiant::getNom)
    .map(String::length)
    .sorted((a, b) -> b - a)
    .forEach(System.out::println);

limit : Resterint le flux aux n premiers éléments.


listeEtudiants.stream()
    .map(Etudiant::getNom)
    .map(String::length)
    .sorted((a, b) -> b - a)
    .limit(3)
    .forEach(System.out::println);

skip : Ignore les n premiers éléments du flux.


listeEtudiants.stream()
    .map(Etudiant::getNom)
    .map(String::length)
    .sorted((a, b) -> b - a)
    .skip(3)
    .forEach(System.out::println);

distinct : Élimine les doublons du flux.


listeEtudiants.stream()
    .map(Etudiant::getNom)
    .map(String::length)
    .sorted((a, b) -> b - a)
    .distinct()
    .forEach(System.out::println);

2. Opérations terminales

forEach : Applique une action à chaque élément, ne retourne pas de flux.

peek : Similaire à forEach mais utilisé en milieu de pipeline, retourne le flux.


Optional<Integer> resultat = listeEtudiants.stream()
    .map(etudiant -> etudiant.getNom().length())
    .sorted((a, b) -> b - a)
    .distinct()
    .peek(System.out::println)
    .reduce((somme, val) -> somme + val);
System.out.println(resultat.get());

reduce : Agrège les éléments en une seule valeur.

collect : Transforme le flux en une collection souhaitée.


Map<String, List<Etudiant>> regroupement = listeEtudiants.stream()
    .filter(etudiant -> etudiant.getEchecs() >= 2)
    .collect(Collectors.groupingBy(Etudiant::getProfChinois));
System.out.println(regroupement);


List<Etudiant> listeFiltree = listeEtudiants.stream()
    .filter(etudiant -> etudiant.getEchecs() >= 2)
    .collect(Collectors.toList());
System.out.println(listeFiltree);

allMatch : Vérifie si tous les éléments satifsont un prédicat.


boolean tousAdmis = listeEtudiants.stream()
    .allMatch(etudiant -> etudiant.getEchecs() == 0);
System.out.println(tousAdmis);

anyMatch : Vérifie si au moins un élément satisfait un prédicat.


boolean auMoinsUnAdmis = listeEtudiants.stream()
    .anyMatch(etudiant -> etudiant.getEchecs() == 0);
System.out.println(auMoinsUnAdmis);

noneMatch : Vérifie si aucun élément ne satisfait un prédicat.


boolean aucunAdmis = listeEtudiants.stream()
    .noneMatch(etudiant -> etudiant.getEchecs() == 0);
System.out.println(aucunAdmis);

findFirst : Récupère le premier élément du flux.


Optional<Etudiant> premier = listeEtudiants.stream().findFirst();
System.out.println(premier.get());

findAny : Récupère un élément arbitraire ; identique à findFirst dans un flux séquentiel, utile en parallèle.


Optional<Etudiant> nimporteQuel = listeEtudiants.parallelStream().findAny();
System.out.println(nimporteQuel.get());

count : Retourne le nombre d'éléments dans le flux.


long nombre = listeEtudiants.stream()
    .map(Etudiant::getEchecs)
    .distinct()
    .peek(System.out::println)
    .count();
System.out.println(nombre);

max/min : Retourne le maximum ou le minimum selon un comparateur.


Optional<Integer> maximum = listeEtudiants.stream()
    .map(Etudiant::getEchecs)
    .distinct()
    .max(Integer::compareTo);
System.out.println(maximum.get());


Optional<Integer> minimum = listeEtudiants.stream()
    .map(Etudiant::getEchecs)
    .distinct()
    .min(Integer::compareTo);
System.out.println(minimum.get());

parallel/parallelStream : Convertit le flux en mode parallèle pour accélérer le traitement (attention à la concurrence).


Optional<Etudiant> parallele = listeEtudiants.parallelStream().findAny();
System.out.println(parallele.get());

Étiquettes: Java Stream API Lambda collections

Publié le 21 juillet à 19h45