首页 > 技术文章 > lambda表达式

codebetter 2019-12-13 13:47 原文

lambda表达式

产生的原因/为什么产生

替代匿名内部类,用于简化匿名内部类的繁琐语法。

有什么特性

Lambda 与闭包的不同之处,但是又无限地接近闭包。在支持一类函数的语言中,Lambda 表达式的类型将是函数。

lambda表达式语法

左侧:Lambda 表达式的参数列表,多个参数时用括号括起来:(param1,param2);单个参数时可以省略圆括号
右侧:Lambda 表达式中所需执行的功能,用花括号括起来,即函数体。若函数体只有一条语句,可以省略花括 号;当代码块只有一条return语句时可以省略return关键字,此时Lambda表达式会自动返回这条语句值。
用符号 “->” 连接左右两侧,即构成Lambda表达式。
形式如:

  1. (param1,param2) -> {...};

  2. param1 -> {...};

  3. param1 -> ...

    如:

    // 带回调的线程池
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Future<Long> result = executorService.submit(new Callable<Long>() {
        @Override
        public Long call() throws Exception {
            return new Date().getTime();
        }
    });
    		
    //Lambda表达式写法
    Future<Long> result1 = executorService.submit(() -> {
        return new Date().getTime();
    });
    //也可以写为
    Future<Long> result1 = executorService.submit(() -> new Date().getTime());
    

什么情况下能使用

在 Java 中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface)。我们会在后文详细介绍函数式接口。

函数式接口

函数式接口是只包含一个抽象方法声明的接口。该接口中可以有多个默认方法、类方法,但是只能有一个抽象方法。如Runable:

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

从源码中可以看见,Runnable接口只有一个抽象run()方法。

在声明函数式接口时可以加入@FunctionalInterface注解,该注解用于检测所声明的接口是不是函数式接口,若不是函数式接口则会报错。如下图:

使用时的注意事项

  1. Lambda表达式的目标类型必须是明确的函数式接口。

  2. Lambda表达式只能为函数式接口创建对象。

    如下由于Object接口不是函数式接口,所以会报错,此时可以对Lambda表达式进行强制类型转换:

示例

interface Eatable {
	void taste();
}

interface Flyable{
	void fly(String weather);
}

interface Addable{
	int add(int a , int b);
}

public class LambdaTest {
	public void eat(Eatable e) {
		System.out.println("Eatable eat");
		e.taste();
	}
	public void drive(Flyable f) {
		System.out.println("Flyable fly");
		f.fly("今天天气不错。");
	}
	public void test(Addable a) {
		System.out.println("Addable add");
		System.out.println("5+3="+a.add(5, 3));
	}
	

	public static void main(String[] args) {
		LambdaTest lt = new LambdaTest();
		lt.drive((weather)->{
			System.out.println(weather);
		});
		lt.eat(() -> System.out.println("我吃饱了。"));
		lt.test((a,b) -> {
			return a+b;
		});
	}

}

推荐阅读