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

 

posted @ 2019-01-20 21:06  _绵绵  阅读(174)  评论(0)    收藏  举报