IntelliJ ciągle proponuje mi zastąpienie wyrażeń lambda odwołaniami do metod.
Czy jest między nimi jakaś obiektywna różnica?
java
intellij-idea
java-8
Gerard
źródło
źródło
Type[]::new
). Klasa anonimowa wygenerowana w czasie wykonywania będzie taka sama. Środowisko JRE nie robi między nimi żadnej różnicy. Zatem użycie odwołania do metody pozwoli Ci zaoszczędzić jedną metodę w skompilowanym kodzie, z drugiej strony nie możesz się na nich zatrzymać podczas debugowania krok po kroku…Odpowiedzi:
Pozwólcie, że przedstawię pewne spojrzenie na to, dlaczego dodaliśmy tę funkcję do języka, skoro wyraźnie nie było to konieczne (wszystkie referencje metod można wyrazić jako lambdy).
Zauważ, że nie ma dobrej odpowiedzi . Każdy, kto mówi „zawsze używaj ref metody zamiast lambda” lub „zawsze używaj lambda zamiast odniesienia do metody” powinien zostać zignorowany.
To pytanie jest bardzo podobne w duchu do „kiedy powinienem używać nazwanej klasy, a kiedy anonimowej”? Odpowiedź jest taka sama: kiedy uznasz, że jest bardziej czytelny . Z pewnością są przypadki, które są zdecydowanie jednym lub zdecydowanie drugim, ale w środku jest mnóstwo szarości i należy zastosować ocenę.
Teoria stojąca za referencjami metod jest prosta: nazwy mają znaczenie . Jeśli metoda ma nazwę, to odwoływanie się do niej po nazwie, a nie za pomocą imperatywnego zbioru kodu, który ostatecznie po prostu obraca się i wywołuje ją, jest często (ale nie zawsze!) Bardziej przejrzyste i czytelne.
Spory o wydajność lub liczenie postaci to głównie czerwone śledzie i należy je zignorować. Celem jest napisanie kodu, który będzie krystalicznie jasny, co robi. Bardzo często (ale nie zawsze!) Referencje metod wygrywają w tym wskaźniku, więc włączyliśmy je jako opcję do wykorzystania w takich przypadkach.
Kluczową kwestią dotyczącą tego, czy odwołania do metod wyjaśniają, czy zaciemniają intencję, jest to, czy z kontekstu jasno wynika, jaki jest kształt reprezentowanej funkcji. W niektórych przypadkach (np.
map(Person::getLastName)
Z kontekstu jasno wynika, że wymagana jest funkcja, która odwzorowuje jedną rzecz na drugą, aw takich przypadkach lśnią odniesienia do metod. W innych użycie ref do metody wymaga od czytelnika zastanowienia się, jakiego rodzaju funkcji; jest to znak ostrzegawczy, że lambda może być bardziej czytelna, nawet jeśli jest dłuższa.Wreszcie, odkryliśmy, że większość ludzi na początku unika odwołań do metod, ponieważ czują się jeszcze nowsze i dziwniejsze niż lambdy, więc początkowo uważają je za „mniej czytelne”, ale z czasem, gdy przyzwyczają się do składni, ogólnie zmieniają swoje zachowanie i skłaniają się ku odniesieniom do metod, kiedy tylko mogą. Bądź więc świadomy, że Twoja subiektywna, początkowa, „mniej czytelna” reakcja prawie na pewno pociąga za sobą jakiś aspekt stronniczości rodzinnej i powinieneś dać sobie szansę oswoić się z oboma przed wyrażeniem opinii stylistycznej.
źródło
LiveData
wewnątrz aFragment
, który przekonwertowałem na programEvent
uruchamiany przez aViewModel
... i inne zachowanie ma miejsce, gdy Android wraca do tego samegoFragment
... . więc trudno mi to uprościć do pytaniaDługie wyrażenia lambda składające się z kilku instrukcji mogą zmniejszyć czytelność kodu. W takim przypadku wyodrębnienie tych instrukcji w metodzie i odwołanie się do niej może być lepszym wyborem.
Innym powodem może być możliwość ponownego użycia . Zamiast kopiować i wklejać wyrażenie lambda składające się z kilku instrukcji, możesz skonstruować metodę i wywołać ją z różnych miejsc kodu.
źródło
houses.map(House::getName)
ihouses.map(h -> h.getName())
. Lambda zajmuje dwa mniej znaków. Prawdą jest, że typ nie jest jawny, ale każde IDE powiedziałoby ci, a poza tym lambdy powinny być używane, gdy typ jest oczywisty. Mogę się z tobą zgodzić co do możliwości ponownego użycia, ale lambdy są dokładnie małe, więc można je łączyć, zamiast tworzyć duże, specyficzne metody. W tym sensie małe metody są bardziej wielokrotnego użytku niż niektóre duże i złożone metody, a ze względu na przejrzystość lambd (i do pewnego stopnia szczegółowość) są nadal łatwe do odczytania.House
jest to bardzo łagodny przykład; co zThreeStoryRedBrickHouseWithBlueDoors
. Preferuję odwołania do metod dla wyrażeń lambda z wieloma argumentami, a czasem podkreślam, że lambda dotyczy tylko jednego wywołania metody. Jest mniej błędów w odwołaniu do metody: możesz źle napisać argument w miejscu użycia, przypadkowo odwołać się do zmiennej z zakresu zewnętrznego itp.