我们都知道在Java8中引入了许多新特性,Lambda表达式,下面就Lambda表达式给大家介绍一下。
一、什么是Lambda表达式?
从java8出现以来lambda是最重要的特性之一,它可以让我们用简洁流畅的代码完成一个功能。 很长一段时间java被吐槽是冗余和缺乏函数式编程能力的语言,随着函数式编程的流行java8种也引入了 这种编程风格,lambda表达式是一段可以传递的代码,它的核心思想是将面向对象中的传递数据变成传递行为。
二、Lambda表达式的语法及表达形式
Lambda表达式具有以下语法限制
1.不能有函数名,代表匿名类
2. 代表函数式接口实例
3. 返回值类型由编译器“推测”
4. 不能出现泛型,泛型定义在函数式接口中
5. 表达式内变量必须是final,不能在表达式内修改。或者显示定义为final,或
者“effectively final“变量,即默认final(local-non-final-initialized-only-once )
6. 没有自己的作用域,this或super指向lambda表达式外部
7. 表达式内部可以使用break, continue, return和throw等
表达形式
基本格式:
匿名函数 = (argument) -> (body)
常用几种写法如下:
在这里插入代码片() -> {} // void
() -> 42 // 表达式
() -> { return 42; } // 有返回值,函数体块
() -> { System.gc(); } // ⽆无返回值,函数体块
(int x) -> x+1 // 显示声明参数(declared types),表达式等价于返回值
(int x) -> { return x+1; }
(x) -> x+1 // 隐式声明参数(inferred-type)
x -> x+1 // 单隐式声明参数,括号可省略略
(int x, int y) -> x+y
(x,y) -> x+y
(x, final y) -> x+y // 错误,隐式参数不能修改
(x, int y) -> x+y // 错误,混用参数
三、Lambda表达式的实例应用
1.用lambda实现Runnable接口
//原始写法
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Java8之前写法");
}
}).start();
//Java 8方式:
new Thread( () -> System.out.println("Java8之后写法") ).start();
new Thread( () -> {
System.out.println("Java8之后写法");
}).start();
2.消费型接口
// 有输入参数,没返回值
// 对应的方法类型为接收一个参数,没有返回值
// 一般来说使用Consumer接口往往伴随着一些期望状态的改变
// 或者事件的发生,典型的forEach就是使用的Consumer接口
// 虽然没有任何的返回值,但是向控制台输出结果
// Consumer 使用accept对参数执行行为
public static void main(String[] args) {
// 创建字符串
String str = "gyk";
// 调用
testCon(str, (s) -> System.out.println(s)); //输出字符串
}
public static void testCon(String str, Consumer<String> con) {
// 执行
con.accept(str);
}
3.供给型接口
// 无传入参数,有返回值
// 该接口对应的方法类型不接受参数,但是提供一个返回值
// 使用get()方法获得这个返回值
public static void main(String[] args) {
// 创建字符串
String str = "gyk";
// 调用
String sup = testSup(() -> str);
System.out.println(sup);
}
public static String testSup(Supplier<String> sup) {
// 执行
String s = sup.get();
return s;
}
4.断言型接口
// 有传入参数,有返回值Boolean
// 该接口对应的方法为接收一个参数,返回一个Boolean类型值
// 多用于判断与过滤,使用test()方法执行这段行为
public static void main(String[] args) {
// 创建字符串
String str = "gyk";
// 调用
boolean flag = testPre(str, (s) -> s.length() > 0); //输入字符串,判断长度是否大于0
System.out.println(flag);
}
public static boolean testPre(String str, Predicate<String> pre) {
// 执行
boolean flag = pre.test(str);
return flag;
}
四、使用Lambda表达式的意义
1.减少代码行数。相比匿名(内部)类,使用lambda表达式实例化函数式接口更更简洁
2. Stream API + Lambda 实现并行/串行操作
3. 传递lambda作为方法参数
4. 惰性计算,或延迟计算(lazy evaluation)
五、方法引用
某些lambda表达式里面仅仅是调用了一个已存在的方法,在这种情况下直接通过方法名称引用方法的形式可读性更高一些,这种形式就是方法引用。方法引用是一种更简洁易懂的lambda 表达式替换。
方法引用:引用类方法而不执行,类似取方法名
构造引用:引⽤用类构造方法而不实例化类,类似取构造方法名
方法引用类型:
1.TypeName::staticMethod - 类,接口,枚举的静态方法 //System::getProperty
2.objectRef::instanceMethod - 对象实例方法 //System.out::println
3.ClassName::instanceMethod - 类的实例方法 //"abc"::length
4.TypeName.super::instanceMethod - 超类的实例方法
5.ClassName::new - 类构造方法 //ArrayList::new
6.ArrayTypeName::new - 数组类型的构造方法 //int[]::new
关于Lambda表达式就介绍到这里,如发现博客中错误请尽管提出