Maison >Java >javaDidacticiel >Article Donner la préférence aux fonctions sans effets secondaires dans les streams

Article Donner la préférence aux fonctions sans effets secondaires dans les streams

WBOY
WBOYoriginal
2024-08-08 16:46:52712parcourir

Item  Dê preferência às funções sem efeitos colaterais nas streams

Introduction à l'utilisation des flux :

  • Les nouveaux utilisateurs peuvent avoir des difficultés à exprimer des calculs dans des pipelines de flux.
  • Les flux sont basés sur une programmation fonctionnelle, offrant expressivité, rapidité et parallélisation.

Structure du calcul :

  • Calculs de structure sous forme de séquences de transformations utilisant des fonctions pures.
  • Les fonctions pures dépendent uniquement de leurs entrées et ne changent pas d'état.

Effets secondaires :

  • Évitez les effets secondaires dans les fonctions transmises aux opérations de flux.
  • Une mauvaise utilisation de forEach qui change l'état externe est une "mauvaise odeur".

Exemple 1 : Code avec effets secondaires

Map<String, Long> freq = new HashMap<>();
try (Stream<String> words = new Scanner(file).tokens()) {
    words.forEach(word -> {
        freq.merge(word.toLowerCase(), 1L, Long::sum);
    });
}

Problème : Ce code utilise forEach pour modifier l'état externe (freq). Il est itératif et ne profite pas des streams.

Exemple 2 : Code sans effets secondaires

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
}

Solution : Utilise le collecteur Collectors.groupingBy pour créer la table de fréquences sans changer l'état externe. Plus court, plus clair et plus efficace.

Appropriation de l'API streams :

  • Le code qui imite les boucles itératives ne profite pas des flux.
  • Utilisez des collecteurs pour des opérations plus efficaces et plus lisibles.

Collectionneurs :

  • Simplifiez la collecte des résultats dans des collections telles que des listes et des ensembles.
  • Collectors.toList(), Collectors.toSet(), Collectors.toCollection(collectionFactory).

Exemple 3 : Extraire une liste des dix mots les plus fréquents

List<String> topTen = freq.entrySet().stream()
    .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
    .limit(10)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

Explication :

  • Classe les entrées de la carte de fréquence par ordre décroissant de valeur.
  • Lime le flux à 10 mots.
  • Collecte les mots les plus fréquents dans une liste.

Complexité de l'API Collectors :

  • L'API dispose de 39 méthodes, mais beaucoup sont destinées à une utilisation avancée.
  • Les collecteurs peuvent être utilisés pour créer des cartes (toMap, groupingBy).

Cartes et stratégies de collecte :

  • toMap(keyMapper, valueMapper) pour des valeurs-clés uniques.
  • Stratégies pour gérer les conflits de clés à l'aide de la fonction de fusion.
  • groupingBy pour regrouper les éléments en catégories en fonction des fonctions de classificateur.

Exemple 4 : Utilisation de toMap avec la fonction de fusion

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.toMap(
        String::toLowerCase, 
        word -> 1L, 
        Long::sum
    ));
}

Explication :

  • toMap mappe les mots à leurs fréquences.
  • La fonction de fusion (Long::sum) gère les conflits de clés en additionnant les fréquences.

Exemple 5 : Regrouper les albums par artiste et trouver l'album le plus vendu

Map<Artist, Album> topAlbums = albums.stream()
    .collect(Collectors.toMap(
        Album::getArtist,
        Function.identity(),
        BinaryOperator.maxBy(Comparator.comparing(Album::sales))
    ));

Explication :

  • toMap mappe les artistes vers leurs albums les plus vendus.
  • BinaryOperator.maxBy détermine l'album le plus vendu pour chaque artiste.

Collection de chaînes :
Collectors.joining pour concaténer des chaînes avec des délimiteurs facultatifs.

Exemple 6 : Concaténation de chaînes avec délimiteur

String result = Stream.of("came", "saw", "conquered")
    .collect(Collectors.joining(", ", "[", "]"));

Explication :

  • Collectors.joining concatène les chaînes avec une virgule comme délimiteur, préfixe et suffixe.
  • Résultat : [venu, vu, conquis].

Conclusion :

  • L'essence des flux est dans des fonctions sans effets secondaires.
  • forEach ne doit être utilisé que pour rapporter les résultats.
  • La connaissance des collectionneurs est essentielle pour une utilisation efficace des flux.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn