Java 8. Lambdas

23
Накрайников Олег [email protected] Java 8. Lambdas Java. The well-known and not well-known

Transcript of Java 8. Lambdas

Накрайников Олег[email protected]

Java 8. Lambdas

Java. The well-known and not well-known

8

Назначение lambda-выражений

Java 7

Java 8

Синтаксис lambda-выражений

▪ (String s) -> { return s. length();}

▪ (s) -> { return s. length();}

▪ (s) -> s. length()

▪ s -> s. length()

▪ () -> System.gc();

( Lambda Parameters ) -> { Lambda Body }

Пример:

▪ (int x, int y) -> x+y

▪ (x, y) -> x+y

▪ (int... x) -> x[0]+1

▪ (int[] x) -> x[0]+1

But illegal:

▪ (x, int y) -> x+y

▪ (x, final y) -> x+y

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

▪ Интерфейс с единственным абстрактным методом

▪ Аннотация @FunctionalInterface не обязательна

Примеры стандартных функциональных интерфейсов

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

Типы параметров Возвращаемый тип Имя абстрактногометода

Runnable Отсутствует Void run

Supplier<T> Отсутствует T get

Consumer<T> T Void accept

BiConsumer<T, U> T, U Void accept

Function<T, R> T R apply

BiFunction<T,U, R> T, U R apply

UnaryOperator<T> T T apply

BinaryOperator<T> T, T T apply

Predicate<T> T Boolean test

BiPredicate<T,U> T,U Boolean test

Примеры стандартных функциональных интерфейсовдля примитивов

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

Типы параметров Возвращаемый тип Имя абстрактногометода

LongFunction<T> long T apply

LongToIntFunction long int apply

ToLongFunction<T> T long apply

Ссылки на методы

▪ объект :: метод экземпляра

▪ класс :: статический метод

▪ класс :: метод экземпляра

В том числе:

▪ this :: метод экземпляра

▪ super :: метод экземпляра

▪ класс:: new

Область действия переменных

▪ Кодовый блок

▪ Параметры

Lambda выражение категории noncapturing :

▪ Кодовый блок

▪ Параметры

▪ Значение свободных переменных

Lambda выражение категории capturing :

Область действия переменных

Java 7. Final Java 8. Effectively final

Область действия переменных

Legal: x и y являются effectively final

void m1(int x) {int y = 1;foo(() -> x+y);

}

Legal: x и y являются effectively final

void m2(int x) {int y;y = 1;foo(() -> x+y);

}

Illegal: y являются effectively final, но гарантированоне инициализирована.

void m3(int x) {int y;if (...) y = 1;foo(() -> x+y);

}

Legal: x и y являются effectively final

void m4(int x) {int y;if (...) y = 1; else y = 2;foo(() ->; x+y);

}

Область действия переменных

Illegal : x не являются effectively final

void m5(int x) {int y;if (...) y = 1;y = 2;foo(() -> x+y);

}

Illegal: x не являются effectively final

void m6(int x) {foo(() -> x+1);x++;

}

Illegal : x не являются effectively final

void m7(int x) {foo(() -> x=1);

}

Illegal : y не являются effectively final

void m8() {int y;foo(() -> y=1);

}

Invokedynamic

Первый вызов: Последующие вызовы:

invokedynamic

BootStrap метод

CallSite

MethodHandlepublic Object foo(..){…}

вызывает

возвращает

Указывающий на

invokedynamic

CallSite

MethodHandlepublic Object foo(..){…}

Извлекае MH из

Указывающий на

или сразувызывает

метод напрямую

Invokedynamic

Пример:

Printer p = System.out::println;p.print("Str");

MethodHandleХранит указатель на метод

CallSiteОбъект,

описывающий«место» вызова в

коде

Трансляция lambda выражений

Стратегия 1. Lambda выражение категории noncapturing :

Исходный код:

class A {public void foo() {List<String> list = ...list.forEach( s -> {

System.out.println(s); } );

}}

Оттранслированый код:

class A {public void foo() {

List<String> list = ...list.forEach(indy((MH(metaFactory),

MH(invokeVirtual Consumer. accepts),MH(invokeStatic A.lambda$1)( )));

}private static void lambda$1(String s) {

System.out.println(s);}

}

Трансляция lambda выражений

Стратегия 2. Lambda выражение категории capturing :

Исходный код:

class B {public void foo() {

List<String> list = ...final int bottom = ..., top = ...;list.removeIf( s ->

(s. length() >= bottom &&s. length() <= top) );

}}

Оттранслированый код:

class B {public void foo() {

List<String> list = ...final int bottom = ..., top = ...;list.removeIf(indy((MH(metaFactory), MH(invokeVirtual Predicate.apply),MH(invokeStatic B.lambda$1))( bottom, top )))); }

static boolean lambda$1(int bottom, int top, String s) {return (p. length() >= bottom && p. length() <= top;

}}

Трансляция lambda выражений

Стратегия 3. Lambda выражение категории capturing :

Исходный код:

class B {final int bottom = ..., top = ...;

public void foo() {List<String> list = ...list.removeIf( s ->

(s. length() >= bottom &&s. length() <= top) );

}}

Оттранслированый код:

class B {final int bottom = ..., top = ...;public void foo() {

List<String> list = ...list.forEach(INDY((MH(metaFactory), MH(invokeVirtual Predicate.apply),MH(invokeVirtual B.lambda$1))( this )))); }

private boolean lambda$1(Element e) {return e.getSize() < minSize;

}}

Трансляция lambda выражений

Стратегия 4. Ссылка на метод :

Исходный код:

class A {public void foo() {List<String> list = ...list.filter(String::isEmpty) }

}

Оттранслированый код:

class A {public void foo() {

List<String> list = ...list.filter(

indy(MH(metaFactory), MH(invokeVirtual Predicate.apply),MH(invokeVirtual String.isEmpty))()))

}}

Трансляция lambda выражений

Стратегия 5. Аргументы переменной длины:

Исходный код:

interface IIS {void foo(Integer a1, Integer a2, String a3);

}class Foo {

static void m(Number a1, Object... rest) { ... }}class Bar {

void bar() {IIS x = Foo::m;

}}

Оттранслированый код:

class Bar {void bar() {

SIS x = indy((MH(metafactory), MH(invokeVirtual IIS.foo),MH(invokeStatic m$bridge))( ))

}

static private void m$bridge(Integer a1, Integer a2, String a3) {

Foo.m(a1, a2, a3);}

}

Сериализация lambda выраженийВариант 1:

Сериализация lambda выраженийВариант 2:

Использованные источники

▪ Кей С. Хорстманн – Java SE 8. Вводный курс

▪ JLS - Lambda Expressions [http://docs.oracle.com/javase/specs/jls/se8/html/ ]

▪ Translation of Lambda Expressions [http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html ]

▪ State of the Lambda [http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html]

▪ Д. Сосноски - Изменения в языке Java 8[http://www.ibm.com/developerworks/ru/library/j-java8lambdas/]

Спасибо за внимание!