2017-07-02 3 views
4

Ist es möglich, Parameter mit Methodenreferenz zu übergeben? Zum Beispiel muss ich eine TreeMap aber unter Verwendungerstellen. Gibt es so etwas wie TreeMap::new(reverseOrder())?Parameter in Methodenreferenz

+2

Eine Methodenreferenz ist eine Referenz zu einer vorhandenen Methode. Wenn es keine Methode gibt, die genau das tut, was Sie wollen, schreiben Sie entweder eine solche Methode (und erfassen Sie dann einen Verweis darauf) oder verwenden Sie ein Lambda, dessen Körper das tut, was Sie wollen. –

+0

Auch [Externes Argument zur Methodenreferenz in Java 8] (https://stackoverflow.com/questions/38697939/external-argument-to-method-reference-in-java-8) und wahrscheinlich [viel mehr] (https : //stackoverflow.com/search?q = Parameter +% 22Methode + Referenz% 22) –

Antwort

6

Nein, es mit einem Verfahren Verweise nicht tun können.

Sie können stattdessen Lambda-Ausdrücke verwenden:

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

oder

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

, wenn Sie diesen Ausdruck in einem Kontext verwenden, wo der Compiler den Elementtyp des TreeMap ableiten kann.

+2

Rohe Typen, wirklich? – ZhekaKozlov

+0

@ZhekaKozlov Guter Punkt, aber ohne den Kontext zu kennen, wusste ich nicht, welchen Elementtyp zu verwenden. – Eran

+0

@Eran gibt es keinen Kontext, es war eine generische Situation –

5

Sie benötigen einen Lambda-Ausdruck für die ... Sie wahrscheinlich über ein Supplier denken:

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

Danke, ich stellte mir vor, dass es nicht möglich ist –

1

Dies wird von Methodenreferenzen selbst (heute) nicht unterstützt, aber es gibt viele Fälle, in denen Methodenreferenzen mit Parametern unter Verwendung der APIs Eclipse Collections verwendet werden können. Nehmen Sie das folgende Beispiel:

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); 

Hier vergleiche ich die Map.computeIfAbsent() Methode des JDK, die eine Function nimmt und den Schlüssel als Parameter übergeben, und Eclipse Collections' MutableMap.getIfAbsentPutWith() Methode, die auch eine Function nimmt und einen zusätzlichen Parameter übergeben . Im JDK-Beispiel muss ich ein Lambda verwenden. Im EG-Beispiel kann ich den Konstruktorreferenz TreeSet::new verwenden und Comparator.<String>reverseOrder() als den Parameter angeben, der an es übergeben werden soll.

Es gibt viele Methoden zur Verfügung *With in Eclipse Sammlungen (z selectWith, rejectWith, collectWith, detectWith, anySatisfyWith etc.). Diese Methoden erhöhen die Gesamtzahl der Stellen, die mit Methodenreferenzen in Java 8 verwendet werden können.

Sie finden Beispiele für Methodenreferenzen, die mit Parametern in den Katas der Eclipse-Sammlungen verwendet werden.

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

Hinweis: Ich bin ein Committer für Eclipse Kollektionen.

1

Sie können in Java keine Methodenreferenzen mit Argumenten haben. Sie müssen einen Lambda-Ausdruck verwenden statt:

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

Aber wenn aus irgendeinem Grund, Sie wollen/müssen sowieso eine Methode Referenz verwenden, hier ist ein Weg, um es mit einem Helfer-Methode zu tun:

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()); 
Verwandte Themen