1、如何使用 lambda表达式
1.1 lambda语法
1 2
| (paramters) -> expression 或 (parameters) ->{ expressions; }
|

具体解释,如上图。此外,lambda 语法注意点:
- 可选类型声明:方法参数不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但无参数或多个参数需要定义圆括号。
- 可选的大括号:如果具体实现方法只有一个语句,就不需要使用中括号{}。
- 可选的返回关键字:如果具体实现方法只有一个表达式,则编译器会自动返回值,如果有多个表达式则,中括号需要指定明表达式返回了一个数值。
具体使用示例:
1 2 3 4 5 6 7 8 9 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 50 51 52 53 54 55
| public class Example {
public interface Hello { String hi(); }
public interface Hello2 { String hei(String hello); }
public interface Hello3 { String greet(String hello, String name); }
public static void main(String[] args) {
Hello no_param = () -> "hi, no param"; Hello no_param2 = () -> { return "hi, no param"; }; System.out.println(no_param.hi()); System.out.println(no_param2.hi());
Hello2 param = name -> name; Hello2 param2 = name -> { return name; };
System.out.println(param.hei("hei, 一个优秀的废人")); System.out.println(param2.hei("hei, 一个优秀的废人"));
Hello3 multiple = (String hello, String name) -> hello + " " + name;
Hello3 multiple2 = (hello, name) -> hello + name;
Hello3 multiple3 = (hello, name) -> { System.out.println(" 进入内部 "); return hello + name; };
System.out.println(multiple.greet("hello,", "祝2019暴富")); System.out.println(multiple2.greet("hello,", "祝2019暴富")); System.out.println(multiple3.greet("hello,", "祝2019暴富")); } }
|
2、 方法引用
1 2 3 4 5 6
| Consumer<String> sc = System.out::println; sc.accept("一个优秀的废人");
Consumer<String> sc2 = (x) -> System.out.println(x); sc2.accept("一个优秀的废人");
|
Consumer 函数式接口源码:
1 2 3 4
| @FunctionalInterface public interface Consumer<T> { void accept(T t); }
|
分析一波:Consumer 是一个函数式接口,抽象方法是 void accept(T t),参数都是 T。那我们现在有这样一个需求,我想利用这个接口的抽象方法,做一下控制台打印。正常情况下,我们需要实现这个接口,实现它的抽象方法,来实现这个需求:
1 2 3 4 5 6
| public class ConsumerImpl implements Consumer<String> { @Override public void accept(String s) { System.out.println(s); } }
|
实现之后,这个抽象方法变具体了。作用就是控制台打印,那就意味着抽象方法刚好可以用实际方法: System.out.println(s) 来实现,所以我们可以使用方法引用。
总结:函数式接口的抽象方法实现恰好可以通过调用一个实际方法来实现时,就可以用方法引用。
方法引用的三种形式:
1 2 3 4 5 6
| 对象::实例方法 objectName::instanceMethod
类::静态方法 ClassName::staticMethod
类::实例方法 ClassName::instanceMethod
|
自定义一个方法类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Method { public static void StaticMethod(String name) { System.out.println(name); }
public void InstanceMethod(String name) { System.out.println(name); }
public Method() { }
public Method(String methodName) { System.out.println(methodName); } }
|
测试用例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class MethodExample {
public static void main(String[] args) {
Consumer<String> consumerStatic = Method::StaticMethod; consumerStatic.accept("静态方法"); Consumer<String> consumerStatic2 = (x) -> Method.StaticMethod(x); consumerStatic2.accept("静态方法");
System.out.println("--------------------------"); Method method = new Method(); Consumer<String> consumerInstance = method::InstanceMethod; consumerInstance.accept("对象的实例方法"); Consumer<String> consumerInstance2 = (x) -> method.InstanceMethod(x); consumerInstance2.accept("对象的实例方法");
System.out.println("--------------------------"); BiPredicate<String, String> sbp = String::equals; System.out.println("类的实例方法 " + sbp.test("a", "A")); BiPredicate<String, String> sbp2 = (x, y) -> x.equals(y); System.out.println("类的实例方法 " + sbp2.test("a", "A")); } }
|
输出结果:
1 2 3 4 5 6 7 8
| 静态方法 静态方法 -------------------------- 对象的实例方法 对象的实例方法 -------------------------- 类的实例方法false 类的实例方法false
|