I. Introduction▲
Sans conteste, la meilleure manière de découvrir une bibliothèque est de parcourir chacune de ses méthodes et de les implémenter les unes après les autres pour comprendre les subtilités de chacune.
Ce tutoriel sur l’exploration de la bibliothèque Guava de Google reprend l’ensemble des méthodes statiques composant la classe utilitaire Collections2. Bonne lecture à tous.
II. Ajouter Google Guava à votre projet (Rappel)▲
La bibliothèque Google Guava peut être ajoutée de plusieurs façons dans un projet. La façon la plus triviale est de récupérer le .jar depuis le site de Google, puis de le placer directement dans la bibliothèque de votre projet.
Une autre façon plus élégante est d’utiliser un outil industrialisé de build comme Apache Maven ou Gradle en y ajoutant la dépendance requise de Google Guava.
2.
3.
4.
5.
6.
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>
com.google.guava</groupId>
<artifactId>
guava</artifactId>
<version>
30.1-jre</version>
</dependency>
III. La classe utilitaire Collections2▲
Force est de constater que tout développeur familier avec le langage Java connaît l’utilité pratique de l’API Collections.
Google Guava est allé encore plus loin dans l’implémentation des fonctionnalités sous-jacentes à l’utilisation des objets itérables. Les développeurs de Google ont conçu de nombreuses méthodes utilitaires statiques permettant une gestion efficiente lorsqu’on travaille avec des objets sur lesquels on peut itérer.
Mieux qu’un long discours dans le chapitre suivant, nous mettrons en œuvre la richesse de cette bibliothèque à travers un cas pratique de gestion d’un parc automobile.
IV. Implémentation des méthodes de la classe Collections2▲
IV-A. Les imports▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
import
com.google.common.collect.Collections2;
import
static
java.lang.System.out;
import
java.util.ArrayList;
import
java.util.Arrays;
import
java.util.Collection;
import
java.util.Comparator;
import
java.util.HashSet;
import
java.util.List;
import
java.util.Stack;
import
java.util.function.Function;
import
java.util.function.Predicate;
IV-B. Les attributs, les blocs et les méthodes statiques▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
public
final
class
Application {
private
final
static
Collection<
String>
mitsubishi;
static
{
// les structures de données
mitsubishi =
new
Stack<>(
);
mitsubishi.add
(
"Mitsubishi Space Star"
);
mitsubishi.add
(
"Mitsubishi Outlander"
);
mitsubishi.add
(
"Mitsubishi Outlander PHEV"
);
mitsubishi.add
(
"Mitsubishi Eclipse Cross PHEV"
);
mitsubishi.add
(
"Mitsubishi SUV ASX"
);
}
private
final
static
Collection<
String>
audi;
static
{
audi =
new
HashSet<>(
);
audi.add
(
"Audi Nouvelle A8 L TFSI e"
);
audi.add
(
"Audi A7 Sportback TFSI e"
);
audi.add
(
"Audi A6 Berline TFSI"
);
audi.add
(
"Audi A5 Sportback"
);
audi.add
(
"Audi A4 Berline"
);
audi.add
(
"Audi Nouvelle A3 Sportback"
);
audi.add
(
"Audi A1 Sportback"
);
}
final
static
Collection<
Float>
consommations;
static
{
// la consommation du litre/100km, on voit qu'elle est très élevée.
consommations =
new
ArrayList<>(
);
consommations.add
(
4.3
f);
consommations.add
(
5.8
f);
consommations.add
(
6.9
f);
consommations.add
(
7.4
f);
consommations.add
(
8.5
f);
consommations.add
(
9.2
f);
}
final
static
Iterable<
String>
iterableCarburants =
Arrays.asList
(
new
String[]{
"GPL"
, "Diesel"
, "GNV"
, "Hybride"
, "Biodiesel"
, "Electrique"
, "Essence Sans Plomb 95"
, "Essence Sans Plomb 98"
}
);
// predicate
private
final
static
Predicate<
String>
typeOutlander =
t ->
t.contains
(
"Outlander"
);
public
static
void
main
(
String[] args) {
// commençons par afficher la liste des véhicules de la marque Mitsubishi
out.println
(
mitsubishi); // [Mitsubishi Space Star, Mitsubishi Outlander, Mitsubishi Outlander PHEV, Mitsubishi Eclipse Cross PHEV, Mitsubishi SUV ASX]
}
IV-C. La méthode filter▲
Cette méthode permet de renvoyer tous les éléments d’une collection répondant à un prédicat (condition déterministe) défini. Nous voulons restituer tous les véhicules de la marque Mitsubishi de type Outlander.
2.
Collection<
String>
filterMitsubishiOutlander =
Collections2.filter
(
mitsubishi, typeOutlander::test);
out.println
(
filterMitsubishiOutlander); // [Mitsubishi Outlander, Mitsubishi Outlander PHEV]
IV-D. La méthode orderedPermutations▲
Cette méthode permet de renvoyer une collection immuable ordonnée de toutes les permutations de l'objet Iterable spécifié en paramètre.
IV-D-1. orderedPermutations(Iterable<E> elements)▲
Nous souhaitons effectuer une permutation triée de tous nos carburants.
2.
3.
out.println
(
iterableCarburants); // [GPL, Diesel, GNV, Hybride, Biodiesel, Electrique, Essence sans plomb 95, Essence sans plomb 98]
Collection<
List<
String>>
orderedPermutationsCarburants =
Collections2.orderedPermutations
(
iterableCarburants);
out.println
(
orderedPermutationsCarburants); // orderedPermutationCollection([Biodiesel, Diesel, Electrique, Essence sans plomb 95, Essence sans plomb 98, GNV, GPL, Hybride])
IV-D-2. orderedPermutations(Iterable<E> elements, Comparator<? super E> comparator)▲
Cette méthode existe sous une autre signature ayant comme paramètres un objet de type Iterable et un objet de type Comparator. Ainsi, nous pouvons effectuer une permutation triée en fonction de la longueur du nom du carburant le plus long.
2.
3.
4.
// nous voulons effectuer un tri permuté en fonction de la longueur du nom du carburant du plus long au plus court
final
Comparator<
String>
comparator =
(
String o1, String o2) ->
(
o2.length
(
) -
o1.length
(
));
Collection<
List<
String>>
orderedPermutationsWithComparator =
Collections2.orderedPermutations
(
iterableCarburants, comparator);
out.println
(
orderedPermutationsWithComparator); // orderedPermutationCollection([Essence sans plomb 95, Essence sans plomb 98, Biodiesel, Electrique, Hybride, Diesel, GPL, GNV])
IV-E. La méthode permutations▲
Admettons que nous souhaitions restituer toutes les permutations d’un objet de type collection, la méthode permutations(Collection<E> elements) nous permet aisément d’effectuer cette opération. Effectuons cette opération sur les véhicules de la marque Audi.
2.
3.
4.
5.
6.
7.
8.
9.
10.
audi.stream
(
).forEach
(
System.out::println);
/* Audi A6 Berline TFSI
Audi A4 Berline
Audi A5 Sportback
Audi Nouvelle A8 L TFSI e
Audi A1 Sportback
Audi Nouvelle A3 Sportback
Audi A7 Sportback TFSI e */
Collection<
List<
String>>
permutationsVehiculeAudi =
Collections2.permutations
(
audi);
out.println
(
permutationsVehiculeAudi); // permutations([Audi A6 Berline TFSI, Audi A4 Berline, Audi A5 Sportback, Audi Nouvelle A8 L TFSI e, Audi A1 Sportback, Audi Nouvelle A3 Sportback, Audi A7 Sportback TFSI e])
IV-F. La méthode transform▲
Nous voulons désormais renvoyer une Collection sur laquelle une fonction a été appliquée sur chaque élément. La Collection renvoyée est une vue en direct de cette dernière suite à la transformation des éléments.
2.
3.
4.
// on a trouvé un procédé permettant de gagner 40% sur la consommation de nos véhicules mesurée en litres pour 100 km
final
Function<
Float, Float>
multiplier =
t ->
t *
0.6
f;
final
Collection<
Float>
diminuerConsommation =
Collections2.transform
(
consommations, multiplier::apply);
out.println
(
diminuerConsommation); // [2.5800002, 3.4800003, 4.1400003, 4.44, 5.1000004, 5.52]
V. Conclusion▲
Nous avons fait le tour des méthodes utilitaires présentes dans la classe Collections. Comme vous avez pu le constater, ces méthodes sont à la fois très simples d’utilisation et particulièrement efficaces. Je vous invite fortement à les implémenter dans vos projets, car elles vous apporteront des avantages sans précédent en termes de productivité.
Par ailleurs, je vous invite à créer un fil de discussion afin d’y laisser tous vos commentaires pour l’appréciation, voire pour l’amélioration des futurs tutoriels.
VI. Remerciements▲
Je remercie escartefigue pour la relecture orthographique de cet article, la communauté developpez.com qui propose un forum d’entraide d’une richesse fortement appréciable, Mickael Baron qui donne de son temps pour s’occuper de la rubrique Java, et surtout RomeoBeni pour l’écriture d’un ouvrage d’une rare simplicité dans l’apprentissage de la programmation en Java.
Pour finir merci encore à tous les membres répondant aux questions des débutants en programmation. Un grand merci à tous.