Skip to content

Latest commit

 

History

History
133 lines (93 loc) · 10.6 KB

File metadata and controls

133 lines (93 loc) · 10.6 KB

Interfaces

Default methods

Метод за замовчуванням (default method) - не статичний метод з реалізацією оголошеною в тілі інтерфейсу. Для оголошення використовується ключове слово default.

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

Логічним розвитком дефолтних методів є private methods в java 1.9. У них описуються блоки коду, які не бажано розміщувати в дефолтних методах (приховування логіки), і які не потрібні в інтерфейсах і класах, які будуть реалізувати інтерфейс. Приватні методи не наслідуються.


Functional interfaces

Функціональний інтерфейс - інтерфейс в якого є тільки один абстрактний метод. Крім єдиного абстрактного методу може також містити static методи, default методи, та методи класу Object. Основне призначення - використання в лямбда виразах. Також функціональні інтерфейси реалізують аналог функцій вищого порядку (функцій, які в якості аргументів можуть приймати інші функції).

Щоб перевірити, чи є інтерфейс функціональним на етапі компіляції, використовується анотація @FunctionalInterface

Посилання на методи в Java 1.8 з'явився механізм, що дозволяє посилатися на метод в реалізації функціонального інтерфейсу. Для цього був введений новий оператор ::.

Базові функціональні інтерфейси

  • Predicate<T> - приймає об'єкт типу Т і перевіряє деяку умову. Якщо умова виконується, повертає true.
  • Consumer<T> - приймає об'єкт типу Т, виконує деяку дію, але при цьому нічого не повертає.
  • Function<T,R> - приймає об'єкт типу Т, перетворює його на об'єкти типу R, і повертає об'єкт типу R.
  • Supplier<T> - не приймає жодних аргументів, але при цьому повертає об'єктитипу Т.
  • UnaryOperator<T> - приймає об'єкт типу Т, виконує над тим деякі операції, і повертає об'єкт того ж типу.
  • BinaryOperator<T> - приймає як параметри 2 об'єкти типу Т, виконує над ними деякі операції, і повертає об'єкт типу Т.

Predicate

Predicate - функціональний інтерфейс, що з'явився у java 8. Використовується для перевірки тої чи іншої умови. Найчастіше використовується для фільтрації даних, щоб визначити, підійде об'єкт для подальшої роботи, чи ні.

Predicate містить наступні методи:

  • абстрактний boolean test(t t)
  • default and(), or(), negate() (логічні оператори)
  • static not(), isEqual()
        List<Integer> listInt = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

        Predicate<Integer> p1 = e -> e > 2;
        Predicate<Integer> p2 = e -> e < 5;

        listInt.removeIf(p1.and(p2).negate());  // або listInt.removeIf(Predicate.not(p1.and(p2)));
        
        System.out.println(listInt); // [3, 4]

Спеціалізації інтерфейсу predicate:

  • BiPredicate<T,U> приймає на вхід 2 об'єкти, має ті ж методи що й Predicate крім статичних
  • IntPredicate, LongPredicate, DoublePredicate - примітивні спеціалізації інтерфейсу, створені для роботи з відповідними примітивами.

Function

Function<T,R> - функціональний інтерфейс, що з'явився у java 8. Використовується для опису функції, що генерує на основі об'єкту одного типу об'єкт іншого типу (або того ж типу). Використовується в методах створення одних об'єктів на основі інших, або для перетворення одних типів в інші.

Методи Function:

  • абстрактний R apply(T t)
  • default andThen(), compose() (композиція)
  • static identity() (повертає значення аргументу)
Function<String, Integer> f = String::length;
System.out.println(f.apply("Hello")); //5

Спеціалазації інтерфейсу Function:

  • BiFunction<U,V,R> як і у випадку зі спеціалізацією predicate приймає на вхід 2 об'єкти.
  • IntFunction, LongFunction ... примітивні спеціалізації, що на вхід приймають об'єкт відповідного примітивного типую
  • ToIntFunction, ToLongFunction ... породжуючі спеціалізації, що повертають об'єкт відповідного примітивного типу

Consumer

Consumer - функціональний інтерфейс java8, що використовується для опису операції над об'єктом, без повернення результату. В основному реалізується опираючист на "побічні ефекти" при виконанні операції.

Побічні ефекти методі (функції) - можливість функції в процесі виконання:

  • читати і модифікувати значення глобальних змінних і полів класу.
  • виконуватиоперації вводу/виводу
  • реагувати на виключення і викликати їх обробку

Методі consumer:

  • абстрактний void accept(T t)
  • дефолтний Consumer<T> andThen(Consumer<? super T> after) (композиція).

Як і для інших функціональних інтерфейсів, для consumer існують бінарна та примітивна спеціалізації:

  • void accept(T t, U u)
  • default BiConsumer<T, U> andThen(BiConsumer<? super T, ? super U> after)
  • ...

UnaryOperator

UnaryOperator - функціональний інтерфейс java8. Є наслідником функціонального інтерфейсу Function<T,T>, з тою лиш різницею, що параметр і результат того ж типу.

Методи UnaryOperator:

  • abstract T apply(T t)
  • default <V> Function<V,T> andThen(Function<? super T, ? extends V> after)
  • default V Function<V,T> compose(Function<? super V, ? extends T> before) (композиція)
  • static <T> UnaryOperator<T> identity() (повертає значення аргументу)

UnaryOperator має стандартні примітивні спеціалізації.


BinaryOperator

BinaryOperator - функціональний інтерфейс в java8. Є наслідником функціонального інтерфейсу BiFunction<T,T,T>. Описує операцію над двома операндами одного типу і повертає результат того ж типу.

Методи BinaryOperator схожі на методb Function:

  • abstract T apply(T t1, T t2)
  • default V BiFunction<T,T,V> andThen(Function<? super T, ? extends V> after) (композиція)
  • static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator), аналогічно maxBy().

BinaryOperator має стандартні примітивні спеціалізації.


Supplier

Supplier - функціональний інтерфейс в java8. Використовується для створення об'єктів потрібного типу без параметрів. Часто використовується в термінальних методах Stream API.

Має єдиний абстрактний метод T get().

Часто Supplier використовують в якості посилання на конструктор класу, реалізуючи т.зв "ліниве" створення об'єкту. Об'єкт створюється лише тоді, коли викликаєтьяс метод get() в реалізації інтерфейсу. Якщо метод не викликається, об'єкт не створюється.

Supplier<List<String>> sup = ArrayList::new;
List<String> list = sup.get();