Я прочитал в книге (Fischer's Java Closures and Lambda, Apress 2015), что ссылки на методы предпочтительнее лямбда-выражений. С моей точки зрения, выражение лямбда легче понять разработчикам, которые используют другие языки. Тогда почему он говорит, что ссылка на метод предпочтительнее? Является ли сочинение лямбда-выражения плохой практикой в Java 8?Лямбда-выражение или ссылка на метод?
ответ
В разделе Lambda Best Practices главы 2, книга Фишера говорит:
Насколько возможно, используйте ссылку на метод вместо лямбда. Ссылки на методы не только более короткие и удобные для чтения, но использование ссылок на методы поможет вам непосредственно думать о методах как значениях. Это код, который нужен акцизы от вашего кодовую и ваш мозг:
x -> it.do(x)
Если вы естественно писать этот код, то вы до сих пор не сделали прыжок, чтобы думать на более высоком уровне функциональных программирование. Как только вы совершите этот скачок, станет намного проще общаться и работать со сложными функциями, потому что вы будете думать о типах, а не о значениях.
Хотя я в основном согласен с заключением, я не уверен, что я куплю линию рассуждений Фишера. Ссылки на методы часто, хотя и не всегда, короче, чем выписанная лямбда. В первой части он говорит, что ссылки на методы помогут вам подумать о методах как значениях. Хорошо, но потом он говорит, что все станет проще, потому что вы будете думать о типах, а не о значениях. Я не уверен, что это значит.
Это можно переписать пример выражение он дает, как
it::do
Это, конечно, меньше, чем оригинал, но это трудно обобщать из крошечного примера.
Вот мой подход к методам против списанных лямбда.
Если есть выбор между использованием выражения лямбда и ссылкой на метод, то часто случай, когда предпочтительна ссылка метода. Но это не правило жесткое и быстрое, и, вероятно, будут ситуации, когда предпочтительным является лямбда-выражение. Это тоже вопрос вкуса.
Если вы знакомы с лямбда-выражениями с других языков, то лямбда-выражения в Java, вероятно, будут более знакомы, чем ссылки на методы. Тем не менее, я считаю, что это временное состояние, пока вы не изучите ссылки на методы. Как только они станут более знакомы, преимущества ссылок на методы могут перевесить первоначальную незнакомость.
Рассмотрим этот простой пример получения длины строк:
List<String> list = ... ;
int[] lengths1 = list.stream().mapToInt(s -> s.length()).toArray();
int[] lengths2 = list.stream().mapToInt(String::length).toArray();
В этом случае размер лямбда-выражения является лишь примерно такой же, как размер стандартного метода (в количестве символов). Но обратите внимание, что ссылка на метод содержит больше информации о типе. Он сообщает читателю, что тип элемента - String
, что может помочь в понимании длинного конвейера. Иногда это также полезно для компилятора, если он не может вывести тип элемента, что иногда встречается в сложных выражениях.
Еще один момент заключается в том, что использование ссылки на метод часто освобождает вас от ответственности за появление имени для формального параметра, который просто передается другому методу. Именование часто важно, но форматы лямбда часто являются «мусорными» именами, такими как i
x
или s
, как в этом примере.
Ссылка на метод немного более эффективна, так как не требуется генерировать статический метод, который должен быть вызван, чтобы перейти к методу String.length(). Но эта эффективность редко является важным соображением.
Рассмотрим также этот пример, намеренно лишен контекста:
(x, y) -> x + y
Является ли это конкатенация или числовое сложение? Если числовое, какой тип? По правилам языка это должно быть известно во время компиляции, иначе это ошибка. Хотя это может быть понятно компилятору, иногда это не очень понятно читателю. Рассмотрим вместо этих ссылок метод:
String::concat
Integer::sum
Double::sum
Используя имя для работы в этом случае делает его очень четко читателю о том, что имеется в виду.
- 1. undefined ссылка на метод
- 2. Ссылка на нестатический метод?
- 3. Ссылка на метод класса
- 4. Ссылка на метод в java
- 5. Ссылка на ссылку или возврат
- 6. Метод Java 8 Ссылка на нестатический метод
- 7. Неопределенная ссылка на метод класса
- 8. C++ неопределенная ссылка на метод
- 9. Статическая ссылка на нестатической метод
- 10. Неопределенная ссылка на статический метод
- 11. Ссылка на метод службы WCF
- 12. Scaladoc ссылка на другой метод
- 13. Ссылка на метод с аргументом
- 14. Ссылка на метод в пакете
- 15. Неопределенная ссылка на существующий метод
- 16. Ссылка на метод цепочки карт
- 17. Неопределенная ссылка на статический метод
- 18. статическая ссылка на нестатической метод
- 19. Недопустимая ссылка на метод/неоднозначная ссылка (разность поведения javac/ecj)
- 20. Ссылка на метод Java 8 на статический метод void
- 21. Ссылка на метод класса в python docstring
- 22. Почему ссылка на метод не отслеживает это?
- 23. Javadoc ссылка на метод в другом классе
- 24. Ссылка на членство или членство
- 25. Ссылка на метод локального конструктора классов
- 26. Неопределенная ссылка на метод шаблона в C++
- 27. Ссылка на два или более SenTestCase
- 28. Ссылка на метод json, "undefined method` stringify_keys "
- 29. Ссылка на объекты Агрегатный метод замены
- 30. Ссылка на метод внутри метода в java?
Это не «плохая практика», это просто означает, что он не может многократно использоваться и не может самоопределяться (рекурсия). – alfasin
Downvoter - прокомментируйте! – alfasin
Какая книга? Автор Роберт Фишер? –