Successfully reported this slideshow.
Your SlideShare is downloading. ×

Урок 18. Лямбда в языке Java

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 77 Ad

Урок 18. Лямбда в языке Java

Download to read offline

Урок 18. Лямбда в языке Java.
Лямбда выражения и функциональный интерфейс.
Интерфейсы Predicate, Consumer, Function, Supplier, UnaryOperator.
Специализации функциональных интерфейсов.
Ссылки на методы.
Лекции, задания, видео, тесты и вопросы на:
https://www.examclouds.com/ru/java/java-core-russian/lesson15
Подписывайтесь на страницу:
https://www.facebook.com/Examclouds
Подписывайтесь на канал
https://www.youtube.com/c/tatyanamilkina

Урок 18. Лямбда в языке Java.
Лямбда выражения и функциональный интерфейс.
Интерфейсы Predicate, Consumer, Function, Supplier, UnaryOperator.
Специализации функциональных интерфейсов.
Ссылки на методы.
Лекции, задания, видео, тесты и вопросы на:
https://www.examclouds.com/ru/java/java-core-russian/lesson15
Подписывайтесь на страницу:
https://www.facebook.com/Examclouds
Подписывайтесь на канал
https://www.youtube.com/c/tatyanamilkina

Advertisement
Advertisement

More Related Content

Slideshows for you (19)

Similar to Урок 18. Лямбда в языке Java (20)

Advertisement

