Java8新特性之lambda表达式
一.函数式接口
函数式接口是有且仅有一个抽象方法,但可以有多个非抽象方法的接口
满足以下条件的接口为函数式接口
1. 使用@FunctionalInterface注释,满足@FunctionalInterface注释的约束
2. 没有使用@FunctionalInterface注释,但满足@FunctionalInterface注释的约束
函数式接口示例:
1 @FunctionalInterface 2 interface TestFunction{ 3 void test(); 4 @Override 5 String toString(); 6 @Override 7 boolean equals(Object obj); 8 } 9 10 11 interface TestFunction{ 12 void test(); 13 @Override 14 String toString(); 15 @Override 16 boolean equals(Object obj); 17 } 18 19 20 @FunctionalInterface 21 interface TestFunction{ 22 void test(); 23 } 24 25 26 interface TestFunction{ 27 void test(); 28 }
PS.前两个接口显式声明了Object的toString()和equals()方法,不影响它是一个函数式接口,因为所有的接口都会声明Object的public方法
二.lambda表达式
lambda表达式,也可称为闭包,是一个语法糖,本质是一个匿名类,需要函数式接口支持。
(闭包 -- 将一个方法作为一个变量去存储,也就是一个方法的实例)
- Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力
1.语法格式
1 1.无参数,无返回值 2 3 () -> {System.out.println("Hello Lambda by java8");} 4 5 //函数体内一条语句可以不写{} 6 7 () -> System.out.println("Hello Lambda by java8"); 8 9 2.单参数,无返回值 10 11 (x) -> {System.out.println(x);} 12 13 //单个参数可不写() 14 15 x -> {System.out.println(x);} 16 17 3.多参数,有返回值 18 19 (x,y)-> { 20 21 System.out.println(x + y); 22 23 return x + y; 24 25 } 26 27 //函数体只有一条语句时,可省略return 28 29 (x,y) -> x + y;
PS.无需声明参数类型,编译器自动识别
2.lambda表达式的类型
lambda表达式可以被当作一个Object,它的类型是由上下文推导而来,即上下文所期待的类型,这个类型称为目标类型
一个lambda表达式可以有多个目标类型
1 Runnable run = () -> System.out.println("run"); 2 Object obj = run; //可以使用lambda表达式为一个函数接口赋值,再赋值给一个Object 3 //Object objLambda = () -> System.out.println("run") 报错,必须转化为一个函数式接口 4 Object objLambda = (Runnable)() -> System.out.println("run");
3.变量作用域
lambda表达式只能引用final修饰的外部变量(或者可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
int x = 0; TestFunction testFunction = () -> {System.out.println(x);};//Variable used in lambda expression should be final or effectively final x = 5;
PS.表达式内部不允许声明一个与外部变量同名的参数或变量
4.lambda表达式应用
4.1创建线程
1 //jdk1.7创建线程
2 Thread thread1 = new Thread(new Runnable() {
3 @Override
4 public void run() {
5 System.out.println("Hello Lambda by java7");
6 }
7 });
8
9 //lambda表达式创建线程
10 Thread thread2 = new Thread(() -> {System.out.println("Hello Lambda by java8");});
11
12 thread1.start();
13 thread2.start();
4.2文件过滤
1 //1.文件目录 2 File fileDir=new File("D:/resource"); 3 //2.筛选 4 File [] files=fileDir.listFiles((f)->!f.isDirectory()&&f.getName().endsWith(".js"));
4.3结合stream批处理(重点,以后展开)
1 List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
2 int sum = nums.stream().reduce(0, (a, b) -> a + b); //求和
5.方法引用
Integer::parseInt //静态方法引用
System.out::print //实例方法引用
Person::new //构造器引用
super::toString //引用某个对象的父类方法
String[]::new //引用一个数组的构造器
1 //c1 与 c2 是一样的(静态方法引用) 2 Comparator<Integer> c2 = (x, y) -> Integer.compare(x, y); 3 Comparator<Integer> c1 = Integer::compare; 4 5 //下面两句是一样的(实例方法引用1) 6 persons.forEach(e -> System.out.println(e)); 7 persons.forEach(System.out::println); 8 9 //下面两句是一样的(实例方法引用2) 10 persons.forEach(person -> person.eat()); 11 persons.forEach(Person::eat); 12 13 //下面两句是一样的(构造器引用) 14 strList.stream().map(s -> new Integer(s)); 15 strList.stream().map(Integer::new);
参考资料:https://blog.csdn.net/ioriogami/article/details/12782141
http://www.runoob.com/java/java8-lambda-expressions.html

浙公网安备 33010602011771号