Als Teil beliebiger Referenzmethoden:Java 8 Methodenreferenzen
Warum ist das erlaubt?
Predicate<String> p1 = String::isEmpty;
Und warum ist das nicht erlaubt?
BiConsumer<HashMap<String,Integer>, Integer> b1 = HashMap<String,Integer>::put;
Als Teil beliebiger Referenzmethoden:Java 8 Methodenreferenzen
Warum ist das erlaubt?
Predicate<String> p1 = String::isEmpty;
Und warum ist das nicht erlaubt?
BiConsumer<HashMap<String,Integer>, Integer> b1 = HashMap<String,Integer>::put;
In Ihrem ersten Beispiel, sie ist ein Predicate
zu schaffen, die als eine Eingabe einen String
nimmt. Dies entspricht String.isEmpty()
, die keine Argumente annimmt. Das Prädikat wirkt nur auf die String-Instanz.
Wie für das zweite Beispiel, lassen Sie uns die put
Methode untersuchen:
public V put(K key, V value)
Da Sie eine HashMap<String, Integer>
verwenden, diese
public Integer put(String key, Integer value)
würde Wie Sie sehen können, das Verfahren selbst ist erwartet zwei Argumente. Da Sie dies als eine Methodenreferenz übergeben möchten, benötigt es zusätzlich zu den zwei Argumenten die HashMap<String, Integer>
.
BiConsumer<HashMap<String, Integer>, Integer> b1 = HashMap<String, Integer>::put;
Hierher, haben Sie markiert korrekt das erste generische Typargument als HashMap<String, Integer>
, aber Sie fehlen das String
Argument, das die put
Methode benötigt. Leider gibt es keine TriConsumer
, aber Sie können Ihre eigene Schnittstelle für sie leicht definieren:
@FunctionalInterface
public interface TriConsumer<T, U, V> {
void accept(T t, U u, V v);
}
Die @FunctionalInterface
Anmerkung ist nicht erforderlich, aber es steht die Absicht, den Leser, dass diese Schnittstelle als Zuweisungsziel verwendet werden kann, für einen Lambda-Ausdruck oder eine Methodenreferenz.
Jetzt können Sie den Verweis auf put
zuweisen:
TriConsumer<HashMap<String, Integer>, String, Integer> consumer = HashMap<String, Integer>::put;
HashMap<String, Integer> map = new HashMap<>();
consumer.accept(map, "Key", 123);
System.out.println(map.get("Key")); // prints 123
Danke für die Erklärung so schön! –
@ VijayNarayanan Ich bin froh, dass ich helfen konnte! Schauen Sie sich auch die Antwort von Bohemian an, sein Beispiel zeigt, wie Sie eine Referenz auf eine Methode eines * bestimmten * Objekts zuweisen können. – cubrr
Das grundlegende Problem ist, dass put()
ist kein Methode getippt - eine, wo der Typ Methode Umfang hat und geschlossen werden kann, ist es eine generische Instanz Methode - eine, die ihren Typ vom Typ der Instanz nimmt.
Außerdem stimmen Sie nicht mit dem Typ der Methodenreferenz und ihren generischen Parametern überein. Ich habe angenommen, du meinst BiFunction
, nicht BiConsumer
.
die bei Let schauen, was tut Arbeit:
HashMap<String, Integer> instance = new HashMap<>();
BiFunction<String, Integer, Integer> b1 = instance::put;
Wenn Sie wirklich BiConsumer
gemeint, das funktioniert auch:
BiConsumer<String, Integer> b1 = instance::put;
Wie ich gesagt habe, weil die Methode von seiner Art nimmt die Instanz, also benötigen Sie eine typisierte Instanz.
Vielen Dank für Ihre Erklärung! –
Meinst du _now_ oder _not_? –
Verstanden, weil im obigen Fall die Argumente für Put nicht abgeleitet werden können.Dies funktioniert BiConsumer, Integer> b1 = HashSet :: add; –