Для работы я сделал презентацию о лямбда-проекте Java 8 и, конечно же, о простом коде, иллюстрирующем некоторые моменты. Общие причины для Java 8:
- Более краткий код (для классов, которые имеют только один метод и коллекции). «Мы хотим, чтобы читатель кода прошел через как можно меньший синтаксис, прежде чем достигнуть« мяса »лямбда-выражения». — Брайан Гетц (http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html)
- Возможность передавать функциональность, а не только данные
- Лучшая поддержка многоядерной обработки
Все примеры работают на следующей версии Java 8, загруженной отсюда :
|
1
2
3
|
openjdk version "1.8.0-ea"OpenJDK Runtime Environment (build 1.8.0-ea-lambda-nightly-h3876-20130403-b84-b00)OpenJDK 64-Bit Server VM (build 25.0-b21, mixed mode) |
Самый простой случай:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public class ThreadA { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.err.println("Hello from anonymous class"); } }).start(); }} |
|
01
02
03
04
05
06
07
08
09
10
|
public class ThreadB { public static void main(String[] args) { new Thread(() -> { System.err.println("Hello from lambda"); }).start(); }} |
Обратите внимание на синтаксис, неофициально как
|
1
|
()|x|(x,..,z) -> expr|stmt |
Стрелка является новым оператором. И обратите внимание на краткость второго фрагмента кода по сравнению с более громоздким первым фрагментом.
Коллекции:
Сначала позвольте мне представить простой домен и несколько помощников
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public class Something { private double amount; public Something(double amount) { this.amount = amount; } public double getAmount() { return amount; } public String toString() { return "Amount: " + amount; }}public class Helper { public static List<Something> someThings() { List<Something> things = new ArrayList<>(); things.add(new Something(99.9)); things.add(new Something(199.9)); things.add(new Something(299.9)); things.add(new Something(399.9)); things.add(new Something(1199.9)); return things; }}public interface Doer<T> { void doSomething(T t);} |
Давайте немного отфильтруем и отсортируем стиль Java 7:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public class CollectionA { public static void main(String... args) { List<Something> things = Helper.someThings(); System.err.println("Filter"); List<Something> filtered = filter(things); System.err.println(filtered); System.err.println("Sum"); double sum = sum(filtered); System.err.println(sum); } public static List<Something> filter(List<Something> things) { List<Something> filtered = new ArrayList<>(); for (Something s : things) { if (s.getAmount() > 100.00) { if (s.getAmount() < 1000.00) { filtered.add(s); } } } return filtered; } public static double sum(List<Something> things) { double d = 0.0; for (Something s : things) { d += s.getAmount(); } return d; }} |
А теперь стиль Java 8 — потоковое :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
import java.util.stream.Collectors;public class CollectionB { public static void main(String... args) { List<Something> things = Helper.someThings(); System.err.println("Filter lambda"); List<Something> filtered = things.stream().parallel().filter( t -> t.getAmount() > 100.00 && t.getAmount() < 1000.00).collect(Collectors.toList()); System.err.println(filtered); System.err.println("Sum lambda"); double sum = filtered.stream().mapToDouble(t -> t.getAmount()).sum(); System.err.println(sum); }} |
Импорт java.util.function. * Интерфейсы и ссылки на методы
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class CollectionC { public static void main(String... args) { List<Something> things = Helper.someThings(); System.err.println("Do something"); doSomething(things, new Doer<Something>() { @Override public void doSomething(Something t) { System.err.println(t); } }); } public static void doSomething(List<Something> things, Doer<Something> doer) { for (Something s : things) { doer.doSomething(s); } }} |
Замените наш интерфейс Doer на стандартный интерфейс Consumer (ранее известный как Block)
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
import java.util.function.Consumer;public class CollectionD { public static void main(String... args) { List<Something> things = Helper.someThings(); System.err.println("Do something functional interfaces"); consumeSomething(things, new Consumer<Something>() { @Override public void accept(Something t) { System.err.println(t); } }); System.err.println("Do something functional interfaces, using lambda"); consumeSomething(things, (t) -> System.err.println(t)); System.err.println("Do something functional interfaces, using lambda method reference (new operator ::) "); consumeSomething(things, System.err::println); System.err.println("Do something functional interfaces, using stream"); things.stream().forEach(new Consumer<Something>() { @Override public void accept(Something t) { System.err.println(t); } }); System.err.println("Do something functional interfaces, using stream and method reference"); things.stream().forEach(System.err::println); } public static void doSomething(List<Something> things, Doer<Something> doer) { for (Something s : things) { doer.doSomething(s); } } public static void consumeSomething(List<Something> things, Consumer<Something> consumer) { for (Something s : things) { consumer.accept(s); } }} |
Карта, уменьшить, ленивый и необязательно
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import java.util.List;import java.util.NoSuchElementException;import java.util.Optional;import java.util.stream.Collectors;public class Various { public static void main(String... args) { List<Something> things = Helper.someThings(); //Map System.err.println(things.stream().map((Something t) -> t.getAmount()).collect(Collectors.toList())); //Reduce double d = things.stream().reduce(new Something(0.0), (Something t, Something u) -> new Something(t.getAmount() + u.getAmount())).getAmount(); System.err.println(d); //Reduce again System.err.println(things.stream().reduce((Something t, Something u) -> new Something(t.getAmount() + u.getAmount())).get()); //Map/reduce System.err.println(things.stream().map((Something t) -> t.getAmount()).reduce(0.0, (x, y) -> x + y)); //Lazy Optional<Something> findFirst = things.stream().filter(t -> t.getAmount() > 1000).findFirst(); System.err.println(findFirst.get()); //Lazy no value Optional<Something> findFirstNotThere = things.stream().filter(t -> t.getAmount() > 2000).findFirst(); try { System.err.println(findFirstNotThere.get()); } catch (NoSuchElementException e) { System.err.println("Optional was not null, but its value was"); } //Optional one step deeper things.stream().filter(t -> t.getAmount() > 1000).findFirst().ifPresent(t -> System.err.println("Here I am")); }} |
Ссылка: Java 8 лямбда-прохождение от нашего партнера JCG