一文掌握Lambda表达式

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)]

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/106898493
今日推荐