搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > Java编程精选 > Java lambda表达式

Java lambda表达式

Java编程精选 2018-07-01

关键时刻,第一时间送达!

Java lambda表达式是Java 8新特性。它是步入Java函数式编程的第一步。因此,Java lambda表达式是创建时不属于任何类的函数。它可以像一个对象一样传递,并按要求执行。


Java Lambdas和单一方法接口


函数式编程通常用于实现事件监听器。Java中的事件监听器通常被定义为带有单个方法的Java接口。这里有一个单一方法接口示例:


public interface StateChangeListener {

    public void onStateChange(State oldState, State newState);

}


这个Java接口定义了一种方法,该方法在状态改变时调用(不管被观察到的是什么)。


在Java 7中,为了侦听状态更改,您必须实现这个接口。假设您有一个名为StateOwner的类,它可以注册状态事件监听器。这是一个例子:


public class StateOwner {

    public void addStateListener(StateChangeListener listener) { ... }

}


在Java 7中,可以用匿名接口实现添加事件监听器:


StateOwner stateOwner = new StateOwner();

stateOwner.addStateListener(new StateChangeListener() {

    public void onStateChange(State oldState, State newState) {

        // do something with the old and new state.

    }

});


首先创建StateOwner实例。然后StateChangeListenerinterface的一个匿名实现被作为监听器被添加在StateOwner实例中。


在Java 8中,您可以使用Java lambda表达式添加事件监听器,如下所示:


StateOwner stateOwner = new StateOwner();

stateOwner.addStateListener(

    (oldState, newState) -> System.out.println("State changed")

);


lambda表达式是这部分:


(oldState, newState) -> System.out.println("State changed")


lambda表达式与addStateListener()方法的参数类型相匹配。如果lambda表达式匹配参数类型(在这种情况下,是StateChangeListenerinterface),lambda表达式将转换成实现该参数接口的函数。


Java lambda表达式只能在匹配的类型只是单方法接口的时候使用。在上面的示例中,使用lambda表达式作为参数,参数类型为StateChangeListener接口。这个接口只有一个方法。因此,lambda表达式与该接口成功匹配。


Lambdas匹配接口


单个方法接口有时也被称为函数式接口。将Java lambda表达式与函数接口相匹配分为以下步骤:


•接口只有一个方法吗?

•lambda表达式参数是否与单方法参数匹配?

•lambda表达式的返回类型是否与单方法的返回类型匹配?


如果对这三个问题的回答是肯定的,那么给定的lambda表达式与接口成功匹配。


Lambda 类型推断


在Java 8之前,实现匿名接口前,必须指定要实现的接口。以下是本文开头的匿名接口实现示例:


stateOwner.addStateListener(new StateChangeListener() {

    public void onStateChange(State oldState, State newState) {

        // do something with the old and new state.

    }

});


在lambda表达式中,类型通常可以从周围的代码中推断出来。例如,可以从addStateListener()方法的方法声明中推断参数的接口类型(StateChangeListener接口上的单一方法)。这就是所谓的类型推断。编译器通过查找其他类型的参数来推断参数的类型—在本例中是方法定义。这是本文开始的例子,StateChangeListenerinterface并未在lambda表达式提及:


stateOwner.addStateListener(

    (oldState, newState) -> System.out.println("State changed")

);


在lambda表达式中,参数类型通常也可以推断出来。在上面的例子中,编译器可以从onStateChange()方法声明中推断出它们的类型。因此,从onStateChange()方法的方法声明中推断出参数oldState和newState的类型。


Lambda 参数


由于Java lambda表达式实际上只是方法,lambda表达式可以像方法一样接受参数。前面显示的lambda表达式的(oldState,newState)部分指定lambda表达式所采用的参数。这些参数必须与单一方法接口上的方法参数相匹配。在此例中,这些参数必须与StateChangeListener接口的onStateChange()方法的参数相匹配:


public void onStateChange(State oldState, State newState);


lambda表达式和方法参数数量必须匹配。


其次,如果您在lambda表达式中指定了任何参数类型,那么这些类型也必须匹配。我还没有向您展示如何在lambda表达式设置类型(稍后将在本文中展示),在很多情况下您并不需要它们。


0 参数

如果匹配lambda表达式的方法没有参数,则可以像这样编写lambda表达式:

() -> System.out.println("Zero parameter lambda");


注意括号之间没有内容。这表示lambda没有参数。


单个参数

如果方法与Java lambda表达式相匹配,那么您可以编写这样的lambda表达式:


(param) -> System.out.println("One parameter: " + param);


注意,参数被列在括号内。

当lambda表达式接受单个参数时,也可以省略括号,如下所示:


 param -> System.out.println("One parameter: " + param);


多个参数

如果匹配Java lambda表达式的方法需要多个参数,则需要在括号内列出参数。下面是Java代码:


(p1, p2) -> System.out.println("Multiple parameters: " + p1 + ", " + p2);


只有当方法取一个参数时,括号才可以省略。


参数类型

如果编译器无法从函数接口方法中推断出参数类型,则需要为lambda表达式指定参数类型。别担心,编译器会告诉你什么时候需要。这里有一个Java lambda参数类型示例:


(Car car) -> System.out.println("The car is: " + car.getName());


正如您所看到的, car参数的类型(Car)是在参数名称本身前面编写的,就像在其他地方声明一个方法参数一样,或者在创建一个接口的匿名实现时一样。


Lambda函数体


lambda表达式的主体,以及它所代表的函数/方法的主体,在lambda声明中- >的右侧:这里有一个例子:


 (oldState, newState) -> System.out.println("State changed")


如果lambda表达式需要由多个行组成,则可以将lambda函数体括在{}括号内,像声明方法时一样。这是一个例子:


 (oldState, newState) -> {

    System.out.println("Old state: " + oldState);

    System.out.println("New state: " + newState);

  }


Lambda表达式返回值


您可以从Java lambda表达式返回值,就像从方法中返回值一样。只需向lambda函数体添加一个返回语句,就像这样:


 (param) -> {

    System.out.println("param: " + param);

    return "return value";

  }


如果您的lambda表达式做的是计算返回值并返回,您可以用更短的方式指定返回值。而不是:


 (a1, a2) -> { return a1 > a2; }


你可以写:


 (a1, a2) -> a1 > a2;


编译器然后计算出表达式a1 > a2是lambda表达式的返回值(作为返回某种值的表达式)。


Lambdas 作为对象


Java lambda表达式本质上是一个对象。您可以将lambda表达式分配给一个变量并传递,就像使用其他对象一样。这是一个例子:


public interface MyComparator {

    public boolean compare(int a1, int a2);

}

MyComparator myComparator = (a1, a2) -> return a1 > a2;

boolean result = myComparator.compare(2, 5);


第一个代码块显示lambda表达式实现的接口。第二个代码块显示lambda表达式的定义,lambda表达式如何分配到变量,最后如何调用它实现的接口方法来调用lambda表达式。

  • 译者:java达人

  • http://tutorials.jenkov.com/java/lambda-expressions.html

  • Java编程精选整理发布,转载请联系作者获得授权

版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Java lambda表达式》的版权归原作者「Java编程精选」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注Java编程精选微信公众号

Java编程精选微信公众号:JavaPush

Java编程精选

手机扫描上方二维码即可关注Java编程精选微信公众号

Java编程精选最新文章

精品公众号随机推荐