Ламбда-вирази не змінюють набір проблем, які можна вирішити за допомогою Java взагалі, але, безумовно, полегшують вирішення певних проблем, просто з тієї ж причини, що ми більше не програмуємо на мові складання. Видалення зайвих завдань з роботи програміста полегшує життя і дозволяє робити речі, які ви навіть не торкалися б інакше, лише за кількість коду, який ви повинні створити (вручну).
Але лямбда-вирази - це не просто збереження рядків коду. Ламбда-вирази дозволяють визначати функції , для чого ви могли раніше використовувати анонімні внутрішні класи як вирішення, тому ви можете замінити анонімні внутрішні класи в цих випадках, але не в цілому.
Найбільш помітно, що лямбда-вирази визначаються незалежно від функціонального інтерфейсу, до якого вони будуть перетворені, тому немає спадкових членів, до яких вони могли б отримати доступ, крім того, вони не можуть отримати доступ до екземпляра типу, що реалізує функціональний інтерфейс. У лямбдаському виразі this
та super
мають те саме значення, що й у навколишньому контексті, дивіться також цю відповідь . Крім того, ви не можете створити нові локальні змінні, що відтіняють локальні змінні оточуючого контексту. Для заданого завдання визначення функції це видаляє багато джерел помилок, але це також означає, що для інших випадків використання можуть існувати анонімні внутрішні класи, які не можуть бути перетворені на лямбда-вираз, навіть якщо реалізувати функціональний інтерфейс.
Крім того, конструкція new Type() { … }
гарантує створення нового чіткого екземпляра (як new
завжди). Анонімні екземпляри внутрішнього класу завжди зберігають посилання на їх зовнішній екземпляр, якщо вони створені в неконтексті static
. Навпаки, лямбда-вирази містять посилання лише на this
необхідність, тобто якщо вони мають доступ this
або не є static
членом. І вони створюють екземпляри навмисно невизначеної ідентичності, що дозволяє впровадженню вирішити під час виконання, чи використовувати повторно існуючі екземпляри (див. Також " Чи створює лямбда-вираз об'єкт на купі кожного разу, коли він виконується? ").
Ці відмінності стосуються вашого прикладу. Ваша анонімна конструкція внутрішнього класу завжди створюватиме новий екземпляр, також вона може захоплювати посилання на зовнішній екземпляр, тоді як ваш (Developer o1, Developer o2) -> o1.getName().compareTo(o2.getName())
- вираз лямбда, що не захоплює, який буде оцінюватися на синглтон в типових реалізаціях. Крім того, він не створює .class
файл на вашому жорсткому диску.
Зважаючи на відмінності як щодо семантичного, так і продуктивного характеру, лямбда-вирази можуть змінити спосіб програмістів вирішувати певні проблеми в майбутньому, звичайно, також завдяки новим API, що використовують ідеї функціонального програмування з використанням нових мовних особливостей. Дивіться також вираз лямбда-вираз і значення першого класу Java 8 .
(o1, o2) -> o1.getName().compareTo(o2.getName())