概述
Lambda表达式是Java8增加的语言级的新特性。
1.背景
在Java中,一切皆对象, 数组、类的实例都是对象。
在Java中定义函数或者方法不可能完全独立,也不能将方法作为参数或返回一个方法给实例。
在Java8之前,要实现将某些功能传递给某个方法,要写匿名内部类:
String[] arr = {"c","a","d","b"};
//Arrays.sort(arr,new StringSort());// 外部类
//Arrays.sort(arr,new InnerStringSort());// 内部类
//new + 接口/抽象类 创建匿名内部类对象
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(Arrays.toString(arr));
为了对集合进行排序,为Comparator接口创建了一个匿名内部类对象,重写了接口中的方法来实现排序的功能。
2.简介
Lambda表达式是一个匿名函数,可以将Lambda表达式理解为一段可以传递的代码(将代码段数据一样传递)。使用Lambda表达式可以写出更简洁,更灵活的代码。
Lambda表达式的本质只是一个语法糖,有编译器推断并帮助我们转换包装为常规的代码,因此我们可以使用更少的代码来实现相同的功能。
Java中的Lambda表达式通常使用(argument)->{body}
的语法书写:
->的左侧:Lambda表达式的参数列表
->的右侧:Lambda表达式中需要执行的功能,及Lambda体
(参数1,参数2,...)->{函数体}
(类 类实例,类 类实例,...)->{函数体}
下面是一些Lambda表达式的例子:
- 无参数,无返回值,lambda 体中只有一行代码时,{}可以忽略
() -> System.out.println("Hello World");
- 无参数,有返回值
() -> { return 3.1415 };
- 有参数,无返回值
(String s) -> { System.out.println(s); }
- 有一个参数,无返回值
s -> { System.out.println(s); }
- 有多个参数,有返回值
(int a, int b) -> { return a + b; }
- 有多个参数,表达式参数类型可以不写,jvm 可以根据上下文进行类型推断
(a, b) -> { return a - b; }
3.Lambda表达式的结构
- Lambda表达式参数可以有0个、1个或多个,正文语句可以有0条,1条或多条。
- 可以显式声明参数类型,也可以由编译器自动从上下位推断参数的类型。
(int a,int b)与 (a,b)相同
。 - 空括号表示无参
()->100
。 - 正文只有一条语句,大括号不用写,且表达式返回值类型与匿名函数的返回类型相同。
(a,b)->return a+b;
- 只有一个参数时,如果不指明类型,那么可以不写括号
x->return x*x;
。
package com.ffyc.forword.lambd;
import java.util.Arrays;
public class LambdDemo {
/*
lambda 语法
(参数列表)->{函数体}
是匿名函数,一般在方法的参数为"接口"时,代替匿名内部类使用(Java8新特性)
(a,b) 参数类型可以不写,可以根据上下文自动推断
推断依据?
要求接口中只有一个抽象方法
@FunctionalInterface 功能接口(java8)单抽象方法接口
public interface Comparator<T>
*/
public static void main(String[] args) {
String[] arr = {"c","a","d","b"};
//用lambda表达式代替匿名内部类对象 将接口中的函数作为参数传递
Arrays.sort(arr,(o1,o2)->{ return o2.compareTo(o1);});
System.out.println(Arrays.toString(arr));
}
}
4.功能接口(Functional Interface)
功能接口是Java8中新增特性,只允许一个抽象方法。这些接口也称为单抽像方法接口。它们也可以使用Lambda表达式,方法引用和构造函数引用来表示。
Java8引入了一个注释:@FunctionalInterface
,当我们注释的接口违反了Functional Interface的规则时,会编译报错。
自定义功能接口示例:
功能接口只能有一个抽象方法,如果在被@FunctionalInterface
标注的接口中声明超过1个抽象方法,会抛出编译错误
Multiple non-overriding abstract methods found in interface …
在该接口中发现了多个未重写的抽象方法
Java8允许我们以Lambda表达式的方式为功能接口提供实现,也就是说我们可以将整个Lambda表达式作为功能接口的实现类。
例如:
功能接口
lambda表达式实现接口
5.Lambda表达式 示例
- 线程初始化
//匿名内部类方式
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("run...");
}
}).start();
//Lambda表达式
new Thread( ()->{System.out.println("run...");} ).start();
- 排序
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
Arrays.sort(arr,(o1,o2)->{ return o1.compareTo(o2);});
List<Integer> list = Arrays.asList(4,1,3,2);
System.out.println(list);//[4, 1, 3, 2]
list.sort((o1,o2)->{return o1.compareTo(o2);});
System.out.println(list);//[1, 2, 3, 4]
- 事件处理
// 匿名内部类方式
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello world");
}
});
// lambda 表达式方式
button.addActionListener( (e) -> { System.out.println("Hello world"); });
- 遍历输出
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
//foreach遍历
for (Integer i : list) {
System.out.print(i+" ");
}
//Lambda表达式
list.forEach(i->{
System.out.print(i+" ");
});
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15601.html