2017-12-27 14 views
1

Bei dieser Methode:Argumente Methode Passing Referenzen

private static Integer getVal(Integer a, Integer b){ 
    return a + b; 
} 

, die als Lambda bezeichnet werden kann:

a -> getVal(1, 2) 

Gibt es trotzdem, dies in ein Verfahren Bezug Drehen, so etwas wie:

Class::getVal 

Dank

+4

Warum glauben Sie, diese brauchen? – shmosel

Antwort

2

Nun, wenn Sie Konstanten für den Methodenaufruf sind vorbei, können Sie eine andere Methode erstellen, die die ursprüngliche Methode aufruft:

private static Integer getVal (Integer a) { 
    return getVal(1,2); 
} 

dann können Sie Methode Referenz für die zweite Methode verwenden.

das heißt Sie können

a -> getVal(1, 2) 

zu

ClassName::getVal 

Das heißt ändern, ist es nicht viel Sinn macht.

P.S., es ist nicht klar, was der Zweck von a in Ihrem Lambda-Ausdruck ist, da Sie es ignorieren.

Im Allgemeinen können Sie eine Methodenreferenz einer bestimmten Methode übergeben, wenn sie mit der Signatur der einzelnen Methode der erforderlichen funktionalen Schnittstelle übereinstimmt.

Beispiel:

public static Integer apply (BinaryOperator<Integer> op, Integer a, Integer b) 
{ 
    return op.apply(a,b); 
} 

Jetzt können Sie anrufen:

apply(ClassName::getVal) 

mit Ihrer ursprünglichen Methode.

+0

Danke. Das ist wirklich die Frage - wie die Integer-Werte an das Lambda übergeben werden, wie: (val1, val2) -> getVal (val1, val2) – user1052610

+0

@ user1052610 Es hängt davon ab, wo Sie Ihre Methodenreferenz übergeben. Wenn Sie es an eine Methode übergeben, die eine funktionale Schnittstelle mit einer Methode mit 2 Argumenten benötigt, können Sie Ihre ursprüngliche Methode übergeben. – Eran

+0

Es wird an das zweite Argument von Map.computeIfAbsent() übergeben. Also was ich möchte, ist map.computeIfAbsent ("xxx", Klasse: getVal) – user1052610

2

Hier ist ein Beispiel.

interface Operator { 
    int operate(int a, int b); 
} 

class Calc { 
    public static int add(int a, int b) { 
     return a + b; 
    } 
} 

class Main {  
    public static void main(String[] args) { 
     // using method reference 
     int result = operate(1, 2, Calc::add); 
     // using lambda 
     int result = operate(1, 2, (a, b) -> Calc.add(a, b)); 
    } 

    static int operate(int a, int b, Operator operator) { 
     return operator.operate(a, b); 
    } 
} 

Sie benötigen ein funktionelles Interface-Methode Referenz zu verwenden (in diesem Beispiel Operator). Außerdem benötigen Sie eine Methode, die eine Instanz der funktionalen Schnittstelle als Parermater akzeptiert (in diesem Beispiel operate(int a, int b, Operator operator).

UPDATE

Wenn Sie ein Objekt-Wrapper müssen, sondern nur die operate Methode

static int operate(ObjectWrapper wrapper, Operator operator) { 
    return operator.operate(wrapper.getA(), wrapper.getB()); 
} 

ändern und dann die operate Methode aufrufen:

int result = operate(wrapper, Calc::add); 
1

getVal() wird nur als eine Methodenreferenz verwendbar sein, an Stellen, an denen eine funktionale Schnittstelle eines anwendbaren Typs i s erwartet, wie BiFunction oder IntBinaryOperator oder eine benutzerdefinierte Funktionsschnittstelle (wie im answer von zhh)

Beispiel:

public static void main(String[] args) { 
     Integer result1 = calculate(1, 2, Second::getVal); 
     Integer result2 = calculateAsInt(1, 2, Second::getVal); 
    } 

    private static Integer getVal(Integer a, Integer b){ 
     return a + b; 
    } 

    private static Integer calculate(Integer a, Integer b, BinaryOperator<Integer> operator) { 
     return operator.apply(a, b); 
    } 

    private static int calculateAsInt(int a, Integer b, IntBinaryOperator operator) { 
     return operator.applyAsInt(a, b); 
    }