Привет друзья,
Когда Java 8 была выпущена, прошло довольно много времени, и теперь она все больше и больше используется. В этом посте мы обсудим следующие темы Java 8.
1. Функциональный интерфейс
2. Лямбда-выражение
3. Методы по умолчанию
1. Функциональный интерфейс
Что такое функциональный интерфейс?
Интерфейс с одним-единственным абстрактным методом является функциональным интерфейсом, так как он представляет только одну функциональность. Тем не менее, функциональный интерфейс может иметь n номеров по умолчанию, а также статических методов.
Синтаксис для функционального интерфейса
Это как любой другой интерфейс. Разница лишь в том, что она должна иметь аннотацию @FunctionalInterface вверху.
1
2
3
4
|
@FunctionalInterface interface fly { } |
Кроме того, мы должны понимать, что даже если мы не используем аннотацию @FunctionalInterface, но интерфейс имеет только один абстрактный метод, то по умолчанию этот интерфейс будет рассматриваться как функциональный интерфейс, но всегда рекомендуется использовать аннотацию @FunctionalInterface для функционального интерфейса.
Преимущество размещения аннотации @FunctionalInterface состоит в том, что сегодня вы можете определить интерфейс как функциональный интерфейс, имея в нем только один абстрактный метод, не используя аннотацию @FucntionalInterface, и помните, что лямбда-выражения могут быть написаны для этого функционального интерфейса, но если у вас большие проект с большим количеством разработчиков, работающих над этим проектом, тогда есть большие шансы, что позже кто-то может добавить другой метод к вашему функциональному интерфейсу, который тогда фактически не останется функциональным интерфейсом, поскольку у него будет более одного абстрактного метода и в то же время, он нарушит все уже написанные лямбда-выражения.
Так что, если вы хотите написать интерфейс, на котором можно писать лямбды, лучше пометьте его @FunctionalInterface.
Основная цель функционального интерфейса
Основная цель введения функционального интерфейса в Java 8 состоит в том, чтобы разрешить запись лямбда-выражения в функциональный интерфейс, так как сигнатура метода лямбда-выражения проверяется по методу функционального интерфейса.
Пример функционального интерфейса
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
@FunctionalInterface public interface Calculator { int add( int a, int b); } public class Test { public static void main(String[] args){ Calculator calculator = (a,b) -> a + b; System.out.println( "Sum is:" + calculator.add( 4 , 6 )); } } |
Существует множество встроенных функциональных интерфейсов, которые были добавлены в JDK 1.8 в пакете java.util.function, который можно использовать для написания лямбда-выражения.
сказуемое
потребитель
поставщик
функция
2. Лямбда-выражение
Что такое лямбда-выражение?
Лямбда-выражение в простых словах является реализацией метода функционального интерфейса. Обычно мы пишем реализации в методах, но в случае лямбда-выражения нет метода, в котором он был бы написан, поэтому мы можем рассматривать лямбда-выражение как анонимную функцию, то есть функцию с реализацией, но без имени.
Синтаксис лямбда-выражения?
1
|
(Comma separated parameters) + arrow symbol + single expression or block of statements; |
Основная цель лямбда-выражения
Основной причиной введения лямбда-выражения в Java 8 было включение функционального программирования в Java. До Java 8, если мы хотели иметь некоторые функциональные возможности, которые мы хотели бы выполнять встроенными, например, по нажатию кнопки, и этот код не имело смысла помещать в отдельный класс, мы делали это, создавая анонимный класс. В этих случаях мы обычно пытаемся передать функциональность в качестве аргумента другому методу, например, какое действие следует предпринять, когда кто-то нажимает кнопку. Проблема с анонимным классом состоит в том, что даже если у нас очень маленькая реализация, код, написанный с использованием анонимного класса, очень многословен и неясен. С помощью лямбда-выражения мы можем писать код более читабельным и лаконичным образом.
Пример лямбда-выражения
Давайте посмотрим, как написать лямбда-выражение.
Из приведенного выше примера мы имеем следующий интерфейс:
1
2
3
4
5
6
7
|
@FunctionalInterface public interface Calculator { int add( int a, int b); } |
Лямбда-выражение получает свою сигнатуру из метода функционального интерфейса, поэтому, используя сигнатуру метода add, мы напишем наше первое лямбда-выражение. С левой стороны в скобках у нас будут параметры, затем символ стрелки, а затем блок утверждения.
1
2
3
4
5
|
( int a, int b) -> { return a + b; }; |
если вы посмотрите на это внимательно, это определение метода без какого-либо имени метода. Скажем, у него будет имя, тогда оно будет выглядеть, как показано ниже, после удаления символа стрелки:
1
2
3
4
5
|
add( int a, int b) { return a + b; }; |
Теперь, чтобы преобразовать его в Lambda, Java-дизайнеры удалили имя, т.е. добавили и поместили символ стрелки после параметров, так, чтобы это было так, как показано ниже:
1
2
3
4
5
|
( int a, int b) ->{ return a + b; }; |
Теперь, поскольку компилятор проверяет сигнатуру лямбда-выражения, сопоставляя ее с сигнатурой метода функционального интерфейса, поэтому компилятор может угадать тип параметров, передаваемых в лямбда-выражении, сравнивая его с методом функционального интерфейса. Таким образом, мы можем удалить типы из параметров, так что наше модифицированное лямбда-выражение будет выглядеть следующим образом:
1
2
3
4
5
|
(a, b) -> { return a + b; }; |
Помимо предположения о типе параметров, компилятор также узнает, что это лямбда-выражение будет возвращать значение int, посмотрев на тип возврата метода, объявленный в функциональном интерфейсе, поэтому мы также можем удалить ключевое слово return.
1
2
3
4
5
|
(a, b) -> { a + b; }; |
Теперь, поскольку в вышеприведенном лямбда-выражении у нас есть только один оператор в блоке, мы также можем избавиться от фигурных скобок, поэтому модифицированная лямбда-выражение будет выглядеть следующим образом:
1
|
(a,b) -> a +b; |
3. Методы по умолчанию в интерфейсе
Что такое метод по умолчанию?
Методы по умолчанию — это методы с некоторой реализацией по умолчанию, которую можно определить в интерфейсе.
До Java8 у нас не могло быть методов с определениями в интерфейсе, однако с Java8 у нас могут быть методы с определением также в интерфейсе, но это особый вид метода, в том смысле, что в его сигнатуре есть ключевое слово по умолчанию ,
Основная цель внедрения методов по умолчанию
Основная причина добавления метода по умолчанию в Java состоит в том, чтобы сделать код обратно совместимым, даже если новые методы введены в уже существующие интерфейсы, потому что если методы по умолчанию не существуют, и мы пытаемся добавить новый метод в уже существующий интерфейс это нарушит все классы реализации, так как эти существующие классы реализации должны реализовывать недавно представленный метод (ы) в интерфейсе.
Синтаксис для метода по умолчанию
1
2
3
4
5
6
7
|
public interface InterfaceTest{ <b> default </b> public void testDefault(){ } } |
Пример метода по умолчанию
Итерируемый интерфейс, который существует с JDK 1.5, получил следующий новый метод по умолчанию в выпуске JDK 1.8. Теперь, когда интерфейс Collection расширяет этот итеративный интерфейс и коллекции, такие как List, Set расширяет интерфейс Collection, этот метод доступен для этих коллекций по умолчанию для перебора элементов этих коллекций.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public interface Iterable<T> { default void forEach(Consumer<? super T>action) { Objects.requireNonNull(action); for (T t : this ) { action.accept(t); } } } |
если бы этот метод не был по умолчанию и был бы добавлен к интерфейсу Iterable, он заставил бы все классы, реализующие этот интерфейс (через интерфейс Collection), реализовать этот метод и, следовательно, сломал бы все эти классы. Таким образом, чтобы код, подобный методу forEach, работал без нарушения существующего кода, в JDK 1.8 введены методы по умолчанию.
Спасибо за чтение возможностей языка Java 8. Пожалуйста, поделитесь им, если вы считаете, что это было полезно, чтобы другие тоже могли извлечь из этого пользу.
Опубликовано на Java Code Geeks с разрешения Гаурава Бхардваджа, партнера нашей программы JCG . См. Оригинальную статью здесь: возможности языка Java 8 в Nutshell — часть 1
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |