Java8 Lambda表达式

来源:互联网 发布:性冲动 知乎 编辑:程序博客网 时间:2024/06/07 01:19

从下面的例子入手

Clazz:

class Clazz {    private Integer x;    public Clazz(Integer x) {        this.x = x;    }    public Integer getX() {        return x;    }    public void setX(Integer x) {        this.x = x;    }    @Override    public String toString() {        return x + ", ";    }}

现在有一个ClazzList,要对其进行排序,有以下几种方法:

==需要强调一点,下面的代码使用到了list.sort(),在jdk1.8中接口可以有默认方法,也就是在List接口中sort方法已经有了默认实现。 在jdk1.8之前,对List排序,可以使用Collections帮助==

1) 实现Comparator接口,但是没有必要,因为可能只使用了一次这个类。
2) 使用匿名类:

    public static void main(String[] args) {        List<Clazz> list = new ArrayList<>(                Arrays.asList(new Clazz(10), new Clazz(80), new Clazz(50), new Clazz(30)));        list.sort(new Comparator<Clazz>() {            @Override            public int compare(Clazz o1, Clazz o2) {                return o1.getX().compareTo(o2.getX());            }        });    }

  使用匿名类,可以不必创建类,如果现在要反向排序,又要实例一个匿名类。 这时会发现有许多一样的代码,如下面的这部分:

     new Comparator<Clazz>() {            @Override            public int compare(Clazz o1, Clazz o2) {            }        }

  不管正序还是逆序排,都会写这段代码,然而真正用到的只是return o1.getX().compareTo(o2.getX());这部分的内容。

3) 使用Lambda表达式

    public static void main(String[] args) {        List<Clazz> list = new ArrayList<>(                Arrays.asList(new Clazz(10), new Clazz(80), new Clazz(50), new Clazz(30)));        list.sort((Clazz a1, Clazz a2) -> a1.getX().compareTo(a2.getX()));    }

非常简短,(Clazz a1, Clazz a2) -> a1.getX().compareTo(a2.getX())这一句话代替了上面繁杂的创建匿名类等过程。接下来就会讲解Lambda表达式。


Lambda表达式

表达式语法

使用匿名类时,有许多模板代码,并且比较啰嗦。 使用Lambda表达式可以简洁的表示一个行为或传递代码。

分析(Clazz a1, Clazz a2) -> a1.getX().compareTo(a2.getX())

  • (Clazz a1, Clazz a2) 参数列表,这是Lambda参数
  • 然后有一个->,把参数列表和Lambda主体分离
  • 后面部分为Lambda主体,比较2个Clazz的大小,表达式就是Lambda返回值。

一些合法的Lambda表达式:
1. () -> {} ,该表达式没有参数,并返回void。类似于public void XXX(){}
2. () -> "Hello", 表达式没有参数,且返回String类型Hello
3. () -> { return "Hello"; }, 表达式没有参数,返回Hello,这里使用了显示返回语句return,所以需要使用花括号
4. (Integer i) -> { return "Hello" + i; },参数为Integer类型,返回String

在哪里使用Lambda

可以在函数式接口使用,函数式接口就是只定义了一个抽象方法的接口。之所以上面的排序的Lambda表达式能够被sort接受,因为Comparator就是一个函数式接口。Runnable也是一个函数式接口,举个例子:

静态方法process,参数为一个Runnable

    public static void process(Runnable r) {        r.run();    }

分别使用匿名函数和Lambda表达式:

        //匿名类        process(new Runnable() {            @Override            public void run() {                System.out.println("Hello World");            }        });        //Lambda表达式        process(() -> System.out.println("Hello World"));

() -> System.out.println("Hello World")可以传给Runnable接口,如何判断传给的表达式是否正确?

函数式接口的抽象方法的签名基本上就是Lambda的签名,这个抽象方法叫做函数描述符。 Runnable接口没有参数也没有返回值,() -> System.out.println("Hello World")表达式也不接受参数,且返回的为void,所以该表达式的签名和Runnable接口的run()方法签名是一样的。也就是说对于同一个函数式接口,可以使用不同的Lambda表达式。

Java8中添加了很多函数式接口,这里不在给出,在java.util.function包下。


本文记录了一些自己学习到的知识,并没有很全面的讲解,本人水平有限~。

0 0
原创粉丝点击