初识Java Lambda 表达式

2018-08-31  本文已影响0人  迷茫的Mr_Jing

作为老一代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"}
....

必须了解的基本规则

函数式接口

只包含一个抽象方法声明的接口叫函数式接口。
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 的外部类。
写文不容易,点个赞呗。

上一篇 下一篇

猜你喜欢

热点阅读