2017-07-02 7 views
4

Est-il possible de transmettre des paramètres à l'aide de la référence de méthode? Par exemple, je dois créer un TreeMap mais en utilisant reverseOrder(). Existe-t-il quelque chose comme TreeMap::new(reverseOrder())?paramètres dans la référence de méthode

+2

Une référence de méthode est une référence à une méthode existante. S'il n'existe aucune méthode qui fasse exactement ce que vous voulez, soit écrire une telle méthode (et ensuite capturer une référence à celle-ci), ou utiliser un lambda dont le corps fait ce que vous voulez. –

+0

Aussi [Argument externe à la référence de méthode dans Java 8] (https://stackoverflow.com/questions/38697939/external-argument-to-method-reference-in-java-8) et probablement [beaucoup plus] (https : //stackoverflow.com/search?q = paramètres +% 22méthode + référence% 22) –

Répondre

6

Non, vous ne pouvez pas le faire avec une référence de méthode.

Vous pouvez utiliser des expressions lambda à la place:

() -> new TreeMap<TheRelevantType>(reverseOrder()) 

ou

() -> new TreeMap<>(reverseOrder()) 

si vous utilisez cette expression dans un contexte où le compilateur peut déduire le type d'élément du TreeMap.

+2

Les types bruts, vraiment? – ZhekaKozlov

+0

@ZhekaKozlov Bon point, mais sans connaître le contexte, je ne savais pas quel type d'élément utiliser. – Eran

+0

@Eran il n'y a pas de contexte, c'était une situation générique –

5

Vous avez besoin d'une expression lambda pour cela ... vous êtes probablement penser à un Supplier:

() -> new TreeMap<>(Comparator.reverseOrder()) 
+0

Merci, j'ai imaginé que ça ne pouvait pas être fait –

1

Ceci n'est pas pris en charge par les références de méthode elles-mêmes (aujourd'hui), mais il existe de nombreux cas où les références de méthode peuvent être utilisées avec des paramètres utilisant les API Eclipse Collections. Prenons l'exemple suivant:

Map<String, TreeSet<String>> jdkMap = new HashMap<>(); 
jdkMap.put("one", new TreeSet<>(Comparator.reverseOrder())); 
jdkMap.computeIfAbsent("two", key -> new TreeSet<>(Comparator.reverseOrder())); 

MutableMap<String, TreeSet<String>> ecMap = 
     Maps.mutable.with("one", new TreeSet<>(Comparator.reverseOrder())); 
ecMap.getIfAbsentPutWith("two", TreeSet::new, Comparator.<String>reverseOrder()); 

Assert.assertEquals(jdkMap, ecMap); 

Ici, je compare en utilisant la méthode Map.computeIfAbsent() du JDK qui prend Function et est passé la clé en tant que paramètre, et Eclipse Collections __gVirt_NP_NN_NNPS<__ méthode MutableMap.getIfAbsentPutWith() qui prend aussi un Function et est passé à un paramètre supplémentaire . Dans l'exemple JDK, je dois utiliser un lambda. Dans l'exemple EC, je peux utiliser la référence constructeur TreeSet::new et spécifier Comparator.<String>reverseOrder() comme paramètre que je veux lui passer.

Il y a beaucoup de *With méthodes disponibles dans les collections Eclipse (par exemple selectWith, rejectWith, collectWith, detectWith, anySatisfyWith etc.). Ces méthodes augmentent le nombre total d'emplacements pouvant être utilisés avec des références de méthode dans Java 8.

Vous trouverez des exemples de références de méthode utilisées avec des paramètres dans les Katas de collections Eclipse.

Company Kata -> Exercise 2 Test
Pet Kata -> Exercise 2 Test

Note: Je suis un validateur pour Collections Eclipse.

1

Vous ne pouvez pas avoir de références de méthode avec des arguments en Java. Vous devez utiliser une expression lambda à la place:

Supplier<Map<String, String>> factory =() -> 
     new TreeMap<>(Comparator.reverseOrder()); 

Mais si, pour une raison quelconque, vous voulez/besoin d'utiliser de toute façon une référence de méthode, voici une façon de le faire avec une méthode d'assistance:

public static <T, U> Supplier<T> withArg(
     Function<? super U, ? extends T> methodRef, 
     U arg) { 
    return() -> methodRef.apply(arg); 
} 

Supplier<Map<String, String>> factory = withArg(
     TreeMap::new, 
     Comparator.<String>reverseOrder());