美文网首页
初识Java Lambda 表达式

初识Java Lambda 表达式

作者: 迷茫的Mr_Jing | 来源:发表于2018-08-31 16:35 被阅读0次

    作为老一代Java工作者,已经习惯了写匿名类,在Java代码中除了基本的数据类型,一切的都是对象,定义的函数和方法不可能完全独立,也不能将方法作为参数或者返回一个方法给实例。但是我们经常通过匿名类给方法传递函数功能,比如 下面代码

    textview.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //todo something
                }
            });
    

    在函数式编程语言中,函数它们可以独立存在,你可以将其赋值给一个变量,或将他们当做参数传给其他函数。
    但是在Java中我们不能这么做,所以就出现了Lambda表达式来弥补这缺陷,Lambda 表达式为 Java 添加了缺失的函数式编程特点。

    Lambda 表达式简介

    Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确,但现在姑且这么认为),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。

    你可以将其想做一种速记,在你需要使用某个方法的地方写上它。当某个方法只使用一次,而且定义很简短,使用这种速记替代之尤其有效,这样,你就不必在类中费力写声明与方法了。

    Lambda语法

    Lambda 表达式通常表示为如下格式:

    (参数) ->{处理代码}
    比如如下:
    (int a, int b )->{return a*b}
      () ->{return "test"}
    ....
    

    必须了解的基本规则

    • Lambda 表达式可以有多个或者零个参数
    • 参数类型 可以不申明 (int a)与 (a)效果相同
    • 参数用逗号相隔 (int a, int b, int c)
    • 只有一个参数括号可以省略 a -> return a;
    • {} 内可以有代码块 a ->{ int b = 2; int c = a+b; return c;}

    函数式接口

    只包含一个抽象方法声明的接口叫函数式接口。
    java.lang.Runnable 就是一种函数式接口,在 Runnable 接口中只声明了一个方法 void run();
    简单的说就是,写成匿名内部类的时候,只有一个内部方法的接口。我们可以看看通过Lambda表达式创建Runnable 接口引用。

    Runnable r = () -> System.out.println("hello world");
    new Thread(r);
    or
    new Thread(
       () -> System.out.println("hello world")
    ).start();
    

    Thread 构造函数将Lambda表达式作为参数传给了类对象。

    FunctionalInterface

    @FunctionalInterface 是 Java 8 新加入的一种接口,用于指明该接口类型声明是根据 Java 语言规范定义的函数式接口。Java 8 还声明了一些 Lambda 表达式可以使用的函数式接口,当你注释的接口不是有效的函数式接口时,可以使用 @FunctionalInterface 解决编译层面的错误。比如:

    @FunctionalInterface 
    public interface TestInterface {
       public void test();
    }
    
    //根据定义,函数式接口只能有一个抽象方法,如果你尝试添加第二
    //个抽象方法,将抛出编译时错误。例如:
    @FunctionalInterface
    public interface TestInterface {
    
        public void test1();
    
        public void test2();
    }
    

    我们看一下使用方法

    public class Test{
       public void run( TestInterface test){
              test.test();
        }
     
       //传统用法
       run(new TestInterface(){
                  @Override
                   public void test() {
                         //do something
                        System.out.println(" Anonymous class");
                    }
         });
      //Lambda 
        run( () ->System.out.println(" Lambda expression"));
    }
    
    //旧方法:
    new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from thread");
    }
    }).start();
    
    //新方法:
    new Thread(
    () -> System.out.println("Hello from thread")
    ).start();
    

    全新的操作符双冒号(::)

    Java 8 更新了一个新的操作符:: 双冒号操作符可以讲一个常规的方法转换为Lambda表达式:

    //Old way:
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    for(Integer n: list) {
       System.out.println(n);
    }
    
    //New way:
    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    list.forEach(n -> System.out.println(n));
    
    
    //or we can use :: double colon operator in Java 8
    list.forEach(System.out::println);
    

    Lambda 表达式与匿名类的区别

    使用匿名类与 Lambda 表达式的一大区别在于关键词的使用。对于匿名类,关键词 this 解读为匿名类,而对于 Lambda 表达式,关键词 this 解读为写就 Lambda 的外部类。
    写文不容易,点个赞呗。

    相关文章

      网友评论

          本文标题:初识Java Lambda 表达式

          本文链接:https://www.haomeiwen.com/subject/dbiswftx.html