JavaRush /Blog Java /Random-FR /Pause café #108. 12 utilisations courantes des flux Java,...

Pause café #108. 12 utilisations courantes des flux Java, comment évaluer l'allocation de mémoire d'un objet en Java

Publié dans le groupe Random-FR

12 façons courantes d'utiliser les flux Java

Source : Dev.to L'API Java Streams est apparue pour la première fois dans Java 8. Son objectif est de fournir un moyen plus compact d'effectuer des opérations courantes sur des collections d'objets. En outre, l'API Java Streams peut être utilisée pour implémenter des algorithmes complexes. Dans cet article, nous parlerons des cas d'utilisation courants de Java Streams. Pause café #108.  12 Utilisations courantes des flux Java, Comment évaluer l'allocation de mémoire d'un objet en Java - 1Tout d’abord, clarifions quelques notions de base :
  • stream() - crée un flux à partir de la collection.

  • collect() - collecte un flux dans un objet. Un objet peut être une collection, une primitive ou une classe personnalisée.

  • Collectors est une classe qui fournit (de nombreuses) méthodes statiques pour collecter des flux.

Examinons maintenant quelques cas d'utilisation de Streams :

1. Filtrage

  • Utilisé pour supprimer des valeurs d'une collection en fonction d'une condition.

  • Pour filtrer les éléments de la collection en fonction d'une condition, utilisez la méthode filter() . Seuls les éléments correspondants sont enregistrés.

Exemple : supprimez tous les nombres impairs de la liste.
List<Integer> evenNumbers = originalList.stream()
        .filter(n -> n % 2 == 0)
        .collect(Collectors.toList());

2. Prétraitement

  • Utile lorsque chaque valeur d’une collection doit être modifiée sur place.

  • La méthode map() permet d'appliquer une fonction à chaque élément de la collection et de renvoyer une nouvelle collection de valeurs calculées.

Par exemple, convertissons chaque valeur en son carré.
List<Integer> squares = originalList.stream()
        .map(n -> n * n)
        .collect(Collectors.toList());

3. Conversions

  • Utile lorsque l'on souhaite transformer une collection en une autre collection.

  • Il existe plusieurs façons d'y parvenir.

Comme mentionné ci-dessus, nous pouvons utiliser les méthodes map() et collect() pour transformer une collection en une autre collection.

Exemple 1 : créer une carte à partir de listes.

Convertissez une liste de chaînes en une carte de chaînes et de longueurs.
Map<String, Integer> wordLengths = words.stream()
        .collect(Collectors.toMap(
                word -> word,
                word -> word.length()));

Exemple 2. Conversion d'une liste en ensembles.

Il s'agit d'un cas d'utilisation courant pour supprimer les doublons. De plus, si nous voulons remettre des éléments dans la liste, nous pouvons utiliser les méthodes stream() et collect() deux fois . Par exemple, convertissons une liste de chaînes en une liste de chaînes uniques :
// if we want to collect to a set
Set<String> uniqueWords = words.stream()
        .collect(Collectors.toSet());

// OR

// if we want to start and end as a list
List<String> uniqueWords = words.stream()
        .collect(Collectors.toSet()).stream().collect(Collectors.toList());

Exemple 3. Conversion d'une liste de produits en une liste de leurs noms. (Aplatissement - Alignement)

List<String> productNames = products.stream()
        .map(product -> product.getName())
        .collect(Collectors.toList());

4. Réduction

  • Réduit Collection à une seule valeur.

  • La méthode réduire() est utilisée pour appliquer une fonction à chaque élément de la collection et renvoyer une valeur unique.

Notez que puisque la méthode réduire() renvoie une valeur unique, elle ne peut pas être utilisée pour renvoyer une collection. Exemple, on résume toutes les valeurs de la liste :
int sum = numbers.stream()
        .reduce(0, (a, b) -> a + b);

5. Regroupement

  • Regroupe les éléments d'une collection en fonction d'une condition donnée.

  • Pour regrouper les éléments de la collection par condition, utilisez la méthode Collectors.groupingBy() .

Par exemple, regroupons tous les produits dans des listes de produits selon leurs catégories.
Map<String, List<Product>> productsByCategory = products.stream()
        .collect(Collectors.groupingBy(product -> product.getCategory()));

6. Trouver

  • Recherche le premier ou tout élément de collection qui correspond à une condition.

  • Les méthodes findFirst() et findAny() sont utilisées pour la recherche .

Ceci est généralement similaire à une recherche linéaire. Par exemple, nous recherchons le premier mot de la liste dont la longueur dépasse 5 caractères.
Optional<String> firstLongWord = words.stream()
        .filter(word -> word.length() > 5)
        .findFirst();
// Note that findFirst() and findAny() methods return Optional<T> objects.

7. Tri

  • Trie les éléments des collections.

  • La méthode sorted() est utilisée pour le tri .

Généralement, Collections.sort() suffit pour trier une collection. Nous pouvons utiliser sorted() spécifiquement si nous voulons exécuter une autre opération. Par exemple, trions une liste de nombres par ordre croissant, puis renvoyons les k premiers éléments.
List<Integer> topK = numbers.stream()
        .sorted()
        .limit(k)
        .collect(Collectors.toList());

8. Partitionnement

  • Sépare les éléments d'une collection en fonction d'une condition donnée.

  • La méthode Collectors.partitioningBy() est utilisée pour séparer les éléments .

