Références de Méthode en Java (::
)
Salut à tous ! Aujourd’hui, je veux vous parler d’une fonctionnalité super pratique introduite dans Java 8 : les références de méthode (ou method references
en anglais). Si vous en avez marre d'écrire des lambdas qui font simplement appel à une méthode existante, cette fonctionnalité va vous simplifier la vie. On va voir ensemble ce que c'est, pourquoi c'est utile, et comment l'utiliser avec plein d'exemples, en incluant des comparaisons avant et après pour bien comprendre l'amélioration.
Qu’est-ce qu’une Référence de Méthode (::
) ?
Une référence de méthode est une manière abrégée d’écrire une expression lambda qui appelle simplement une méthode existante. Plutôt que de réécrire une lambda qui ne fait qu’appeler une méthode, vous pouvez utiliser une référence de méthode pour rendre votre code plus concis et lisible.
Les Quatre Types de Références de Méthode
Il existe quatre types principaux de références de méthode en Java. Chacun correspond à un type particulier de méthode que vous voulez appeler.
1. Référence à une Méthode d’Instance d’un Objet Particulier
Ce type de référence de méthode est utilisé pour appeler une méthode d’instance sur un objet spécifique.
Avant :
String str = "hello";
Supplier<String> supplier = () -> str.toUpperCase();
System.out.println(supplier.get()); // Output: HELLO
Après :
String str = "hello";
Supplier<String> supplier = str::toUpperCase;
System.out.println(supplier.get()); // Output: HELLO
Explication :
Ici, str::toUpperCase
est une référence à la méthode toUpperCase()
de l'objet str
. La méthode est appelée via supplier.get()
, ce qui produit "HELLO". En utilisant une référence de méthode, on évite de répéter l'appel à str.toUpperCase()
dans la lambda, rendant le code plus propre.
2. Référence à une Méthode d’Instance d’un Objet Arbitraire d’un Type Particulier
Ce type de référence de méthode est utilisé lorsque vous voulez appeler une méthode d’instance sur des objets passés en paramètre d’une opération, comme dans un Stream.
Avant :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(name -> name.length())
.collect(Collectors.toList());
System.out.println(nameLengths); // Output: [5, 3, 7]
Après :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(nameLengths); // Output: [5, 3, 7]
Explication :String::length
est une référence à la méthode length()
de chaque chaîne de la liste. En utilisant une référence de méthode, on simplifie la syntaxe de la lambda en appelant directement la méthode length
sur chaque élément.
3. Référence à une Méthode Statique
Une référence à une méthode statique est utilisée pour appeler une méthode statique d’une classe.
Avant :
List<Integer> numbers = Arrays.asList(3, 5, 2, 8, 1);
int max = numbers.stream()
.reduce((a, b) -> Integer.max(a, b))
.get();
System.out.println(max); // Output: 8
Après :
List<Integer> numbers = Arrays.asList(3, 5, 2, 8, 1);
int max = numbers.stream()
.reduce(Integer::max)
.get();
System.out.println(max); // Output: 8
Explication :Integer::max
est une référence à la méthode statique max()
de la classe Integer
. En utilisant la référence de méthode, on rend le code plus lisible en supprimant le besoin d'écrire la lambda qui appelle Integer.max()
.
4. Référence à un Constructeur
Une référence de méthode peut également pointer vers un constructeur, ce qui est utile lorsque vous voulez créer de nouveaux objets dans un Stream ou avec une lambda.
Avant :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Person> people = names.stream()
.map(name -> new Person(name))
.collect(Collectors.toList());
System.out.println(people); // Output: [Person{name='Alice'}, Person{name='Bob'}, Person{name='Charlie'}]
Après :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Person> people = names.stream()
.map(Person::new)
.collect(Collectors.toList());
System.out.println(people); // Output: [Person{name='Alice'}, Person{name='Bob'}, Person{name='Charlie'}]
Explication :Person::new
est une référence au constructeur de la classe Person
. En utilisant une référence de méthode, on simplifie la syntaxe de la lambda qui appelait le constructeur new Person(name)
pour chaque nom.
Pourquoi Utiliser les Références de Méthode ?
Les références de méthode rendent le code plus concis et lisible. Elles sont particulièrement utiles lorsque vous avez une lambda qui ne fait que déléguer le travail à une méthode existante. Plutôt que d’écrire une lambda qui appelle une méthode, vous pouvez utiliser une référence de méthode pour simplifier le code.
Avant :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(name -> name.length())
.collect(Collectors.toList());
System.out.println(nameLengths); // Output: [5, 3, 7]
Après :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<Integer> nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(nameLengths); // Output: [5, 3, 7]
Avantages :
- Clarté : Le code est plus clair, car on voit directement quelle méthode est appelée.
- Réutilisation : Vous réutilisez les méthodes existantes sans avoir à écrire de nouvelles lambdas.
- Moins de Code : Le code est plus court et plus concis, ce qui réduit le risque d’erreurs.
Quand ne pas utiliser les Références de Méthode ?
Les références de méthode sont très pratiques, mais elles ne sont pas toujours la meilleure solution. Si votre lambda est complexe ou combine plusieurs opérations, une lambda classique peut être plus appropriée. Par exemple, si vous avez besoin de plus de contrôle sur les paramètres ou si vous faites plus qu’un simple appel de méthode, une lambda pourrait être plus lisible.
Avant :
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> upperCaseNames = names.stream()
.map(name -> {
String upperName = name.toUpperCase();
return upperName.substring(0, 2);
})
.collect(Collectors.toList());
System.out.println(upperCaseNames); // Output: [AL, BO, CH]
Après :
Dans ce cas, une référence de méthode ne serait pas appropriée, car la transformation des noms est plus complexe et nécessite plusieurs étapes.
Conclusion
Les références de méthode (::
) en Java sont une fonctionnalité puissante et élégante qui vous permet de rendre votre code plus concis, plus lisible, et plus facile à maintenir. Elles sont particulièrement utiles lorsque vous travaillez avec l'API Stream ou d'autres fonctionnalités de programmation fonctionnelle en Java.
Cependant, comme pour tout outil, il faut savoir quand les utiliser. Elles sont parfaites pour les tâches simples où une méthode existante fait exactement ce que vous voulez, mais pour les opérations plus complexes, les lambdas classiques peuvent être plus adaptées.
Alors, n’hésitez pas à utiliser les références de méthode dans votre code, et profitez de cette belle simplicité qu’elles apportent !
À bientôt pour la suite !
Terence NZIDJOUO votre Artisan Développeur