W Javie 8 metody mogą być tworzone jako wyrażenia Lambda i mogą być przekazywane przez referencję (z niewielką pracą pod maską). Istnieje wiele przykładów online z lambdami tworzonymi i używanymi z metodami, ale nie ma przykładów, jak zrobić metodę przyjmującą lambda jako parametr. Jaka jest na to składnia?
MyClass.method((a, b) -> a+b);
class MyClass{
//How do I define this method?
static int method(Lambda l){
return l(5, 10);
}
}
Odpowiedzi:
Lambda są konstrukcją czysto wywoławczą: odbiorca lambda nie musi wiedzieć, że jest zaangażowana Lambda, zamiast tego przyjmuje interfejs z odpowiednią metodą.
Innymi słowy, definiujesz lub używasz funkcjonalnego interfejsu (tj. Interfejsu z jedną metodą), który akceptuje i zwraca dokładnie to, co chcesz.
Do tego Java 8 dołączony jest zestaw najczęściej używanych typów interfejsów
java.util.function
(dzięki Maurice Naftalin za podpowiedź na temat JavaDoc).W tym przypadku konkretnego zastosowania tam
java.util.function.IntBinaryOperator
z jednymint applyAsInt(int left, int right)
sposobem , więc można napisać swojemethod
tak:Ale równie dobrze możesz zdefiniować własny interfejs i używać go w następujący sposób:
Korzystanie z własnego interfejsu ma tę zaletę, że możesz mieć nazwy, które wyraźniej wskazują zamiar.
źródło
(int a, int b, int c)
doTwoArgIntOperator
. Co się stanie, jeśliTwoArgIntOperator
ma dwie metody z tym samym podpisem. Ta odpowiedź jest myląca.Aby użyć wyrażenia Lambda, musisz utworzyć własny interfejs funkcjonalny lub użyć interfejsu funkcjonalnego Java do operacji, które wymagają dwóch liczb całkowitych i zwracają jako wartość. IntBinaryOperator
Korzystanie z interfejsu funkcjonalnego zdefiniowanego przez użytkownika
Korzystanie z funkcjonalnego interfejsu Java
Inny przykład, który stworzyłem, jest tutaj
źródło
IntBinaryOperator
dokumentacji jest martwy.W przypadku funkcji, które nie mają więcej niż 2 parametry, możesz przekazać je bez definiowania własnego interfejsu. Na przykład,
W
BiFunction<Integer, String, List<String>>
,Integer
iString
są jego parametry iList<String>
jest jego typ zwracany.W przypadku funkcji z tylko jednym parametrem można użyć
Function<T, R>
, gdzieT
jest typem parametru iR
typem wartości zwracanej. Sprawdź na tej stronie wszystkie interfejsy, które zostały już udostępnione przez Javę.źródło
Dostępna jest publicznie dostępna w sieci wersja JavaDocs Java 8 z obsługą Lambda, do której link znajduje się na stronie http://lambdafaq.org/lambda-resources . (To oczywiście powinien być komentarz do odpowiedzi Joachima Sauera, ale nie mogę dostać się na swoje konto SO z punktami reputacji, które muszę dodać komentarz.) Witryna lambdafaq (utrzymuję ją) odpowiada na to i wiele innych Java -lambda pytania.
Uwaga: Ta odpowiedź została napisana, zanim dokumentacja Java 8 GA stała się publicznie dostępna . Zostawiłem jednak na miejscu, ponieważ często zadawane pytania dotyczące Lambda mogą być przydatne dla osób uczących się o funkcjach wprowadzonych w Javie 8.
źródło
Dla mnie najbardziej sensownym rozwiązaniem jest zdefiniowanie
Callback
interfejsu:a następnie użyć go jako parametru w funkcji, którą chcesz wywołać:
Ale tylko precyzja
Lambda nie jest specjalnym interfejsem, klasą ani niczym innym, co mógłbyś sam zadeklarować.
Lambda
to tylko nazwa nadana() -> {}
specjalnej składni, która umożliwia lepszą czytelność przy przekazywaniu interfejsów jednoprocesowych jako parametru. Został zaprojektowany, aby zastąpić to:W powyższym przykładzie nie
Callback
jest to lambda, to zwykły interfejs; to nazwa składni skrótu, której można użyć do jej wdrożenia.lambda
źródło
Dla każdego, kto googluje, dobrą metodą byłoby użycie
java.util.function.BiConsumer
. dawny:Nakład wyniósłby: 166
źródło
Consumer<Pair<A,B>>
użyjBiConsumer<A,B>
w tym przypadku. ( docs )Wyrażenie lambda można przekazać jako argument. Aby przekazać wyrażenie lambda jako argument, typ parametru (który odbiera wyrażenie lambda jako argument) musi mieć funkcjonalny typ interfejsu.
Jeśli istnieje funkcjonalny interfejs -
Istnieje metoda filtrowania, która dodaje liczbę int na liście tylko wtedy, gdy jest ona większa niż 5. Zauważ, że metoda filtrowania ma funkcjonalny interfejs IMyFunc jako jeden z parametrów. W takim przypadku wyrażenie lambda można przekazać jako argument parametru parametru.
źródło
Można używać interfejsów funkcjonalnych, jak wspomniano powyżej. poniżej znajdują się niektóre przykłady
Mam nadzieję, że to pomoże
źródło
Cóż, to łatwe. Celem wyrażenia lambda jest implementacja interfejsu funkcjonalnego. Jest to interfejs z tylko jedną metodą. Oto niesamowity artykuł na temat predefiniowanych i starszych interfejsów funkcjonalnych.
W każdym razie, jeśli chcesz wdrożyć własny interfejs funkcjonalny, zrób to. Dla prostego przykładu:
Stwórzmy więc klasę, w której stworzymy metodę, która akceptuje typ MyFunctionalInterface :
Ostatnią rzeczą, którą powinieneś zrobić, to przekazać implementację MyFunctionalInterface do zdefiniowanej przez nas metody:
Otóż to!
źródło
Lambda to nie obiekt, ale interfejs funkcjonalny. Można zdefiniować tak wiele interfejsów funkcjonalnych, jak to możliwe, używając @FuntionalInterface jako adnotacji
Dane wyjściowe będą następujące
Podstawową koncepcją wyrażenia lambda jest zdefiniowanie własnej logiki, ale już zdefiniowanych argumentów. Tak więc w powyższym kodzie możesz zmienić definicję funkcji do z dodania do dowolnej innej definicji, ale twoje argumenty są ograniczone do 2.
źródło
Zasadniczo, aby przekazać wyrażenie lamda jako parametr, potrzebujemy typu, w którym możemy go utrzymać. Podobnie jak wartość całkowita, którą przechowujemy w prymitywnej klasie int lub Integer. Java nie ma osobnego typu dla wyrażenia lamda, zamiast tego używa interfejsu jako typu do przechowywania argumentu. Ale ten interfejs powinien być interfejsem funkcjonalnym .
źródło
Wykonaj następujące czynności ...
Zadeklarowałeś
method(lambda l)
Wszystko, co chcesz zrobić, to utworzyć Interfejs z nazwąlambda
i zadeklarować jedną metodę abstrakcyjnąnazwa metody nie ma tutaj znaczenia.
Więc kiedy u zadzwoń
MyClass.method( (a,b)->a+b)
Ta implementacja(a,b)->a+b
będzie wstrzykiwany do metody interfejsu doda .so kiedy nazywaszl.add
go zajmie to wdrożenie i wykonywać dodawaniea
ib
ireturn l.add(2,3)
powróci5
. - Zasadniczo to robi lambda ..źródło
Oto w przybliżeniu sposób, w jaki C # radzi sobie z tym problemem (ale wyrażony jako kod Java). Coś takiego może zaspokoić prawie wszystkie Twoje potrzeby:
źródło
Istnieje elastyczność w stosowaniu lambda jako parametru. Umożliwia programowanie funkcjonalne w Javie. Podstawowa składnia to
Oto sposób, w jaki możesz zdefiniować metodę przyjmującą interfejs funkcjonalny (używana jest lambda) jako parametr. za. jeśli chcesz zdefiniować metodę zadeklarowaną w interfejsie funkcjonalnym, powiedzmy interfejs funkcjonalny jest podawany jako argument / parametr dla metody wywoływanej z
main()
Powyżej wyjaśnia szczególne użycie wyrażenia lambda, jest ich więcej. ref Java 8 lambda w lambda nie może modyfikować zmiennej z lambda zewnętrznej
źródło