Une division est similaire à un groupe, sauf qu'elle renvoie deux collections : une pour les éléments qui correspondent à la condition et une pour les éléments qui ne correspondent pas à la condition. Par exemple, divisons les étudiants entre ceux qui ont réussi l'examen et ceux qui l'ont échoué.
Map<Boolean, List<Student>> passingFailing = students
        .stream()
        .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));

9. Compter

  • Compte le nombre d'éléments qui correspondent à une condition.

  • La méthode count() est utilisée pour compter le nombre d'éléments qui correspondent à une condition .

Par exemple, comptons le nombre de mots dans la liste dont la longueur dépasse 5 caractères.
long count = words.stream()
        .filter(word -> word.length() > 5)
        .count();

10. Gamme

  • Crée une plage de valeurs.

  • Pour créer une plage de valeurs, utilisez la méthode range() .

Il existe des classes spéciales pour créer des flux de certains types - IntStream , LongStream , DoubleStream et Stream . Ces classes sont utiles lorsque vous travaillez avec des types numériques primitifs. Pour convertir un tableau en flux, utilisez Arrays.stream() . Par exemple, créons un tableau de nombres de 0 à 10.
int[] numbers = IntStream.range(0, 10).toArray();

11. Correspondance

  • Fait correspondre les éléments d'une collection avec un prédicat (condition).

  • Des méthodes telles que anyMatch() , allMatch() et noneMatch() sont utilisées pour faire correspondre les éléments de la collection avec un prédicat et renvoyer une valeur booléenne .

Par exemple, vérifions les produits dont le prix est supérieur à 10.
// true when all elements match the predicate
boolean allMatch = products.stream()
        .allMatch(product -> product.getPrice() > 10);

// true when any element matches the predicate
boolean anyMatch = products.stream()
        .anyMatch(product -> product.getPrice() > 10);

// true when no elements match the predicate
boolean noneMatch = products.stream()
        .noneMatch(product -> product.getPrice() > 10);

12. Rejoindre

  • Concatène les éléments d'une collection dans une chaîne.

  • Pour joindre des éléments de collection dans une chaîne, utilisez la méthode Collectors.joining() .

Par exemple, concaténons tous les mots d’une liste en une seule chaîne.
String joinedWords = words.stream()
        .collect(Collectors.joining(" "));
C'est tout pour les scénarios généraux. Il existe d’autres scénarios moins courants que vous pouvez explorer par vous-même :
  • Flux parallèles ;
  • Statistiques;
  • Collectionneurs personnalisés.

Avantages des fils

  • Code plus compact : réduit la quantité de code requise pour traiter la collection.

  • Moins de variables intermédiaires. Les variables intervenantes peuvent provoquer des erreurs. Moins il y en a, plus il est facile d'éviter les erreurs inattendues.

  • Code intuitif. Certains développeurs ne seront pas d’accord sur le fait que les threads sont plus intuitifs que les autres méthodes. Cependant, une fois qu’on s’y est habitué, elles deviennent beaucoup plus intuitives que les autres méthodes.

Merci pour la lecture. J'espère que vous avez apprécié cet article. Il existe de nombreux autres cas où des threads peuvent être utilisés qui ne sont pas abordés dans cette rubrique. N'hésitez pas à ajouter tout scénario courant que j'ai manqué.

Comment évaluer l'allocation de mémoire d'un objet en Java

Source : DZone Cet article présente les trois méthodes les plus connues pour évaluer l'allocation de mémoire d'un objet en Java.

Évaluation de la mémoire à l'aide de Profiler

Le moyen le plus simple d'estimer la mémoire de certains objets est de consulter directement la mémoire de la JVM à l'aide d'un profileur tel que Visual VM . Pause café #108.  12 Utilisations courantes des flux Java, Comment évaluer l'allocation de mémoire d'un objet en Java - 2Le problème avec cette approche est que vous devez vous connecter à une JVM en cours d'exécution, ce qui peut ne pas être possible pour les environnements de production pour des raisons de sécurité.

Évaluation de la mémoire à l'aide d'instruments

Une autre façon d'estimer la mémoire allouée pour un objet donné consiste à utiliser Instruments. En termes simples, nous devons créer une classe et la compiler dans un JAR. Après avoir créé le JAR, nous devons exécuter notre JVM avec ce JAR. Vous pouvez en savoir plus sur cette méthode ici . L'inconvénient ici est la nécessité d'ajouter un fichier jar spécifique à la JVM, ce qui peut ne pas être acceptable pour la production en raison de problèmes de sécurité ou connexes.

Évaluation de la mémoire à l'aide de la bibliothèque JOL

Comme autre option, nous pouvons utiliser la bibliothèque JOL . Il s'agit d'une bibliothèque très puissante qui peut fournir une estimation détaillée du poids d'un objet et de la mémoire allouée par une instance d'objet. Pour utiliser la bibliothèque, nous devons ajouter une dépendance :
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.16</version>
</dependency>
Après cela, nous pouvons l'utiliser comme ceci :
out.println(GraphLayout.parseInstance(myObject).totalSize() / 1024000d + " MB")

ObjectSizeCalculator des archives Twitter

Le référentiel GitHub public de Twitter possède une classe d'outils appelée ObjectSizeCalculator qui peut estimer la mémoire allouée pour une instance d'objet donnée. Son utilisation ne prend pas beaucoup de mémoire ni de temps. Le processus d'évaluation prend quelques secondes, même pour les objets volumineux. Utiliser cette classe est assez simple :
ObjectSizeCalculator.getObjectSize(address)
Je recommande cette méthode, mais gardez à l'esprit qu'elle n'est prise en charge que par Java Hotspot, OpenJDK et TwitterJDK.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION