Przeczytałem w książce (Fischer's Java Closures i Lambda, Apress 2015), że odniesienia do metody są lepsze od wyrażeń lambda. Z mojego punktu widzenia wyrażenie lambda jest łatwiejsze do zrozumienia dla programistów używających innych języków. Więc dlaczego mówi, że odniesienie do metody jest lepsze? Czy pisanie wyrażeń lambda jest złym zwyczajem w Java 8?Wyrażenie lambda lub odwołanie do metody?
Odpowiedz
W Lambda Best Practices sekcji Rozdział 2, książka Fischera mówi:
O ile to możliwe, należy używać Referencyjna metoda zamiast lambda. Odnośniki metod są nie tylko krótsze i łatwiejsze do odczytania, ale użycie odwołań metod pozwoli ci bezpośrednio myśleć o metodach jako wartościach. Jest to kod trzeba akcyzy ze swoim kodzie i mózg:
x -> it.do(x)
Jeśli naturalnie pisząc ten kod, to jeszcze nie wykonany skok do myślenia na wyższym poziomie funkcjonalnym programowanie. Gdy dokonasz takiego skoku, znacznie łatwiej będzie się komunikować i pracować ze złożonymi funkcjami, ponieważ będziesz myślał o typach, a nie wartościach.
Chociaż w większości zgadzam się z konkluzją, nie jestem pewien, czy kupuję linię rozumowania Fischera. Odnośniki do metod są często, choć nie zawsze, krótsze niż pisane lambda. W pierwszej części mówi, że referencje metod pomogą ci myśleć o metodach jako wartościach. OK, ale później mówi, że rzeczy staną się łatwiejsze, ponieważ będziesz myślał o typach, a nie wartościach. Nie jestem pewien co to znaczy.
Istnieje możliwość przerobienia przykład wyraz daje jako
it::do
to na pewno krócej niż oryginał, ale trudno jest uogólniać z maleńkim przykładzie.
Oto moje zdanie na temat metod referencji i zapisanych lambd.
Jeśli istnieje możliwość wyboru między wyrażeniem lambda a odwołaniem do metody, to jest to , często przypadek, w którym preferowane jest odniesienie do metody. Ale nie jest to reguła twarda i szybka, i prawdopodobnie istnieją okoliczności, w których preferowane jest wyrażenie lambda. To także kwestia gustu.
Jeśli znasz wyrażenia lambda z innych języków, wyrażenia lambda w Javie będą prawdopodobnie bardziej znane niż odwołania do metod. Uważam jednak, że jest to stan tymczasowy, dopóki nie poznasz referencji metod. Gdy są bardziej znane, zalety odniesień do metod mogą przeważyć początkową nieznajomość.
Rozważmy prosty przykład uzyskanie długości ciągi:
List<String> list = ... ;
int[] lengths1 = list.stream().mapToInt(s -> s.length()).toArray();
int[] lengths2 = list.stream().mapToInt(String::length).toArray();
w tym przypadku, wielkość wyrażenia lambda jest po prostu o tym samym jako wielkości odniesienia metody (w liczbie znaków). Ale zauważ, że odwołanie do metody zawiera więcej informacji o typie. Informuje czytelnika, że typ elementu to String
, co może być pomocne w zrozumieniu długiego rurociągu. Czasem jest to pomocne również dla kompilatora, jeśli nie można wywnioskować typu elementu, ponieważ czasami występuje w złożonych wyrażeniach.
Inną kwestią jest to, że użycie odnośnika do metody często zwalnia cię z odpowiedzialności za wymyślenie nazwy dla formalnego parametru, który jest po prostu przekazywany do innej metody. Nazewnictwo jest często ważne, ale formaty lambda to często "śmieciowe" nazwy, takie jak i
x
lub s
, jak w tym przykładzie.
Odwołanie do metody jest nieco bardziej wydajne, ponieważ nie musi generować statycznej metody, która musi zostać wywołana, aby uzyskać dostęp do metody String.length(). Ale ta wydajność rzadko jest ważnym czynnikiem.
rozważyć również ten przykład, celowo pozbawiona kontekstu:
(x, y) -> x + y
Czy to konkatenacji ciąg liczbowy lub dodatek? Jeśli numeryczne, jaki typ? Zgodnie z regułami języka, musi to być znane w czasie kompilacji, w przeciwnym razie jest to błąd. Chociaż może to być jasne dla kompilatora, czasami nie jest to zbyt jasne dla czytelnika. Zamiast tego należy rozważyć następujące odniesienia do metod:
String::concat
Integer::sum
Double::sum
Używanie nazwy operacji w tym przypadku bardzo wyraźnie informuje czytelnika o tym, co jest przeznaczone.
- 1. Wyrażenie Lambda
- 2. Wyrażenie Lambda w Powershell
- 3. Nieznane odwołanie do metody Java 8
- 4. Funkcja zwracająca wyrażenie lambda
- 5. Wyrażenie lambda jest nieużywany
- 6. Przełęcz lambda wyrażenie argumentem lambda C++ 11
- 7. Gdzie zaznaczam wyrażenie asynchroniczne lambda?
- 8. Wyrażenie Lambda na ostatnią datę
- 9. Lambda Wyrażenie dla wielu parametrów
- 10. Wyrażenie Lambda jako atrybut klasy?
- 11. Czy można wstawiać wyrażenie lambda?
- 12. Wyrażenie Lambda dla "nie w"?
- 13. Jak napisać wyrażenie VB.Net Lambda
- 14. Wyrażenie Lambda z wejściem void
- 15. Składnia odnosząca się do metody zwracającej wyrażenie do innej metody?
- 16. jest funkcja lambda, która nie może być odwołaniem do metody
- 17. MethodInvoke delegate lub lambda expression
- 18. Czy istnieje odwołanie do metody do wyrzucania wyjątku?
- 19. przekonwertuj to wyrażenie LINQ na Lambda
- 20. F # wyrażenie lambda z wieloma stwierdzeniami
- 21. Jak przekazać wyrażenie lambda do konstruktora C# ze skryptu IronPython?
- 22. jak „nie” wyrażenie lambda dla Entity Framework
- 23. Wykonaj wyrażenie lambda natychmiast po jego definicji?
- 24. Wyrejestrowanie wyrażenie lambda z imprezy C#
- 25. Zmienne lokalne, do których odwołuje się wyrażenie lambda, muszą być ostateczne lub efektywne.
- 26. Dlaczego zmiany prototypów nie są przekazywane przez odwołanie do metody?
- 27. jak korzystać z metody ajax GET lub POST do przeszłych danych do amazon lambda node.js funkcja
- 28. Odwołanie do metody konstruktora dla (niestatycznej) klasy wewnętrznej?
- 29. Wiele wątków przekazujących odwołanie do metody statycznego pomocnika
- 30. # błędu C: „Odwołanie do obiektu jest wymagane dla pola non-static, metody lub właściwości”
Nie jest to "zła praktyka" oznacza po prostu, że nie nadaje się do wielokrotnego użytku i nie może samo się odwoływać (rekurencyjnie). – alfasin
Downvoter - prosimy o komentarz! – alfasin
Która książka to jest? Czy autor jest Robertem Fischerem? –