Dive into lambdas
Наконец-то добрались руки чтобы пощупать такие долгожданные лямбды, качнул свеженькую восьмерку и набросал некоторые варианты использования, которые могут быть полезны для увеличения связности кода. Сходу набросал три примера, сырцы в песочнице.Method reference vs BeanInfo
Старый способ - получать геттеры и сеттеры по строковому имени через Introspector. Все работает, до первого переименования поля в классе, пока мы не начинаем получать WTF в коде.
С новым способом мы можем рефакторинго-безопасно передавать ссылки на методы. Смотри код methodAccessorsDemo. Причем передавать можем двумя способами: в виде lambda и в виде closure. И если с первым спомобом все понятно: есть экземпляр объекта, и метод, который у него вызывается, то второй способ полнейший разрыв мозга: передача метода через Тип, а не экземпляр. Долго курил, пока не понял, что если в functionalInterfaceMethod(a,b) мы передаем concreteMethod(b) с одним параметром, то конпелятор развернет это в a.concreteMethod(b). Очень неочевидно, напоминает питоний Self, подробнее про это здесь.
Lazy evaluation
Ленивые вычисления. Один раз столкнулся, когда писал FluentBuilder: очень часто была проверка на истинность и выполнение тех или иных действий. В простейших случаях было нормально, но только до первой проверки на null: doIf(a != null, a.name(), b.name()). Очень красиво, но сходу ловишь NPE: перед вызовом метода все фактические параметры должны быть вычислены. Но если у нас есть лямбды то можно переписать, не теряя лаконичности: doIf(a != null, () -> a.name(), () -> b.name()). Когда писал, увидел, что в примере не возвращаются параметры, но это решается заменой Runnable на Callable.
AOP
Нормальный такой AOP без всяких аннотаций. Можно использовать для всех классических применений: логирование, транзакции, контракты, проверка прав доступа. В примере просто логирую значение до и после вызова метода.
API
Зачем все эти танцы с бубном вокруг лямбд для простого пользователя? Есть же стандартные вещи типа коллекций, событий, зачем городить свои огороды? У меня необратимые изменения в мозге появились, когда я зачем-то заглянул в код Guava. Вернее сначала увидел ImmutableIist.of(...), очень сильно удивился (ну ведь не дураки же писали, значит зачем-то нужно), полез в смотреть в сырцы и бездны ада взглянули на меня. Затем, мне очень понравился Joiner, то как он сохраняет контекст. Целиком впитав эту идею, я проникся и понял: чтобы в основном коде лаконично, читаемо, в одну строку выражать мысли типа Joiner.on(",").join(Arrays.asList(1, 5, 7)), где-то придется устроить Адъ и Израиль на пол тысячи строк. Последнее время очень активно ощупываю границы применимости, пока очень доволен. IntelliJIDEA уже давно сворачивает анонимные классы до лямбд и синтаксис уже совершенно привычен. Когда же до debian доедет восьмерка, можно будет совершенно легально их использовать.