lambda表达式
笔记来自于宋红康老师
举例
(o1,o2) -> Integer.compare(o1,o2);
格式
-
->:lambda操作符 或 箭头操作符
-
-> 左边:lambda 的形参列表 (其实就是接口中的抽象方法的形参列表)
-
-> 右边:lambda体 (其实就是重写抽象方法的方法体)
lambda表示式的使用: (六种情况)
//语法格式1:无参,无返回值的 @Test public void test1() { Runnable r1 = () -> System.out.println("我爱北京故宫"); r1.run(); } //语法格式2:需要一个参数,但是没有返回值 @Test public void test2() { Consumer<String> con = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }; con.accept("谎言和誓言的区别是什么呢?"); System.out.println("*************************************"); Consumer<String> con1 = (String s) -> { System.out.println(s); }; con1.accept("一个是听得人当真了,一个是说的人当真了"); } //语法格式三:数据类型可以省略,因为编译器可以推断得出,称为类型推断 @Test public void test3() { Consumer<String> con1 = (String s) -> { System.out.println(s); }; con1.accept("一个是听得人当真了,一个是说的人当真了"); System.out.println("*********************************"); Consumer<String> con2 = (s) -> { System.out.println(s); }; con2.accept("一个是听得人当真了,一个是说的人当真了"); } //语法格式四:lambda 若只需要一个参数时,参数的小括号也可以省略 @Test public void test4() { Consumer<String> con2 = s -> { System.out.println(s); }; con2.accept("一个是听得人当真了,一个是说的人当真了"); } //语法格式五:lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值 @Test public void test5() { Comparator<Integer> com1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { System.out.println(o2); System.out.println(o1); return o1.compareTo(o2); } }; System.out.println(com1.compare(12, 21)); System.out.println("*****************************"); Comparator<Integer> com2 = (o1, o2) -> { System.out.println(o2); System.out.println(o1); return o1.compareTo(o2); }; System.out.println(com2.compare(12, 6)); } //语法格式六:当lambda 体只有一条语句时,return 与大括号若有,都可以省略 @Test public void test6() { Comparator<Integer> com1 = (o1, o2) -> { return o1.compareTo(o2); }; System.out.println(com1.compare(12, 6)); System.out.println("*********************"); Comparator<Integer> com2 = (o1, o2) -> o1.compareTo(o2); System.out.println(com2.compare(12, 21)); } @Test public void test7() { Consumer<String> con1 = s -> { System.out.println(s); }; con1.accept("一个是人听得人当真了,一个是说的人当真了"); System.out.println("*****************************"); Consumer<String> con2 = s -> System.out.println(s); con2.accept("一个是人听得人当真了,一个是说的人当真了"); }
-
总结:
-
->左边:lambda形参列表的参数类型可以省略(类型推断);如果参数列表只有一个参数,其一对小括号()可以省略;
-
->右边:lambda体应该使用一对大括号{}包裹,如果lambda体,只有一条执行语句(有可能是return语句),可以省略一对大括号{},以及return关键字
lambda表达式的本质
-
作为函数式接口的实现
函数式接口(Fuctional)
-
只包含一个抽象方法的接口,就称为函数式接口
-
你可以通过Lambda表达式来创建该接口的对象
-
我们可以在一个接口上使用 @FunctionalInterface注解,这样可以检查他是否是一个函数式接,同时 javadoc 也会包含一条声明,说明该接口是一个函数式接口
-
在 java.util.function 包下定义了Java8的丰富的函数式接口
-
所以以前用匿名实现类表示的现在都可以用lambda表达式来写
Java内置四大核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer<T>消费型接口 | T | void | 对类型T的对象应用操作,包含方法: void accept(T t) |
Supplier<T>供给型接口 | 无 | T | 返回类型为 T的对象,包含方法: T get() |
Function<T,R>函数型接口 | T | R | 对于类型为 T 的对象应用操作,并返回结果,结果是 R 类型的对象,包含方法: R apply(T t) |
Predicate<T>断定型接口 | T | boolean | 确定类型为 T 的对象满足某约束,并返回 boolean 值,包含方法: boolean test(T t) |