【JDK 8特性】Lambda 入门

乐猿社区,程序员的花果山javascript

Lambda 管中窥豹

什么是 Lambda 表达式?简单的来讲,Lambda 表达式是一个匿名函数,Lambda 表达式基于数学中的λ演算得名,直接对应其中的 Lambda 抽象( lambda abstraction ),是一个匿名函数,既没有函数名的函数。Lambda 表达式能够表示闭包(注意和数学传统意义的不一样)。你也能够理解为,简洁的表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个能够抛出异常的列表。java

有时候,咱们为了简化代码而去使用匿名类,虽然匿名类能简化一部分代码,可是看起来很啰嗦。为了更好的的提升开发的效率以及代码的简洁性和可读性,Java8 推出了一个核心的新特性之一:Lambda 表达式。程序员

Java8 以前,使用匿名类给用户排序的代码:express

users.sort(new Comparator<User>() {
    @Override
    public int compare(User o1, User o2) {
        return o1.getAge().compareTo(o2.getAge());
    }
});

而有了lambda后,代码可能会是这样的编程

Comparator<User> byWeight = (User a1, User a2) -> a1.getAge().compareTo(a2.getAge());

还多是这样的闭包

Comparator<User> byAge = Comparator.comparing(User::getAge);

看上去更简洁了,少了好多行代码是否是?jvm

Lambda的本质

lambda的本质就是匿名函数编程语言

咱们都知道在java里赋值语句是这样的ide

String str = "123";

可是若是你想把“一块代码块”赋值给一个变量,该怎么作呢?,好比在javascript中能够这么写函数

var fun = ()->{alert(1)}

java作为老大哥,能不能有相似的写法呢?

codeSpan = public void doSomething(){System.out.pringln("乐猿社区")};

在java8以前是作不到,但有了java8以后,咱们能够一步步简化上面的代码实现相似的效果

函数式接口

这样,咱们就成功的很是优雅的把“一块代码”赋给了一个变量。而“这块代码”,或者说“这个被赋给一个变量的函数”,就是一个Lambda表达式。看到可能会有javaer要问,codeSpan的类型是什么呢?

在Java 8里面,全部的Lambda的类型都是一个接口,而Lambda表达式自己,也就是”一块代码“,须要是这个接口的实现。简而言之就是,Lambda表达式自己就是一个接口的实现。俗话说一图胜千言:

这种只有一个接口函数须要被实现的接口类型,咱们叫它”函数式接口“。为了不后来的人在这个接口中增长接口函数致使其有多个接口函数须要被实现,变成"非函数接口”,咱们能够在这个上面加上一个声明@FunctionalInterface, 这样别人就没法在里面添加新的接口函数了:

@FunctionalInterface
public interface MyLambdaInterface {
    void doSomething();
}

这样一个完整的函数式接口实现以下

public class Test {
    MyLambdaInterface codeSpan = () -> System.out.println(""乐猿社区);
}

而在Java7以前实现接口以下

public class MyInterfaceImpl implements MyLambdaInterface{
    @Override
    public void doSomething() {
        System.out.println("乐猿社区");
    }
}

在jvm层,这两种写法的本质同样的,但明显java8的写法更简洁清晰。

jdk默认的函数式接口

接口 参数 返回值 类别
Consumer T void 消费型接口
Supplier None T 供给型接口
Function T R 函数型接口
Predicate T boolean 断言型接口

基础语法

在lambda中咱们遵循以下的表达式来编写

expression = (variable) -> action
  • variable: 这是一个变量,一个占位符。像x,y,z,能够是多个变量;
  • action: 这里我称它为action, 这是咱们实现的代码逻辑部分,它能够是一行代码也能够是一个代码片断

能够看到Java中lambda表达式的格式:参数、箭头、以及动做实现,当一个动做实现没法用一行代码完成,能够编写 一段代码用{}包裹起来。

lambda表达式能够包含多个参数,例如:

int sum = (x, y) -> x + y;

这时候咱们应该思考这段代码不是以前的x和y数字相加,而是建立了一个函数,用来计算两个操做数的和。 后面用int类型进行接收,在lambda中为咱们省略去了return。

Lambda做用

  • lambda最直观的做用就是使得代码变得异常简洁
  • Lambda容许把函数做为一个方法的参数(函数做为参数传递进方法中)

写在最后的

lambda灵活多变,内容博大精深,本文只是介绍了lambda的基本原理以及基础语法,顺带讲述了下什么是函数式接口,让初次接触java8的Javaer对lambda有了一个大概的了解。

鼓励把新的Java8特性引入到目前的项目中,一个长期配合的团队以及一门古老的编程语言都须要不断的注入新活力,不然不进则退