4. Чем ФП приятно?Чем ФП приятно?
Функция не может поменять значение переменной вне
своей видимости, все переменные final (рай для юнит
тестов)
Внешние состояние не влияет на функцию (удобно
отлаживать и замещать части кода).
Встроенная многопоточность (кому нравится думать
про «разделяй и властвуй?»)
Ленивые (отложенные) вычисления - выполняется
только нужный код в момент, когда надо результат.
5. Чем ФП чревато?Чем ФП чревато?
Состояние не хранится (нет переменных)
Все переменные final или const, нет public (как вам
код с такими ограничениями?)
Встроенная многопоточность (к сожалению пока не
на высшем уровне)
Ленивые (отложенные) вычисления - выполняется
только используемый код в «когда захочу» момент.
Тяжело контролировать очередность действий.
9. КАК делаем -> ЧТОКАК делаем -> ЧТО
делаем?делаем?
Imperative style:
public boolean isPrime(int number) {
for (int curNumb = 2; curNumb <= number/2; curNumb++) {
if (number % curNumb == 0) {
return false;
}
}
return true;
}
DECLARATIVE STYLE:
public boolean isPrimeDeclarative(final int number) {
return IntStream.rangeClosed(2, number/2)
.noneMatch(curNumb -> number % curNumb == 0);
}
10. Добавим проверку наДобавим проверку на
знак числазнак числа
public boolean isPrimeImperative(int number) {
if (number < 0) {
return false;
}
for (int curNumb = 2; curNumb <= number / 2; curNumb++) {
if (number % curNumb == 0) {
return false;
}
}
return true;
}
public boolean isPrimeDeclarativeNegativeNumbCheck(final int number) {
return number >= 0 && IntStream.rangeClosed(2, number.2)
.noneMatch(curNumb -> number % curNumb == 0);
}
11. Ну… надо бы еще наНу… надо бы еще на
что-то посмотретьчто-то посмотреть
12. Кого на собеседовании неКого на собеседовании не
просили посчитать факториал?просили посчитать факториал?
public static int factorialOf(int number) {
if (number >= 0) {
int factorial = 1;
for (int curNumb = 2; curNumb <= number; curNumb++){
factorial = factorial * curNumber;
}
return factorial;
} else throw new IllegalArgumentException("Factorial can be counted only
of not negative numbers.");
}
6 строчек!
13. public static int factorialOf(int number) {
if (number > 0) return number*factorialOf(number-1);
if (number == 0) return 1;
else throw new IllegalArgumentException("Factorial can be counted only of not
negative numbers.");
}
3 строчки!
Факториал через цикл каждыйФакториал через цикл каждый
напишет. А рекурсия во чтонапишет. А рекурсия во что
обойдется?обойдется?
public static int factorialOf(int number) {
if (number >= 0)
return IntStream.rangeClosed(2, number)
.reduce(1, (accResult, curNumb) -> accResult * curNumb);
else throw new IllegalArgumentException("Factorial can be counted only of not negative
numbers.");
}
3 строчки!
14. – Я и многие другие
“Не делайте что-то только потому, что вы
можете это сделать. Делайте красиво.”
15. Chuck Norris can do multipleChuck Norris can do multiple
inheritance in Javainheritance in Java
16. Я скажу вамЯ скажу вам
больше, не толькобольше, не только
он может. Вы тоже!он может. Вы тоже!
С помощьюС помощью
интерфейсов,интерфейсов,
правда.правда.
17. А что если бы Cлон был Моськой, аА что если бы Cлон был Моськой, а
Моська Cлоном?Моська Cлоном?
interface Elephant {
default String makeSound(String name) {
return name + ": Не злите меня!";
}
}
interface Dog {
default String makeSound(String name) {
return name + ": Гав-гав";
}
}
18. class EveryDogWantsToBeAnElephant implements Dog, Elephant {
@Override
public String makeSound(String name) {
return name + ": Я спокоен";
}
public static void main(final String[] args) {
EveryDogWantsToBeAnElephant elephantDog = new
EveryDogWantsToBeAnElephant();
Elephant e = new Elephant(){};
Dog d = new Dog(){};
System.out.println(e.makeSound("Слон"));
System.out.println(d.makeSound("Моська"));
System.out.println(elephantDog.makeSound("Моська-слон"));
}}
А что если бы Cлон был Моськой, аА что если бы Cлон был Моськой, а
Моська Cлоном?Моська Cлоном?
СлонСлон: Не злите меня!: Не злите меня!
МоськаМоська: Гав-гав: Гав-гав
МоськаМоська--слонслон: Я спокоен: Я спокоен
19. Множественное наследование - это когда
есть дефолтная реализация метода с
одинаковым названием в каждом
интерфейсе.
А как себя будут вести статические и
абстрактные методы?
20. Статические методыСтатические методы
К ним мы обращаемся как
НазваниеКласса.имяМетода. По
сути эта комбинация всегда
уникальна и ее можно
воспринимать целиком, как
название
interface Dog {
static String walk() {
return "Я бегаю быстренько своими
маленькими лапками.»;
}}
interface Elephant {
static String walk() {
return "Я большой и ступаю тихо но тяжело.";
}}
——————————————————————
———————————————
System.out.println(Elephant.walk());
System.out.println(Dog.walk());
OUTPUT:
Я большой и ступаю тихо но тяжело.
Я бегаю быстренько своими маленькими
лапками.
21. Абстрактные методыАбстрактные методы
Когда мы инстанциируем абстрактный класс
(интерфейс), то надо реализовать все абстрактные
методы.
Но если мы имплементируем интерфейсы с
одинаковыми названиями методов, достаточно
описать только один из них.
22. Пример: Comparator с его int compare(T o1, T o2),
Comparable с его int compareTo(T o)
и другие
Интерфейс, у которого есть только один
абстрактный метод называется
функциональным интерфейсом
23. 1. Можно по-старинке:
Elephant e = new Elephant() {
@Override
public boolean isProud() {
return false;
}
};
2. Можно по-модному:
Elephant e = () -> { return false; };
3. А можно без лишних слов:
Elephant e = () -> false;
Реализуем функциональныйРеализуем функциональный
интерфейсинтерфейс
24. interface Elephant {
boolean isProud();
}
interface Dog {
boolean isProud();
}
System.out.println("Слон горделив: " + e.isProud());
System.out.println("Моська горделива: " + d.isProud());
System.out.println("Моська-слон горделив: " + elephantDog.isProud());
OUTPUT:
Слон горделив: false
Моська горделива: true
Моська-слон горделив: false
Функциональный интерфейсФункциональный интерфейс
вызываем точно так жевызываем точно так же
26. ПредикатыПредикаты
1. Обычный предикат:
public Predicate<Integer> isGreaterThan2New() {
return a -> a > 2;
}
Как это выглядело раньше:
public boolean isGreaterThan2Old(Integer a) {
return a > 2;
}
2. Обычный би-предикат:
public BiPredicate<Integer, Integer> isGreaterThanFunc() {
return (a, b) -> a > b;
}
Как это выглядело раньше:
public boolean isGreaterThan(Integer a, Integer b) {
return a > b;
}
ВсегдаВсегда
возвращаютвозвращают
булеан,булеан,
реализуютреализуют
интерфейс синтерфейс с
методомметодом
booleanboolean testtest((TT t)t);;
Если реализуется метод boolean test(T t),Если реализуется метод boolean test(T t),
почему нигде нет этого названия?почему нигде нет этого названия?
28. ФункцииФункции
1. Обычный предикат:
public Function<Integer, Integer> multiplyFuncBy2() {
return (a) -> a * 2;
}
Как это выглядело раньше:
public Integer multiplyBy2(Integer a) {
return a * 2;
}
2. Обычный би-предикат:
public BiFunction<Integer, Integer, Integer> multiplyFuncBy() {
return (a, b) -> a * b;
}
Как это выглядело раньше:
public Integer multiplyFuncBy(Integer a, Integer b) {
return a * b;
}
В отличие отВ отличие от
предикатов,предикатов,
возвращают тип,возвращают тип,
указанный науказанный на
последнем месте ипоследнем месте и
принимает типы,принимает типы,
указанные вначалеуказанные вначале
29. Как применяемКак применяем
предикатыпредикаты
1. Обычный и би-предикат, аналогичные методы:
boolean actual = p.isGreaterThan2New().test(4);
boolean actual = p.isGreaterThan2Old(4);
p.isGreaterThanNew().test(4, 8);
p.isGreaterThanOld(4, 8);
2. Предикат и соответствующий метод в стриме:
values.stream().filter(p.isGreaterThan2New( ))
.collect(Collectors.toList());
List<Integer> actual = values.stream()
.filter(v ->
p.isGreaterThan2(v)).collect(Collectors.toList());
Нету параметра.Нету параметра.
Стрим самСтрим сам
передает.передает.
30. Как применяемКак применяем
функции?функции?
1. Обычная и би-функция, аналогичные методы:
int actual = f.multiplyFuncBy2().apply(5);
int actual = f.multiplyBy2(5);
f.multiplyFuncBy().apply(5, 3);
f.multiplyBy(5, 3);
2. Функция и соответствующий метод в стриме:
values.stream().map(f.multiplyFuncBy2()).skip(2).limit(2).collect(
Collectors.toList());
List<Integer> actual = values.stream()
.map(v -> f.multiplyFuncBy().apply(v, 3))
.skip(2).limit(2).collect(Collectors.toList());
Параметр передаетсяПараметр передается
через apply()через apply()
36. Это совсем не все,Это совсем не все,
но основное, чтоно основное, что
надо знать о Javaнадо знать о Java
Тут код с презентации и слайды
https://github.com/olexandra-dmytrenko/LambdasForConfs.git