10. Lambdas
variable capture
10.1. Functional interface
1interface IntegerTest {
2 boolean test(int n);
3}
1IntegerTest isEven = (n) -> n % 2 == 0;
2
3var numbers = new Integer[] { 1, 2, 3, 4, 5 };
4for (var num : numbers) {
5 System.out.println(isEven.test(num));
6}
10.2. Generic functional interface
1interface NumberFormatter<T extends Number> {
2 String format(T num);
3}
1NumberFormatter formatter = (num) -> String.format("%.3f", num);
2
3var data = new Double[] { 1.22222, 3.44444, 5.823432 };
4for (var num : data) {
5 System.out.println(formatter.format(num));
6}
10.3. Block lambda
1interface StringMerger {
2 String f(String ... items);
3}
1StringMerger classicMerger = (items) -> {
2 String s = "";
3 for (int i = 0; i < items.length; i++) {
4 s += items[i];
5 if (i < items.length - 1) {
6 s += ",";
7 }
8 }
9 return s;
10};
11
12StringMerger sbMerger = (items) -> {
13 StringBuilder sb = new StringBuilder();
14 for (int i = 0; i < items.length; i++) {
15 sb.append(items[i]);
16 if (i < items.length - 1) {
17 sb.append(',');
18 }
19 }
20 return sb.toString();
21};
22
23StringMerger backwardMerger = (items) -> {
24 String s = "";
25 for (int i = items.length - 1; i >= 0; i--) {
26 s += items[i];
27 if (i > 0) {
28 s += ",";
29 }
30 }
31 return s;
32};
33
34var tokens = new String[] { "John", "Jack", "Jake", "Joe" };
35
36System.out.println(classicMerger.f(tokens));
37System.out.println(sbMerger.f(tokens));
38System.out.println(backwardMerger.f(tokens));
10.4. Lambda as argument
1interface MathFunc {
2 int doIt(int v1, int v2);
3}
4
5static int mathOp(MathFunc f, int v1, int v2) {
6 return f.doIt(v1, v2);
7}
1MathFunc add = (v1, v2) -> v1 + v2;
2MathFunc sub = (v1, v2) -> v1 - v2;
3MathFunc mul = (v1, v2) -> v1 * v2;
4MathFunc div = (v1, v2) -> v1 / v2;
5
6System.out.println(mathOp(add, 10, 8));
7System.out.println(mathOp(sub, 10, 8));
8System.out.println(mathOp(mul, 10, 8));
9System.out.println(mathOp(div, 10, 8));
10.5. Variable capture
1interface StringOp {
2 String f(String s);
3}
1final int max = 10;
2StringOp op = (s) -> {
3 StringBuilder sb = new StringBuilder();
4 for (int i = 0; i < max; i++) {
5 sb.append(s);
6 if (i < max - 1) {
7 sb.append(',');
8 }
9 }
10 return sb.toString();
11};
12
13System.out.println(op.f("dog"));
14System.out.println(op.f("cat"));
10.6. Predefined functional interfaces
1import java.util.function.BinaryOperator;
2import java.util.function.Consumer;
3import java.util.function.Function;
4import java.util.function.Predicate;
5import java.util.function.Supplier;
6import java.util.function.UnaryOperator;
1UnaryOperator<Integer> addOne = a -> a + 1;
2System.out.println(addOne.apply(3));
3
4BinaryOperator<Integer> add = (a, b) -> a + b;
5System.out.println(add.apply(1, 2));
6
7Consumer<Integer> print = a -> System.out.println(a);
8print.accept(3);
9
10Supplier<Double> next = () -> Math.random();
11System.out.println(next.get());
12
13Function<Double[], Double> sum = (numbers) -> {
14 double s = 0.0d;
15 for (int i = 0; i < numbers.length; i++) {
16 s += numbers[i];
17 }
18 return s;
19};
20System.out.println(sum.apply(new Double[] { 1.0, 2.0, 3.0 }));
21
22Predicate<Integer> isEven = a -> a % 2 == 0;
23System.out.println(isEven.test(3));