2017-09-19 4 views
6

Ich versuche, Lambdas in Java zu verwenden, kann aber nicht verstehen, wie es überhaupt funktioniert. Ich habe @FunctionalInterface wie folgt aus:Lambdas in FunctionalInterfaces in Java

@FunctionalInterface 
public interface MyFunctionalInterface { 
    String getString(String s); 
} 

jetzt in meinem Code verwende ich die lambda wie hier:

MyFunctionalInterface function = (f) -> { 
    Date d = new Date(); 
    return d.toString() + " " + person.name + " used fnc str"; 
}; 

Als nächstes benutze ich meine function vorbei es in den Konstruktor einer anderen Klasse machen wollen und verwenden sie es wie folgt aus:

public SampleClass(MyFunctionalInterface function) { 
    String tmp = "The person info: %s"; 
    this.result = String.format(tmp, function.getString(String.valueOf(function))); 
} 

Warum ich es die hier valueOf() verwenden müssen? Ich dachte, dass ich dafür nur function.getString() verwenden könnte?

Ausgang: Tue Sep 19 11:04:48 CEST 2017 John used fnc str

+0

Ihre Funktion nimmt einen 'String' als Parameter. Wenn Sie Ihr String-Format lesen, sollten Sie die Person-Info als "String" an sie übergeben. Im Moment übergeben Sie die String-Repräsentation der Funktion selbst an die Funktion. – marstran

+0

Es ist nicht wirklich klar, was Sie erreichen wollen. Ich hätte erwartet, dass Lambda-Definition an der Stelle, wo Sie Funktion verwenden. Oder Sie verwenden eine Methodenreferenz. Ich denke, der Code, den Sie gerade haben, wird das OBJECT, das diese Funktion ebenfalls darstellt, umwandeln und eine String-Repräsentation davon erzeugen, die dann als Eingabe an die Funktion selbst übergeben wird. Macht einfach keinen Sinn. – GhostCat

+0

Was ist die Ausgabe dieses Codes? – jrook

Antwort

5

Ihre getString Methode erfordert eine String Argument, so dass Sie es nicht ohne Argument aufrufen können.

Das heißt, Ihr Lambda-Ausdruck ignoriert das String Argument und nimmt stattdessen Daten von einer Variablen (die Sie nicht angezeigt haben, wo Sie es deklarieren).

Vielleicht ist Ihre funktionale Schnittstelle sollte ein Person Argument statt:

@FunctionalInterface 
public interface MyFunctionalInterface { 
    String getString(Person p); 
} 

MyFunctionalInterface function = p -> { 
    Date d = new Date(); 
    return d.toString() + " " + p.name + " used fnc str"; 
}; 

public SampleClass(MyFunctionalInterface function, Person person) { 
    String tmp = "The person info: %s"; 
    this.result = String.format(tmp, function.getString(person)); 
} 

Alternativ können Sie das Argument von Ihrem funktionalen Schnittstelle Methode entfernen:

@FunctionalInterface 
public interface MyFunctionalInterface { 
    String getString(); 
} 

MyFunctionalInterface function =() -> { 
    Date d = new Date(); 
    return d.toString() + " " + person.name + " used fnc str"; 
}; 

public SampleClass(MyFunctionalInterface function) { 
    String tmp = "The person info: %s"; 
    this.result = String.format(tmp, function.getString()); 
} 
+0

Hmm, ich kann dort nicht ein bestimmtes Objekt übergeben, weil ich viele von ihnen mit dieser 'Inerface' formatieren möchte, nicht nur eine' Person' (zB 'car',' animal' usw.) – soommy12

+0

@ soommy12 In diesem Fall können Sie vielleicht die funktionale Schnittstelle generisch machen - 'interface MyFunctionalInterface '. Wenn Sie bestimmte Eigenschaften wie p.name verwenden möchten, müssen Sie natürlich einen Typ festlegen, der an T gebunden ist ('' wobei 'SomeType' eine Klasse mit einer Eigenschaft' name' ist). Andernfalls können Sie das Argument aus der Methode 'getString()' (und aus Ihrem Lambda-Ausdruck) entfernen und alles andere unverändert lassen. – Eran

+0

Ok, aber eine andere Frage ist, kann ich meine Schnittstelle dazu bringen, nichts aufzunehmen und 'String' dann zurückzugeben? Ich meine, ich möchte hier eine Art "abstrakte Methode" machen. Ich möchte etwas mit der 'String' machen und es zurückgeben. Kann ich das durch Lamdas erreichen? – soommy12