В Java 8: освоить новый уровень абстракции

В Java 8: освоить новый уровень абстракции

372
ПОДЕЛИТЬСЯ

Это ведь в конечном счете мы имеем дело с наиболее читаемый и лаконичный код, что, непременно, содействует сближению с логикой предметной области. Одна из почти всех обстоятельств , почему я люблю работать с многофункционального программирования является высочайший уровень абстракции.
В данной статье больший упор делается на 4 моментах введены в Java 8, которые посодействуют для вас выучить новейший уровень абстракции.

Проститься с циклами, и приветствуют поток по API. Дни java дискуссии о циклах частей. Нет больше циклов
Я говорил это ранее и скажу опять. 1. С Stream API в Java мы можем огласить , что мы желаем, заместо того, чтоб огласить , как этого можно достичь.
Давайте разглядим последующий пример.
Сейчас мы желаем получить 1-ые статьи, содержащие тег «Ява». У нас есть перечень статей, любая из которых имеет собственный перечень тегов.
Разглядим обычный подход. общественная статье getFirstJavaArticle() {

для (статьи статьи: статьи) {
раз (статья.getTags().содержит(«Ява»)) {
возврат артикула;
}
}

возвращать значение NULL;
}
Решим задачку, используя поток по API. общественная Факультативного<статья> getFirstJavaArticle() {
возвращение статей.поток()
.фильтр(статьи -> статьи.getTags().содержит(«Ява»))
.предназначенный findfirst();
}
Классно, правда?
Во-первых, мы используем фильтр, чтоб отыскать все статьи, содержащие тег java, то через предназначенный findfirst получить 1-ое включение.
Возникает вопросец: почему мы должны фильтровать весь перечень, раз нам необходимо лишь 1-ое время? и фильтр возвращает поток, Расчеты производятся до тех пор, пока не отыщите выключатель. Так как потоки ленивы…
У меня ранее была размещена статья о подмене циклов для потокового API-интерфейса. Прочитайте ее, раз для вас необходимо больше примеров.
2. Избавиться от проверки NULL
Вы сможете увидеть, что в прошлом примере, мы можем возвратиться Факультативного<статья>.

Необязательно это объект-контейнер, который может содержать либо не содержать ненулевое значение.
Этот объект имеет некие функции высшего порядка, избавляющий от прибавления дубликата , раз значение NULL/notNull проверок, что дозволяет нам сосредоточиться на том, что мы желаем сделать.
Сейчас давайте улучшим способ getFirstJavaArticle. Раз Вы не сможете отыскать Ява статья, мы будем рады получать свежайшие статьи.
Давайте разглядим, как смотрится обычное решение. Статья статья = getFirstJavaArticle();

раз (статья == значение NULL) {
статья = fetchLatestArticle();
}
getFirstJavaArticle()
.orElseGet(это::fetchLatestArticle); И на данный момент решение находится с внедрением Факультативного<Т>.
Смотрится здорово, не так ли?
Мы просто применять необязательно.orElseGetсказать, что мы желаем получить, раз не будет найдено значение. Никаких доп переменных, нет раз-структур, ни каких-или ссылок на нуль.
Давайте разглядим еще один пример использования необязательно. Представим, что мы желаем получить имя первого Ява статья, раз она найдена.
Необязательно тут, чтоб спасти день. знаешь что? Опять, используя типовое решение, мы должны добавить нуль-проверить, но… площадка.getFirstJavaArticle()
.карта(статьи::конкретно gettitle);
Как видите, необязательно реализует функции высшего порядка карте, помогая нам применить функцию к результату, раз он есть.
Доп сведения о необязательных обратитесь к документации.
Создавать свои собственные функции высшего порядка
Как видите, в Java 8 поставляется с готовым набором функций высшего порядка, и вы сможете делать чудеса. И почему бы не сделать свои собственные функции высшего порядка? 3. Но для чего останавливаться на достигнутом?
Единственное, что для вас необходимо сделать функцию высшего порядка, это взять один из многофункциональных интерфейсов в Java, либо Сэм интерфейс-типа как аргумент и / либо возврата 1-го из их.
Чтоб проиллюстрировать это, разглядим последующий сценарий.
Перед печатью принтер должен быть согрет, и опосля печати в спящий режим. У нас есть принтер, который может печатать разные виды документов.
публичного недействительными печати(потребительское<принтер> toPrint) {

принтер.приготовить();
toPrint.принимаем(принтер);
принтер.сон();
} Это может быть решена методом сотворения функций высшего порядка. Сейчас мы желаем иметь возможность посылать команды на принтер без хлопот о собственных процедур включения и выключения.
Как вы сможете созидать, мы используем потребителей<принтер>являясь одним из многофункциональных интерфейсов в качестве аргумента. Потом мы исполняем эту функцию как шаг меж процедурами пуска и завершения работы.
Сейчас мы можем просто применять наш принтер, не заботясь ни о чем другом, не считая того, что мы желаем напечатать. // Печати одна статья
printHandler.печати(п -> п.печати(oneArticle));

// Распечатать некие статьи
printHandler.печать(p -> allArticles.по каждому элементу(р::печать));
Для наиболее детализированного примера, прочитайте мою статью о том, как сделать TransactionHandler.
4. Остерегайтесь дублирования. Принцип Dry
Написание функций является скорым и легким. Тем не наименее, с обычным написанием кода приходит желание дублировать.
общественная Факультативного<статья> getFirstJavaArticle() {
возвращение статей.поток()
.фильтр(статьи -> статьи.getTags().содержит(«Ява»))
.предназначенный findfirst();
} Разглядим последующий пример.
Нам нужен метод, что можете отыскать статьи на базе остальных тегов и требования в целом. Этот способ был совсем излишний, но он не является всепригодным.
Они так малы и так просто можно сделать, как это может навредить? Чрезвычайно интригующе-сделать новейшие потоки. В отличие от их, маленькие части кода должны мотивировать принцип Dry дальше.
общественная Факультативного<статьи> способ getfirst(предикат<статья> предикат) {
возвращение статей.поток()
.фильтр(предикат)
.предназначенный findfirst();
} Давайте реорганизуем наш код. Во-первых, давайте сделаем нашу функцию getFirstJavaArticle наиболее всепригодным — оно воспримет предикат в качестве аргумента для фильтрации статей в согласовании с тем, что нам необходимо.
Сейчас давайте используем эту функцию, чтоб получить несколько различных статей. способ getfirst(статьи -> статьи.getTags().содержит(«Ява»));
способ getfirst(статьи -> статьи.getTags().содержит(«Гора»));
способ getfirst(статьи -> статьи.конкретно gettitle().содержит(«в clojure»));
Давайте попробуем снять эти дупликации через интерфейс функции. Сейчас код смотрится последующим образом. Функция<строчка, предикат<статья>> basedOnTag = тег -> статьи -> статья.getTags().содержит(тег);

способ getfirst(basedOnTag.применить(«Ява»));
способ getfirst(basedOnTag.применить(«Гора»)); И еще, мы все еще имеем дело с циклическим кодом. Вы сможете узреть, что применять тот же предикат для разных значений.
Я бы произнес, что этот код соответствует сухой принцип, не так ли? Непревзойденно!
Я надеюсь, что эта статья оказалась для вас полезной и отдала несколько идей о том, что вы могли бы сделать на наиболее высочайшем уровне абстракции с внедрением java 8 и многофункциональные индивидуальности. habrahabr.ru