2017-09-19 30 views
6

Próbuję użyć lambdas w Java, ale nie mogę zrozumieć, jak to działa. Stworzyłem @FunctionalInterface takiego:Lambdas w FunctionalInterfaces w Javie

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

teraz w moim kodu używam lambda jak tutaj:

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

Następnie chcę, aby korzystanie z moim function przekazaniem go do konstruktora z innej klasy i używać go tak:

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

Dlaczego muszę go valueOf() tu użyć? Pomyślałem, że dzięki za to mogę użyć tylko function.getString()?

wyjściowa: Tue Sep 19 11:04:48 CEST 2017 John used fnc str

+0

Twoja funkcja przyjmuje 'String' jako parametr. Odczytując format ciągu, należy przekazać mu informacje o osobie jako "String". W tej chwili przekazujesz funkcję string samej funkcji do tej funkcji. – marstran

+0

Nie jest jasne, co próbujesz osiągnąć. Spodziewałbym się tej definicji lambda w miejscu, w którym używasz funkcji. Lub, że używasz odwołania do metody. Myślę, że kod, który masz teraz, obróci OBIEKT, którego funkcja również reprezentuje i utworzy ciąg znaków, który jest następnie przekazywany jako wejście do samej funkcji. Po prostu nie ma sensu. – GhostCat

+0

Jaki jest wynik tego kodu? – jrook

Odpowiedz

5

Twoja metoda getString wymaga String argumentu, więc nie można nazwać bez żadnego argumentu.

To powiedziawszy, twoje wyrażenie lambda ignoruje ten argument String i zamiast tego pobiera dane z pewnej zmiennej person (której nie pokazywałeś, gdzie ją zadeklarujesz).

Być może twój interfejs funkcjonalny powinien wziąć Person argumentu zamiast:

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

Alternatywnie, można usunąć argument z metodą Twojego funkcjonalny interfejs użytkownika:

@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, nie mogę przekazać tam konkretnego obiektu, ponieważ chciałbym sformatować wiele z nich za pomocą 'Inerface', a nie tylko' osoba' (np. 'Car',' animal' itd.) – soommy12

+0

@ Soommy12 W tym przypadku, być może możesz uczynić interfejs funkcjonalny generycznym - 'interface MyFunctionalInterface '. Oczywiście, jeśli zamierzasz używać specyficznych właściwości, takich jak p.nazwa, będziesz musiał umieścić jakiś typ związany na T ('', gdzie 'SomeType' jest klasą, która ma własność' name'). W przeciwnym razie możesz usunąć argument z metody 'getString()' (i z wyrażenia lambda) i zachować wszystko inne, jak jest. – Eran

+0

OK, ale inne pytanie brzmi: czy mogę spowodować, że mój interfejs nic nie przyjmuje i zwraca "String"? Chodzi mi o to, że chciałbym tutaj zrobić jakąś "abstrakcyjną metodę". Chcę robić rzeczy za pomocą 'String' i zwrócić je. Czy mogę to osiągnąć za pomocą lamdas? – soommy12