Урок 18. Лямбда в языке Java

  1. 1. 1. Лямбда выражения 2. Функциональный интерфейс 3. Интерфейс Predicate 4. Интерфейс Consumer 5. Интерфейс Function 6. Интерфейс Supplier 7. Интерфейс UnaryOperator 8. Специализации функциональных интерфейсов 9. Ссылки на методы www.examclouds.com
  2. 2. Пример private int getCompactCarsNumber(Car[] cars) { int result = 0; for (Car car : cars) { if (car.getType().equals(CarTypes.COMPACT)) { result++; } } return result; } private int getExpensiveCarsNumber(Car[] cars) { int result = 0; for (Car car : cars) { if (car.getCost() > 20000) { result++; } } return result; }(CarDemo1.java) www.examclouds.com
  3. 3. Пример public interface Searchable { boolean test(Car car); } public class CompactCarSearch implements Searchable { public boolean test(Car car) { return car.getType().equals(CarTypes.COMPACT); } } public class ExpensiveCarSearch implements Searchable { public boolean test(Car car) { return car.getCost() > 20000; } } www.examclouds.com
  4. 4. Пример private int getCarsNumber(Car[] cars, Searchable s) { int result = 0; for (Car car : cars) { if (s.test(car)) { result++; } } return result; } private int getCompactCarsNumber(Car[] cars) { int result = 0; for (Car car : cars) { if (car.getType().equals(CarTypes.COMPACT)) { result++; } } return result; } private int getExpensiveCarsNumber(Car[] cars) { int result = 0; for (Car car : cars) { if (car.getCost() > 20000) { result++; } } return result; }(CarDemo1.java) carDemo.getCarsNumber(cars, new CompactCarSearch()); carDemo.getCarsNumber(cars, new ExpensiveCarSearch()); www.examclouds.com
  5. 5. Лямбда выражение  Вместо  можно: carDemo.getCarsNumber(cars, new Searchable() { @Override public boolean test(Car car) { return car.getType().equals(CarTypes.COMPACT); } }); carDemo.getCarsNumber(cars, car -> car.getType().equals(CarTypes.COMPACT)); www.examclouds.com
  6. 6. Части лямбда выражения  Синтаксис: (параметры) -> (тело)  Пример: (Object arg1, Object arg2) -> arg1.equals(arg2);  Лямбда выражение содержит три части: список параметров; стрелочка; тело. www.examclouds.com
  7. 7. Правила написания списка параметров лямбда выражений  Лямбда выражение может содержать ноль и более входных параметров:  (int a1, int a2) -> { return a1 - a2; }  (String s) -> { System.out.println(s); }  () -> 89; www.examclouds.com
  8. 8. Правила написания списка параметров лямбда выражений  Тип параметра может быть явно объявлен или выведен компилятором из значения параметра. Например: (String s) -> { System.out.println(s); } Можно переписать так: (s) -> { System.out.println(s); } www.examclouds.com
  9. 9. Правила написания списка параметров лямбда выражений  Если параметров нет или их больше одного, скобки необходимы:  (a1, a2) -> return a1 + a2;  (int a1, int a2) -> return a1 + a2;  () -> 42;  Нет необходимости объявлять один параметр в скобках, но в этом случае нельзя явно указать тип параметра:  a1 -> return 2 * a1 www.examclouds.com
  10. 10. Правила написания тела лямбда выражений  Тело лямбда выражения может содержать одно и более выражений.  Нет необходимости использовать фигурные скобки и ключевое слово return, если тело состоит из одного выражения.  () -> 4;  (int a) -> a*6; www.examclouds.com
  11. 11. Правила написания тела лямбда выражений  Если тело содержит более одного выражения, фигурные скобки и ключевое слово return необходимы.  () -> { System.out.println("Hi"); return 4; } (int a) -> { System.out.println(a); return a*6; } www.examclouds.com
  12. 12. Правила написания тела лямбда выражений  Если ключевое слово return отсутствует, возвращаемый тип может быть void.  () -> System.out.println("Hi"); () -> { System.out.println("Hi"); return; } www.examclouds.com
  13. 13. Функциональный интерфейс  Чтобы иметь возможность использовать лямбда выражения, необходим интерфейс.  public interface Searchable { boolean test(Car car); }  Searchable s = (Car c) -> c.getCostUSD() > 20000; www.examclouds.com
  14. 14. Лямбда и интерфейс  Лямбда выражения не содержат информацию о том, какой функциональный интерфейс они реализуют.  Тип выражения выводится из контекста, в котором используется лямбда выражение. Этот тип называется целевой тип (target type).  Если лямбда выражение присваивается какому-то интерфейсу, лямбда выражение должно соответствовать синтаксису метода интерфейса. www.examclouds.com
  15. 15. Лямбда и интерфейс  Одно и то же лямбда выражение может использоваться с разными интерфейсами, если они имеют абстрактные методы, которые совместимы.  interface Searchable { boolean test(Car car); } interface Saleable { boolean approve(Car car); } //... Searchable s1 = c -> c.getCostUSD() > 20000; Saleable s2 = c -> c.getCostUSD() > 20000; www.examclouds.com
  16. 16. Функциональный интерфейс  Функциональный интерфейс (functional interface) – это интерфейс у которого только один абстрактный метод.  Функциональный интерфейс может содержать любое количество методов по умолчанию (default) или статических методов. www.examclouds.com
  17. 17. Пример 1 функционального интерфейса  interface A { default int defaultMethod() { return 0; } void method(); } www.examclouds.com
  18. 18. Пример 2 функционального интерфейса  interface B { default int defaultMethod() { return 0; } default int anotherDefaultMethod() { return 0; } void method(); } www.examclouds.com
  19. 19. Пример 3 функционального интерфейса  interface A { boolean equals(Object o); int hashCode(); String toString(); void method(); } www.examclouds.com
  20. 20. Аннотация @FunctionalInterface  В Java 8 была введена аннотация @FunctionalInterface, которая генерирует ошибку компиляции, если интерфейс не является функциональным.  // This won't compile @FunctionalInterface interface A { void m(int i); void m(long l); } www.examclouds.com
  21. 21. Примеры функциональных интерфейсов  java.lang.Runnable  java.util.Comparator www.examclouds.com
  22. 22. Лямбда и анонимные классы  Лямбда выражения являются альтернативой анонимным классам. Но они не одинаковы.  Общее: 1. Локальные переменные могут быть использованы только если они final или effective final. 2. Разрешается доступ к переменным класса и статическим переменным класса. 3. Они не должны выбрасывать больше исключений чем определено в throws метода функционального интерфейса. www.examclouds.com
  23. 23. Лямбда и анонимные классы  Различия: 1. Для анонимных классов ключевое слово this ссылается на сам класс. Для лямбда выражений на внешний класс. 2. Анонимные классы компилируются во внутренние классы. Но лямбда выражения преобразуются в статические private методы класса, в котором они используют invokedynamic инструкцию. Лямбда более эффективны, т.к. не надо загружать еще один класс. www.examclouds.com
  24. 24. Задание 1  Написать лямбда выражение для интерфейса Printable. www.examclouds.com
  25. 25. Встроенные функциональные интерфейсы  В Java 8 добавлены встроенные функциональные интерфейсы в пакет java.util.function:  Predicate  Consumer  Function  Supplier  UnaryOperator www.examclouds.com
  26. 26. Функциональный интерфейс Predicate<T>  Принимает на вход значение, проверяет состояние и возвращает boolean значение в качестве результата.  Predicate<T> “подтверждает” какое-то значение как true или false.  @FunctionalInterface public interface Predicate<T> { boolean test(T t); } www.examclouds.com
  27. 27. Функциональный дескриптор Predicate<T> интерфейса  T -> boolean www.examclouds.com
  28. 28. Пример использования интерфейса Predicate<T> public class PredicateDemo1 { public static void main(String[] args) { Predicate<Integer> negative = i -> i < 0; System.out.println(negative.test(-6)); System.out.println(negative.test(6)); System.out.println(negative.test(0)); } } www.examclouds.com
  29. 29. Задание 2 1. Создать лямбда выражение, которое возвращает значение true, если строка не null, используя функциональный интерфейс Predicate. 2. Создать лямбда выражение, которое проверяет, что строка не пуста, используя функциональный интерфейс Predicate. www.examclouds.com
  30. 30. Методы по умолчанию интерфейса Predicate  Predicate интерфейс содержит методы по умолчанию: default Predicate<T> and(Predicate<? super T> other); default Predicate<T> or(Predicate<? super T> other); default Predicate<T> negate(); www.examclouds.com
  31. 31. Методы по умолчанию интерфейса Predicate public class PredicateDemo2 { public static void main(String[] args) { Predicate<String> containsA = t -> t.contains("A"); Predicate<String> containsB = t -> t.contains("B"); System.out.println(containsA.and(containsB).test("ABCD")); } } www.examclouds.com
  32. 32. Задание 3  Написать программу проверяющую, что строка не пуста, используя метод and() функционального интерфейса Predicate. www.examclouds.com
  33. 33. Задание 4  Написать программу которая проверяет, что строка начинается буквой “J”или “N” и заканчивается “A”.  Используем функциональный интерфейс Predicate. www.examclouds.com
  34. 34. Функциональный интерфейс Consumer<T>  Принимает значение в качестве аргумента и ничего не возвращает.  @FunctionalInterface public interface Consumer<T> { void accept(T t); } www.examclouds.com
  35. 35. Пример использования интерфейса Consumer<T> public class ConsumerDemo1 { public static void main(String[] args) { Consumer<String> printUpperCase = str -> System.out.println(str.toUpperCase()); printUpperCase.accept("hello"); Consumer<String> printLowerCase = str -> System.out.println(str.toLowerCase()); } } www.examclouds.com
  36. 36. Функциональный дескриптор интерфейса Consumer<T>  T -> void www.examclouds.com
  37. 37. Задание 5  Написать лямбда выражение, которое принимает на вход объект типа HeavyBox и выводит на консоль сообщение “Отгрузили ящик с весом n”.  Используем функциональный интерфейс Consumer. www.examclouds.com
  38. 38. Метод andThen интерфейса Consumer  Consumer интерфейс содержит метод по умолчанию, который возвращает составной Consumer, выполняющий последовательно действия указанные в каждом интерфейсе.  default Consumer<T> andThen(Consumer<? super T> after) www.examclouds.com
  39. 39. Пример использования интерфейса Consumer<T> public class ConsumerDemo1 { public static void main(String[] args) { Consumer<String> printUpperCase = str -> System.out.println(str.toUpperCase()); printUpperCase.accept("hello"); Consumer<String> printLowerCase = str -> System.out.println(str.toLowerCase()); printUpperCase.andThen(printLowerCase).accept("Hello world"); } } www.examclouds.com
  40. 40. Задание 6  Написать лямбда выражение, которое принимает на вход объект типа HeavyBox и выводит на консоль сообщение “Отгрузили ящик с весом n”. “Отправляем ящик с весом n”  Используем функциональный интерфейс Consumer и метод по умолчанию andThen. www.examclouds.com
  41. 41. Функциональный интерфейс Function<T, R>  Принимает значение в качестве аргумента одного типа и возвращает другое значение.  Часто используется для преобразования одного значения в другое.  @FunctionalInterface public interface Function<T, R> { R apply(T t); } www.examclouds.com
  42. 42. Функциональный дескриптор интерфейса Function<T, R>  T -> R www.examclouds.com
  43. 43. Пример использования интерфейса Function<T,R> public class FunctionDemo1 { public static void main(String[] args) { Function<Double, Long> function = d -> Math.round(d); System.out.println(function.apply(5.7)); } } www.examclouds.com
  44. 44. Методы по умолчанию интерфейса Function<T,R>  default <V> Function<T, V> andThen(Function<? super R, ? extends V> after);  default <V> Function<V, R> compose(Function<? super V, ? extends T> before); www.examclouds.com
  45. 45. Пример использования интерфейса Function<T,R> public class FunctionDemo2 { public static void main(String[] args) { Function<String, String> f1 = s -> s + "1"; Function<String, String> f2 = s -> s + "2"; Function<String, String> f3 = s -> s + "3"; Function<String, String> f4 = s -> s + "4"; System.out.println(f1.andThen(f2).compose(f3).compose(f4).apply(" System.out.println(f1.andThen(f2).andThen(f3).apply("AndThen")); } } www.examclouds.com
  46. 46. Статический метод интерфейса Function<T,R>  static <T> Function<T, T> identity()  Возвращает интерфейс Function, который всегда возвращает входной параметр.  Пример: public class FunctionDemo3 { public static void main(String[] args) { Function<String, String> f = Function.identity(); System.out.println(f.apply("Some Value")); } } www.examclouds.com
  47. 47. Задание 7  Написать лямбда выражение, которое принимает на вход число и возвращает значение “Положительное число”, “Отрицательное число” или “Ноль”.  Используем функциональный интерфейс Function. www.examclouds.com
  48. 48. Функциональный интерфейс Supplier<T>  Возвращает значение, одно и тоже или разные.  @FunctionalInterface public interface Supplier<T> { T get(); } www.examclouds.com
  49. 49. Функциональный дескриптор интерфейса Supplier<T>  () -> T www.examclouds.com
  50. 50. Пример использования интерфейса Supplier<T> public class SupplierDemo1 { public static void main(String[] args) { String t = "One"; Supplier<String> supplierStr = () -> t.toUpperCase(); System.out.println(supplierStr.get()); } } www.examclouds.com
  51. 51. Задание 8  Написать лямбда выражение, которое возвращает случайное число от 0 до 10.  Используем функциональный интерфейс Supplier. www.examclouds.com
  52. 52. Встроенные функциональные интерфейсы www.examclouds.com
  53. 53. Функциональный интерфейс UnaryOperator  UnaryOperator расширяет интерфейс Function.  Используется в случае, если аргумент и возвращаемое значение одного типа.  @FunctionalInterface public interface UnaryOperator<T> extends Function<T, T> { … } www.examclouds.com
  54. 54. Функциональный дескриптор интерфейса UnaryOperator  T -> T www.examclouds.com
  55. 55. Пример использования интерфейса UnaryOperator public class UnaryOperatorDemo { public static void main(String[] args) { UnaryOperator<String> uo = s -> s.toUpperCase(); System.out.print(uo.apply("Java 12")); } } www.examclouds.com
  56. 56. Бинарные специализации  Существуют бинарные специализации (binary specializations) функций Predicate, Consumer, Function и UnaryOperator, которые принимают на вход два элемента.  BiConsumer<T, U>  BiFunction<T, U, R>  BiPredicate<T, U>  BinaryOperator<T> www.examclouds.com
  57. 57. Примитивные специализации Predicate Интерфейс Описание IntPredicate Принимает на вход значение типа int возвращает значение типа boolean. LongPredicate Принимает на вход значение типа long возвращает значение типа boolean. DoublePredicate Принимает на вход значение типа double возвращает значение типа boolean. www.examclouds.com
  58. 58. Примитивные специализации Consumer Интерфейс Описание IntConsumer Принимает на вход значение типа int и ничего не возвращает. LongConsumer Принимает на вход значение типа long и ничего не возвращает. DoubleConsumer Принимает на вход значение типа double и ничего не возвращает. www.examclouds.com
  59. 59. Примитивные специализации Function Интерфейс Описание IntFunction<R> Принимает на вход значение типа int и возвращает значение типа R. LongFunction<R> Принимает на вход значение типа long и возвращает значение типа R. DoubleFunction<R> Принимает на вход значение типа double и возвращает значение R. Интерфейс Описание ToIntFunction<T> Принимает на вход значение типа T и возвращает значение типа int. ToDoubleFunction<T> Принимает на вход значение типа T и возвращает значение типа double. ToLongFunction<T> Принимает на вход значение типа T и возвращает значение типа long. www.examclouds.com
  60. 60. Примитивные специализации Function Интерфейс Описание IntToDoubleFunction Принимает на вход значение типа int и возвращает значение типа double. IntToLongFunction Принимает на вход значение типа int и возвращает значение типа long. LongToDoubleFunction Принимает на вход значение типа long и возвращает значение типа double. LongToIntFunction Принимает на вход значение типа long и возвращает значение типа int. DoubleToIntFunction Принимает на вход значение типа double и возвращает значение типа int. DoubleToLongFunction Принимает на вход значение типа double и возвращает значение типа long. www.examclouds.com
  61. 61. Примитивные специализации Supplier Интерфейс Описание BooleanSupplier Возвращает значение типа boolean. IntSupplier Возвращает значение типа int. LongSupplier Возвращает значение типа long. DoubleSupplier Возвращает значение типа double. www.examclouds.com
  62. 62. Примитивные специализации UnaryOperator Интерфейс Описание IntUnaryOperator Принимает и возвращает значение типа int. LongUnaryOperator Принимает и возвращает значение типа long. DoubleUnaryOperator Принимает и возвращает значение типа double. www.examclouds.com
  63. 63. Примитивные специализации BinaryOperator Интерфейс Описание IntBinaryOperator Принимает на вход два значения типа int и возвращает значение типа int. LongBinaryOperator Принимает на вход два значения типа long и возвращает значение типа long. DoubleBinaryOperator Принимает на вход два значения типа double и возвращает значение типа double. www.examclouds.com
  64. 64. Примитивные специализации BiConsumer Интерфейс Описание ObjIntConsumer<T> Принимает на вход два значения: типа int и Object. ObjLongConsumer<T> Принимает на вход два значения: типа long и Object. ObjDoubleConsumer<T> Принимает на вход два значения: типа double и Object. www.examclouds.com
  65. 65. Примитивные специализации BiFunction Интерфейс Описание ToIntBiFunction<T, U> Принимает на вход два объекта и возвращает значение типа int. ToLongBiFunction<T, U> Принимает на вход два объекта и возвращает значение типа long. ToDoubleBiFunction<T, U> Принимает на вход два объекта и возвращает значение типа double. www.examclouds.com
  66. 66. Ссылки на методы (Method References)  Если лямбда выражения вызывают только один существующий метод, лучше ссылать на этот метод по его имени.  Method References – это компактные лямбда выражения для методов у которых уже есть имя.  Например:  Consumer<String> consumer = str -> System.out.println(str);  Можно переписать с помощью Method References:  Consumer<String> consumer = System.out::println; www.examclouds.com
  67. 67. Method References Тип Пример Ссылка на статический метод ContainingClass::staticMethodName Ссылка на нестатический метод конкретного объекта containingObject::instanceMethodName Ссылка на нестатический метод любого объекта конкретного типа ContainingType::methodName Ссылка на конструктор ClassName::new www.examclouds.com
  68. 68. 1. Ссылка на статический метод  Синтаксис: ContainingClass::staticMethodName  Например:  Function<String, Boolean> function = e -> Boolean.valueOf(e); System.out.println(function.apply("TRUE"));  Перепишем с помощью ссылки:  Function<String, Boolean> function = Boolean::valueOf; System.out.println(function.apply("TRUE")); www.examclouds.com
  69. 69. Задание 9  Перепишите используя method references:  IntFunction<String> function = i -> String.valueOf(i); System.out.println(function.apply(450)); www.examclouds.com
  70. 70. 2. Ссылка на нестатический метод конкретного объекта  Синтаксис:  containingObject::instanceMethodName  Этот тип используется когда лямбда выражение вызывает метод внешнего уже существующего объекта. www.examclouds.com
  71. 71. 2. Ссылка на нестатический метод конкретного объекта  Например:  Consumer<String> consumer = e -> System.out.println(e);  consumer.accept("OCPJP 8");  Перепишем, используя ссылку:  Consumer<String> consumer = System.out::println; consumer.accept("OCPJP 8"); www.examclouds.com
  72. 72. 2. Ссылка на нестатический метод конкретного объекта  Пример:  Integer integer = 5;  Supplier<String> supplier = () -> integer.toString(); System.out.println(supplier.get());  Перепишем:  Integer integer = 5;  Supplier<String> supplier = integer::toString; System.out.println(supplier.get()); www.examclouds.com
  73. 73. 3. Ссылка на нестатический метод любого объекта конкретного типа  Синтаксис:  ContainingType::methodName  Например:  Function<String, String> function = s -> s.toLowerCase(); System.out.println(function.apply("OCPJP 8"));  Перепишем:  Function<String, String> function = String::toLowerCase; System.out.println(function.apply("OCPJP 8")); www.examclouds.com
  74. 74. 4. Ссылка на конструктор  Синтаксис:  ClassName::new  ClassName не может быть абстрактным классом или интерфейсом. www.examclouds.com
  75. 75. 4. Ссылка на конструктор  Например:  Function<String, Integer> function = (d) -> new Integer(d);  System.out.println(function.apply("4"));  Перепишем:  Function<String, Integer> function = Integer::new; System.out.println(function.apply("4")); www.examclouds.com
  76. 76. Задание 10  Перепишите используя method references:  Supplier<String> newString = () -> new String();  System.out.println(newString.get()); www.examclouds.com
  77. 77. • Лекции, задания, видео, тесты и вопросы на: • https://www.examclouds.com/ru/java/java-core- russian/lesson15 • Подписывайтесь на страницу: • https://www.facebook.com/Examclouds • Подписывайтесь на канал • https://www.youtube.com/c/tatyanamilkina www.examclouds.com

×