Нове в java 8

Про все по порядку.

Default методи в інтерфейсах.

У інтерфейсах тепер можна визначати статичні методи. Справа в тому, що до Java 8 для якогось інтерфейсу, скажімо, Employee, існує клас Employees, що містить статичні методи для генерації об'єктів Employee і роботи з ними. Зручність нововведення в тому, що ці самі методи будуть знаходитися в самому інтерфейсі, а про клас Employees розробнику можна буде забути.

Як приклад подивимося на метод naturalOrder, який був доданий в java.util.Comparator

У інтерфейсах можна буде оголошувати default методи. Погляньмо на forEach в java.lang.Iterable: Default метод - це метод в інтерфейсі з реалізованої логікою, який не потрібно обов'язково визначати в реалізації цього інтерфейсу.

У попередніх версіях JDK додавати методи в інтерфейси стандартних бібліотек не представлялося можливим, це зруйнувало б весь призначений для користувача код, адже для кожної реалізації інтерфейсу довелося б дописувати реалізацію відсутнього нового методу. В Java 8 стандартні інтерфейси розширені великою кількістю default методів.

Тут варто відзначити, чому інтерфейси не реалізують default hashCode, equals і toString. Справа в тому, що об'єкти, що реалізують інтерфейс, є спадкоємцями Object, в якому вже визначені ці методи за замовчуванням. Чи стане незрозумілим, який з default методів викликати - той, що визначений в інтерфейсі, або той, що в батьківському класі.

Функціональні інтерфейси.

Функціональний інтерфейс - це той інтерфейс, який визначає тільки один абстрактний метод, як, наприклад, java.lang.Runnable:

Щоб точно визначити інтерфейс як функціональний, добавлена ​​анотація @FunctionalInterface, що працює за принципом @Override. Вона позначить задум і не дасть визначити другий абстрактний метод в інтерфейсі.

Зауважимо, інтерфейс може включати скільки завгодно default методів і при цьому залишатися функціональним, тому що default методи - не абстрактні.

Лямбда-вирази

Саме значуще нововведення в Java 8 - це лямбда-вирази. Якщо сказати взагалі, то під ними розуміються анонімні методи, які при цьому ще вдають із себе об'єкт, який можна привласнювати змінної і передавати як аргумент в інші методи. приклад:

Тут завдяки такому лямбда-виразу ми значно скорочуємо код. Як би це виглядало без лямбда: У новій версії також введений особливий синтаксис посилань на методи, що по суті - скорочена форма деяких лямбда-виразів:

String :: valueOf x -> String.valueOf (x)

Object :: toString x -> x.toString ()

x :: toString () -> x.toString ()

ArrayList :: new () -> new ArrayList<>()

java.util.function

Ще одне нововведення JDK - безліч функціональних інтерфейсів, які будуть дуже корисні. Розглянемо деякі з них:

Function - інтерфейс, за допомогою якого реалізується функція, яка отримує на введення екземпляр класу T і повертає на виході екземпляр класу R. Далі не так докладно.

Predicate - на введення - T, повертає результат типу boolean.

Consumer - на введення - T, виробляє якусь дію і нічого не повертає.

Supplier - нічого не приймає на введення, повертає T

BinaryOperator - на введення - два примірника T, повертає один T

Пакет також забезпечений примітивними реалізаціями даних інтерфейсів для типів int, long і double.

java.util.stream

java.util.stream введений для підтримки розпаралелювання обчислень в потоках. Тепер потоки діляться на послідовні і паралельні. Найбільша користь від цього - в роботі з колекціями:

Stream забезпечений гнучким API для перетворення даних і оперування над ними. Ось так ми, наприклад, швидко знайдемо сумарна вага окремо червоних і синіх блоків в колекції: Що відбувається в коді:

1) З колекції blocks ми отримуємо stream

2) Метод filter повертає ще один stream, який вже містить елементи тільки одного кольору. Це проміжний (intermediate) метод класу Stream.

3) Метод mapToInt викликається у stream'а, який отриманий в пункті 2), і повертає stream, що містить не самі елементи, а їх властивості weight (тобто вага)

4) Метод sum викликається у stream'а з пункту 3), він підсумовує все weight і повертає простий int. Це кінцевий (terminal) метод, він повертає одиночний результат.

В цілому, стиль дуже схожий на той, що використовується в функціональному програмуванні, і це добре, тому що спроститься рішення широкого кола типових завдань.

Stream можна распараллелить, і тоді продуктивність операцій над ним зросте, адже навантаження розподілиться на всі ядра процесора. Давайте зробимо підрахунок елементів паралельним:

Єдина відмінність в тому, що тепер викликається метод parallelStream, і кожен наступний проміжний метод поверне паралельний stream. Таким чином, весь блок обчислень розподілиться на всі ядра процесора.

Зробити stream назад послідовним можна викликавши метод sequential (). Це в нагоді, коли нам, наприклад, потрібно, щоб відбір елементів за кольором був паралельним, а обчислення суми weight - послідовним:

Якщо ви знайомі з Joda Time, то освоїти нове API буде дуже легко. Майже всі в java.time є immutable. На відміну від старого API дати / часу, такі величини як місяці і дні тижня реалізовані через enum.

Основні класи java.time:

* LocalDateTime, LocalDate, LocalTime - представлення дати і часу. Час зберігається з точністю до наносекунди, так що в LocalTime можна зберігати, наприклад, величину "13: 45.30.123456789". Є безліч зручних методів, таких як plusMinutes, plusHours, isAfter, toSecondOfDay і т.д.

* Year, Month, YearMonth, MonthDay, DayOfWeek - типи, пов'язані з датами, отримали більший діапазон. Так, величина Year може бути від "-999,999,999" до "+999,999,999"

* Duration, Period - корисні, коли потрібно висловити дані як "3 роки, 2 місяці і 18 днів" або "3 години, 45 хвилин і 8 секунд"

На цьому нововведення Java 8 не закінчуються, а ми вивчили найочікуваніша в новій версії JDK. Всі стандартні колекції були розширені великою кількістю зручних методів і отримали можливість розпаралелювання обчислень в них з java.util.stream. Разом з java.util.function Java отримала ідіоми функціонального програмування. Лямбда-вирази, безумовно, скоротять обсяг коду, який розробникам доведеться писати, а новий API для роботи з датами і часом прийшов на заміну порядком застарілому старому.

admin liberal4ik AlexVovolka maxiflash annagrin007 ProteIne alexanzer vanya88 anastassia d3m0n1c nick_kryloff Andrey_G Cr0s dydus0x14 AngryCellophane AndrewRogovets t1oo1 san Basuliic dmytro_p Victor_MM Diesel31ks MrNikita alekseysamoylov swyd Orthodox nv_yunko