Lambda表达式

#Lambda 简介

> Java 1.8新增了Lambda表达式,让Java可以支持函数式编程(Python,Js等也支持),让代码更加的优美简洁。

##1.引入

在 `awt/swing` 、`Java FX`、`Android` 开发中需要大量的使用到匿名内部类,要知道这东西一写出来,代码就显得比较的臃肿,十分的不利于阅读,就如下 JavaFx 程序(简单的按钮事件)

![image](http://39.106.31.106/group1/M00/00/00/rBGejlr9jqiAaBj5AABBKDQPUeg884.png)

其实核心业务就只需要 handle方法里面中的2行

那么我们换成Lambda表达式

![image](http://39.106.31.106/group1/M00/00/00/rBGejlr9kL-Ab_cFAABW0_jasJw368.png)

为了方便理解,需要跟着如下步骤顺序阅读

##2.自定义一个lambda表达式

**1. 新建一个接口**

lambda表达式其实就是优化匿名内部类的写法如下我们定义一个Test的**接口**,要保证该接口只能有**一个抽象方法**

“` lang-java

interface Test{

public void sayHi();

}

“`

**2. 使用原始的匿名内部类调用**

“`lang-java

Test test = new Test(){

public void sayHi(){

System.out.println(“匿名内部类实现!”);

}

};

test.sayHi();

“`

**3.使用Lambda表达式**

“`lang-java

Test test = () -> {

System.out.println(“hello java8 !”);

};

test.sayHi();

“`

上面是无参的调用方式,下面我们看一下有参调用

**4.有返回值和有参调用**

“`lang-java

public class TestLambda{

public static void main(String[] args) {

//

Test1 test = (arg1) -> {

return “Hi ! 我叫:”+arg1;

};

System.out.println(test.sayHi(“网络巡警”));

}

}

interface Test1{

//有返回值和形参列表定义

public String sayHi(String name);

}

“`

有参和返回值都玩了 下面看一下Lambda语法

**5.Lambda表达式语法**

“`lang-java

//接口名 变量名 = (方法的形参) -> {

//方法体

//};

//调用方法

“`

**6.Lambda简写**

在日常开发中,为了体现使用Lambda的特性一般都会使用简写的方式。

这是不简写情况下

“`lang-java

Test1 test = (String arg1) -> {

return arg1;

}

“`

简写1:去掉参数类型,在Java8会**自动推断**该参数的类型,

早在JDK1.7中就加入了**类型推断**的特性比如:List<String> list = new ArrayList<>();

“`lang-java

Test1 test = (arg1) -> {

return arg1;

}

“`

简写2:形参列表为一个 时可以去掉()

“`lang-java

Test1 test = arg1 -> {

return arg1;

}

“`

简写3:单只存在一行代码时,可以去掉方法和return关键字

“`lang-java

Test1 test = arg1 -> arg1;

“`

下面可以复制如下代码测一下

“`lang-java

public class TestLambda{

public static void main(String[] args) {

//不简写

Test1 test1 = (arg1) -> {

return “Hi ! 我叫:”+arg1;

};

//形参列表只有一个,可以简写为

Test1 test2 = arg1 -> {

return “Hi ! 我叫:”+arg1;

};

//最简化状态(方法体只有一条代码,要去掉return)

//为了方便展示就没这样

//Test1 test3 = arg1 -> “Hi ! 我叫:”+arg1;

Test1 test3 = arg1 ->

“Hi ! 我叫:”+arg1;

//测试打印

test1.sayHi(“网络巡警!”);

test2.sayHi(“网络巡警!”);

test3.sayHi(“网络巡警!”);

//不简写情况

Test test4 = () -> {

System.out.println(“hello !”);

};

//简写后

Test test5 = () ->

System.out.println(“hello !”);

test4.sayHi();

test5.sayHi();

//不简写情况

Test2 test6 = (amount,quantity) -> {

return amount*quantity;

};

//简写后

Test2 test7 = (amount,quantity) ->

amount*quantity;

System.out.println(“订单价格”+test6.sayHi(200, 2));

System.out.println(“订单价格”+test7.sayHi(200, 2));

}

}

interface Test{

public void sayHi();

}

interface Test1{

//有返回值和形参列表定义

public String sayHi(String name);

}

interface Test2{

public int sayHi(int amount,int quantity);

}

“`

##3.声明函数式接口的注解

我们常用的一些接口Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解。

![image](http://39.106.31.106/group1/M00/00/00/rBGejlr9mwKAPvHrAACTHvB_JfY721.png)

**1、该注解只能标记在有且仅有一个抽象方法”的接口上。**

**2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。**

**3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。**

**4、该注解不是必须的,如果一个接口符合”函数式接口”定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。**

下面我在函数接口第2个抽象方法

![image](http://39.106.31.106/group1/M00/00/00/rBGejlr9m-6AYVBIAAAyLe3H6HY403.png)

毫无意外编辑器会报错

## 3.Lambda常见应用

**1 排序使用**

“`lang-java

//排序

List<String> names1 = new ArrayList<>();

names1.add(“Google “);

names1.add(“Runoob “);

names1.add(“Taobao “);

names1.add(“Baidu “);

names1.add(“Sina “);

//jdk1.7排序

Collections.sort(names1, new Comparator<String>() {

@Override

public int compare(String s1, String s2) {

return s1.compareTo(s2);

}

});

List<String> names2 = new ArrayList<>();

names2.add(“Google “);

names2.add(“Runoob “);

names2.add(“Taobao “);

names2.add(“Baidu “);

names2.add(“Sina “);

//jdk1.8排序

Collections.sort(names2,(s1,s2) -> s1.compareTo(s2));

//打印

System.out.println(names1);

System.out.println(names2);

“`

**2 线程创建**

“`lang-java

//线程创建一

Thread thread = new Thread(() ->

System.out.println(“当前线程:”+Thread.currentThread()));

thread.start();

//线程创建二,有返回值线程

FutureTask<String> future = new FutureTask<>(() -> “123”);

new Thread(future).start();

“`

    原文作者:网络巡警啊
    原文地址: https://zhuanlan.zhihu.com/p/37009327
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