转载请注明出处:https://www.cnblogs.com/zhizaixingzou/p/10024036.html
目录
1. Lambda表达式
1.1. 实例
接口定义中只能有一个方法。
1 package com.cjw.knowledge.demo; 2 3 public interface MathOperator { 4 int operate(int a, int b); 5 }
使用Lambda表达式可以免去使用匿名类的麻烦,且提供了函数式编程的能力。
1 package com.cjw.knowledge.demo; 2 3 public class Demo { 4 public static void main(String[] args) { 5 MathOperator adder = (int a, int b) -> a + b; 6 System.out.println("3 + 5 = " + adder.operate(3, 5)); 7 } 8 }
等价于:
1 System.out.println("3 + 5 = " + ((MathOperator)((int a, int b) -> a + b)).operate(3, 5));
运行的结果如下。
Lambda表达式的语法格式如下:
(parameters) -> expression;
或者
(parameters) -> {statement;}
参数的类型可以不写,编译器可以推断出来。
如果参数只有一个,则参数可不括号括起来,但零个或多个参数需要。
如果主体只有一条语句或者为一个表达式,则可以不写大括号。
1.2. Lambda表达式的定义
Lambda表达式是Java 8最重要的特性。它可以作为方法的参数使用,使得代码更加简洁紧凑,为函数式编程的特征。
Lambda表达式是一个对象,它必须赋给一个函数式接口,这种接口可以通过@FunctionalInterface显式指明,它只能有一个方法。
Lambda表达式访问的外部变量必须是final修饰的。当然也可以不用final修饰,但一旦为Lambda表达式使用,则必须不能被修改,否则编译不过。
Lambda表达式中不许声明一个与外部变量同名的参数或局部变量。
将常规方法转换为Lambda表达式。
1 public class Demo { 2 public static void main(String[] args) { 3 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); 4 list.forEach(n -> System.out.println(n)); 5 6 list.forEach(System.out::println); 7 } 8 }
1 package com.cjw.knowledge.demo; 2 3 import java.util.Arrays; 4 import java.util.List; 5 import java.util.function.Predicate; 6 7 public class Demo { 8 public static void main(String[] a) { 9 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); 10 System.out.println("Print all numbers:"); 11 evaluate(list, (n) -> true); 12 13 System.out.println("Print no numbers:"); 14 evaluate(list, (n) -> false); 15 16 System.out.println("Print even numbers:"); 17 evaluate(list, (n) -> n % 2 == 0); 18 19 System.out.println("Print odd numbers:"); 20 evaluate(list, (n) -> n % 2 == 1); 21 22 System.out.println("Print numbers greater than 5:"); 23 evaluate(list, (n) -> n > 5); 24 } 25 26 public static void evaluate(List<Integer> list, Predicate<Integer> predicate) { 27 for (Integer n : list) { 28 if (predicate.test(n)) { 29 System.out.print(n + " "); 30 } 31 } 32 System.out.println(); 33 } 34 }
1 package com.cjw.knowledge.demo; 2 3 import java.util.Arrays; 4 import java.util.List; 5 6 public class Demo { 7 public static void main(String[] a) { 8 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7); 9 list.stream().map((x) -> x * x).forEach(System.out::println); 10 System.out.println(list.stream().map(x -> x * x).reduce((x, y) -> x + y).get()); 11 } 12 }
对于匿名类,关键词 this 解读为匿名类,而对于 Lambda 表达式,关键词 this 解读为写就 Lambda 的外部类。
1.3. 几种常见的Lambda表达式接口
1 package com.cjw.knowledge.demo; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.List; 6 import java.util.function.Consumer; 7 import java.util.function.Function; 8 import java.util.function.Predicate; 9 import java.util.function.Supplier; 10 11 public class Demo { 12 // 消费型接口 13 public static void donate(Integer money, Consumer<Integer> consumer) { 14 consumer.accept(money); 15 } 16 17 // 供给型接口 18 public static Integer supply(Supplier<Integer> supplier) { 19 return supplier.get(); 20 } 21 22 // 函数型接口 23 public static Integer convert(String str, Function<String, Integer> function) { 24 return function.apply(str); 25 } 26 27 // 断言型接口 28 public static List<String> filter(List<String> fruits, Predicate<String> predicate) { 29 List<String> f = new ArrayList<>(); 30 for (String s : fruits) { 31 if (predicate.test(s)) { 32 f.add(s); 33 } 34 } 35 return f; 36 } 37 38 public static void main(String[] args) { 39 donate(1000, money -> System.out.println("捐款: " + money + "元")); 40 41 Integer integer = supply(() -> (int) (Math.random() * 100)); 42 43 Integer value = convert("28", x -> Integer.parseInt(x)); 44 45 List<String> fruits = Arrays.asList("香蕉", "哈密瓜", "榴莲", "火龙果", "水蜜桃"); 46 List<String> newFruit = filter(fruits, (f) -> f.length() == 2); 47 } 48 }