Java8 lambda表达式
lambda表达式初识
lambda表达式的重要用法就是简化某些匿名类的写法,实际上lambda不仅仅是匿名内部类的语法糖,JVM内部也是通过invokedynamic指令来实现lambda表达式的。
也正是因为如此匿名类在编译以后会创建一个新的匿名内部类出来,而由于Lambda是调用JVMinvokedynamic指令实现的,所以并不会产生新类。
其实lambda表达式描述了一个代码块(匿名方法);可以将其作为参数传递给构造方法或者普通方法以便后续执行,如下:
()->System.out.println("冢狐")
- 其中()为lambda表达的参数列表(可以有也可以没有)
- ->标识这段代码为lambda表达式,后面就是要执行的代码。
其中lambda最常见的用途就是新建线程,有时候为了省事会用下面的方法创建并启动一个线程
public static void main(String[] args) {
new Thread(() -> System.out.println("冢狐")).start();
}
Lambda语法
lambda标准的语法如下:
(parameter-list)->{
express-or-statements}
-
其中()中的parameter-list是以逗号分隔的参数,在其中可以指定参数类型,也可以不执行(编译器会根据上下文进行推断)
-
->作为lambda的标识符,主要作用就是告诉这是一个lambda表达式
-
{}中为lambda的主体,主要通过其中的代码进行要做的事情
-
为变量赋值
Runnable r = (){ System.out.print("冢狐")};
-
作为return的结果:
static FileFilter getFilter(String ex){ return (pathname)->pathname.toString().endWith(ex); }
-
作为数组元素:
扫描二维码关注公众号,回复: 11778447 查看本文章final PathMatcher matchers[] = { (path) -> path.toString().endsWith("zhong"), (path) -> path.toString().endsWith("hu") };
-
作为普通方法或者构造方法的参数
new Thread(() -> System.out.println("冢狐")).start();
-
使用Lambda表达式的要求
能够使用lambda的依据就是必须有相应的函数接口。
函数接口是指内部只有一个抽象方法的接口,这一点和java是强类型语言吻合,即不能在代码的任何地方使用lambda表达式。
lambda的类型就是对于函数接口的类型。
自定义函数接口
自定义函数接口还是比较容易的,只需要编写一个只有一个抽象方法的接口即可
// 自定义函数接口
public static void main(String[] args) {
ConsumerInterFace<String> consumer = str-> System.out.println(str);
consumer.accept("自定义函数接口");
}
@FunctionalInterface
public interface ConsumerInterFace<T>{
void accept(T t);
}
java内置四大核心函数式接口
函数式接口 | 参数列表 | 返回类型 | 用途 |
---|---|---|---|
Consumer<T>消费型接口 | T | void | 对类型为T的对象应用操作,包含方法void accept(T t); |
Supplier<T>供给型接口 | 无 | T | 返回类型为T的对象,包含方法T get(); |
Function<T,R>函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果类型为R的对象,包含方法R apple(T t); |
Predicate<T>断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean值,包含方法boolean test(T t); |
Lambda和this关键字
由于lambda表达式并不会引入新的作用域,即lambda表达式的主体内使用的this关键字和其所在的类实例相同。
示例:
public class Player {
public static void main(String[] args) {
new Player().work();
}
public void work() {
System.out.printf("this = %s%n", this);
Runnable r = new Runnable() {
@Override
public void run() {
System.out.printf("this = %s%n", this);
}
};
new Thread(r).start();
new Thread(() -> System.out.printf("this = %s%n", this)).start();
}
}
work()中的代码可以分为三个部分:
- 单独的this关键字
- 这里的this为main()方法中通过new关键字创建的Player对象
- 匿名内部类中的this关键字
- 这里的this为work()方法中通过new关键字创建的Runnable对象
- Lambda表达式中的this关键字
- 这个和第一个单独的this是一个
输出结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nuq1rUxN-1592796226199)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200622101950.png)]