💕"我不要麻木的死去"💕
作者:Mylvzi
文章主要内容:Java中lambda表达式的使用
一.背景
lambda表达式是Java SE 8中一个重要的新特性,允许你使用一个表达式来代替功能接口。lambda表达式可以看作一个没有返回值,没有修饰符修饰的方法,它具有参数和这些参数的主体(方法体)Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure)
二.语法
1.基本语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements};
- parameters:类似于方法中的形参列表,参数来源于函数式接口的参数
- ->:可以理解为"被用于"
- expression :方法体 可以是一条语句也可以是多条语句
2.函数式接口
函数式接口就是只含有一条抽象方法的接口
如果接口上声明了@FunctionalInterface,那么编译器就会按照函数式接口进行检验,也即此接口内部只能有一个抽象方法,但是可以使用default来添加一个非抽象方法
@FunctionalInterface interface FuncInterface1 { void test(); } // 这样也是可以的 @FunctionalInterface interface FuncInterface2 { void test(); default void test2(){ System.out.println("==="); } }
三.lambda表达式的基本使用
lambda表达式就相当于使用一种更简单的方式重写了抽象方法(相比于使用匿名内部类)
以下所有情况的实现方式都有两种,lambda表达式和匿名内部类
1.无返回值,无参数
//无返回值无参数 @FunctionalInterface interface NoParameterNoReturn { void test(); }
使用两种方式实现
// 使用lambda表达式重写函数式接口的抽象方法 参数 方法体 NoParameterNoReturn noParameterNoReturn1 = () -> System.out.println("hello1"); noParameterNoReturn1.test();// 输出hello1 // 使用匿名内部类重写函数式接口的抽象方法 NoParameterNoReturn noParameterNoReturn2 = new NoParameterNoReturn() { @Override public void test() { System.out.println("hello2"); } };
2.无返回值,一个参数
//无返回值一个参数 @FunctionalInterface interface OneParameterNoReturn { void test(int a); }
使用两种方式实现
// 使用lambda表达式 OneParameterNoReturn oneParameterNoReturn = (x) -> System.out.println(x); oneParameterNoReturn.test(10);// 打印10 // 使用匿名内部类 OneParameterNoReturn oneParameterNoReturn1 = new OneParameterNoReturn() { @Override public void test(int a) { System.out.println(a); } };
注意:当参数只有一个或者方法体只有一句时,可以省略外面的();
3.无返回值多个参数
//无返回值多个参数 @FunctionalInterface interface MoreParameterNoReturn { void test(int a,int b); }
使用两种方式实现
// 使用lambda表达式 MoreParameterNoReturn moreParameterNoReturn = (x,y) -> System.out.println(x+y); moreParameterNoReturn.test(10,20);// 输出30 // 使用匿名内部类 MoreParameterNoReturn moreParameterNoReturn1 = new MoreParameterNoReturn() { @Override public void test(int a, int b) { System.out.println(a+b); } };
4.有返回值无参数
//有返回值无参数 @FunctionalInterface interface NoParameterReturn { int test(); }
使用两种方式实现
NoParameterReturn noParameterReturn = () -> {return 10;}; System.out.println(noParameterReturn.test());// 输出10 // 简化 NoParameterReturn noParameterReturn1 = () ->10; System.out.println(noParameterReturn1.test());// 输出10 // 使用匿名内部类 NoParameterReturn noParameterReturn2 = new NoParameterReturn() { @Override public int test() { return 10; } };
5.有返回值一个参数
//有返回值一个参数 @FunctionalInterface interface OneParameterReturn { int test(int a); }
使用两种方式实现
OneParameterReturn oneParameterReturn = (x) -> {return x*x;}; System.out.println(oneParameterReturn.test(10));// 输出100 // 简化 OneParameterReturn oneParameterReturn1 = x -> x*x; System.out.println(oneParameterReturn1.test(10));// 输出100 // 使用匿名内部类 OneParameterReturn oneParameterReturn2 = new OneParameterReturn() { @Override public int test(int a) { return a*a; } };
6.有返回值多参数
@FunctionalInterface interface MoreParameterReturn { int test(int a,int b); }
使用两种方式实现
MoreParameterReturn moreParameterReturn = (x,y) -> {return x+y;}; System.out.println(moreParameterReturn.test(10, 20));// 输出30 // 使用匿名内部类 MoreParameterReturn moreParameterReturn1 = new MoreParameterReturn() { @Override public int test(int a, int b) { return a+b; } };
以上就是lambda表达式的基本使用
四.变量捕获
1.什么是变量捕获
变量捕获:在一个内部作用域内(lambda表达式,匿名内部类等)中引用外部作用域(方法,类)的变量
2.捕获的方式
当在内部作用域内引用外部作用域的变量时,Java会在内部作用域内对引用的变量进行拷贝/引用
3.匿名内部类的变量捕获
匿名内部类就是没有名字的类,往往用于接口的实现,下面使用一个简单的匿名内部类来实现
class Demo { public void func() { System.out.println("hello"); } } public class Demo10 { public static void main(String[] args) { new Demo() { @Override public void func() { System.out.println("hello Demo"); } }; } }
如果在匿名内部类中进行变量的捕获
1.局部变量 且没有被修改过
2.局部变量 但是被修改
可以发现,如果对A进行修改就会报错
这也是变量捕获的一个要求,即:
在内部作用域内捕获的变量(使用的变量)只能是被final修饰的或者从来没有被修改过的(被final修饰就代表无法改变)
如果你传入的变量并没有被final修饰,则系统会强制要求你传入的变量不能被修改!!!
Java中lambda表达式的使用(二)+https://developer.aliyun.com/article/1413559