lambda 表达式是 Java8 的新特性,虽说都发布很久了,但是不到万不得已是肯定不会研究这个的,现在就是那不得不学习的时候了。

本文主要说一下什么 lambda 表达式、Java 中为什么要有 lambda 表达式以及 lambda 表达式的应用。

在 Java 面向对象的思想中,我们知道函数是不能单独存在的,函数一般会作为某个对象的功能封装在对象之中,我们传递参数也不能传递一个函数。曾经 Java 也为此挣扎过,我们看下面这段代码,创建一个线程,输出一句话。

new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello World !");
}
}).start();

有点基础应该都知道这是匿名内部类,但是你知道的,真正有效的代码就一行输出语句。其余代码基本没用,我们可以反过来想一下,我们创建线程是为了执行某一个任务,也就是某一个方法,那我们为何不直接传入一个方法呢?

按照这个思路,我们可以这样写伪代码。

new Thread((某某任务)).start();

好了,现在问题就出现了,如何去形容这个任务,或者说在 Java 中如何表示呢?lambda 表达式应运而生。

一个函数,可能会有入参,函数要有函数体,于是就这样定义了 lambda 表达式 “(参数1,参数2)-> { 函数体 } ” 。

但是吧,实际使用过程中,因为参数和函数体的不同,又有一些变种的写法,一个 lambda 表达式可以有零个或多个参数,参数之间用逗号相隔。空括号代表参数为空。

lambda 表达式的主体可包含零条或多条语句,如果 lambda 表达式的主体只有一条语句,花括号 { } 可省略,否则必须包含在花括号 { } 中。

OK,到这里我们就可以重写上面的线程了。

new Thread(
() -> System.out.println("Hello World ")
).start();

说到这简单回忆一下什么是 lambda 表达式,曾经 Java 中不能直接把函数做参数,为了能行,创造了 lambda 表达式,可以把 lambda 表达式理解为一个功能块,只不过匿名罢了。

其实 lambda 的出现是为了和函数式编程相呼应,函数式编程,就是用函数为主体来编程,把函数当成是代码的基本组成部分,就像变量一样。官方说法叫第一等公民。

举个例子说明一下函数式编程的特点。

计算如下表达式:
(1 + 2) * 3 - 4 传统的过程式编程,可能这样写(比较傻,为了演示效果):
int a = 1 + 2;
int b = a * 3;
int c = b - 4; 函数式编程要求使用函数,我们可以把运算过程定义为不同的函数,然后写成下面这样:
int result = subtract(multiply(add(1,2), 3), 4);

有点蒙,没关系,先理解 lambda 表达式的使用再说,lambda 表达式最常用的莫过于替换 Runnable 接口实现线程任务,还有什么用处呢?

太难的不介绍,说一个比较简单的,用于列表的迭代。

对一个列表的每一个元素进行操作,不使用 Lambda 表达式时如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (int element : numbers) {
System.out.prinln(element);
}

使用 Lambda 表达式:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(x -> System.out.println(x));

重点在操作上,输入是 x ,然后对 x 进行输出操作。就线程和列表迭代来说,为什么他们能接收 lambda 表达式作为参数呢?我们看看 forEach 方法的参数内部是什么。

 * @since 1.8
*/
@FunctionalInterface
public interface Consumer<T> { /**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);

是一个接口,而这个接口被定义为函数式接口,lambda 表达式可以替换功能接口,我们就来自定义一个函数式接口来演示一下。

定义一个函数式接口:

// 定义一个功能接口或叫函数式接口
@FunctionalInterface
public interface WorkerInterface {
// 该接口中只能有一个抽象方法
public void doSomeWork();
} public class WorkerInterfaceTest { public static void execute(WorkerInterface worker) {
worker.doSomeWork();
} public static void main(String[] args) { // invoke doSomeWork using Annonymous class
execute(new WorkerInterface() {
@Override
public void doSomeWork() {
System.out.println("Worker invoked using Anonymous class");
}
});
// invoke doSomeWork using Lambda expression
execute(()->{System.out.println("Worker invoked using Lambda expression");});
}
}

总结一下最开始提出的几个问题,lambda 表达式可以理解为是一个匿名的函数,我们可以通过 lambda 表达式来代替功能接口(比方说 Runnable 接口)。函数式编程是一种编程模式,Java 为了支持它而定义了 lambda 。lambda 的应用主要在替代功能接口,列表迭代,还有一些对集合的操作上。

最后,能告诉我你现在使用 Lambda 表达式了吗,都是用在什么地方呢 ?

躲不掉的 lambda 表达式的更多相关文章

  1. Java 8特性探究(1):通往lambda之路与 lambda表达式10个示例

    本文由 ImportNew 函数式接口 函数式接口(functional interface 也叫功能性接口,其实是同一个东西).简单来说,函数式接口是只包含一个方法的接口.比如Java标准库中的ja ...

  2. java lambda表达式学习笔记

    lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是‘=>’. 杜甫说:射 ...

  3. C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...

  4. 写的非常好的文章 C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

  5. Python学习_列表推导和Lambda表达式

    列表推导目的是减少将一个列表转换为另一个列表时所需编写的代码量,其功能也能用列表迭代完成 1.根据要求创建列表threes_and_fives(列表值包括1到15中能够被3或者5正常的数) three ...

  6. Lambda表达式与匿名方法

    在C#2中,由于有了方法组,匿名方法,类型的协变和抗变,使得运用delegate变得很容易,在注册事件时代码变得简单易读,但是在C# 2中,代码仍然有点臃肿,大块的匿名方法会降低代码的可读性,一般我们 ...

  7. Java8特性详解 lambda表达式 Stream

    1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...

  8. Java 8 Lambda表达式10个示例【存】

    PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...

  9. (转)C#中的委托,匿名方法和Lambda表达式

    简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Fir ...

随机推荐

  1. Confluence 6 审查日志的对象

    审查日志记录一下事件的信息,这个记录不是详细的信息列表.但是这些信息能够让你了解你能够在日志中看到些什么内容. 空间 创建和删除一个空间. 编辑空间细节,主题,配色方案或者样式表. 修改空间权限,包括 ...

  2. 【python】安装hyperscan-python

    环境centos6.2 1. 先安装hyperscan 主要参考http://blog.csdn.net/cheng_fangang/article/details/51143412 注意:里面2.8 ...

  3. es2015(es6)基础知识整理(更新中...)

    1.let let可以声明块级作用域变量 'use strict'; if (true) { let app = 'apple'; } console.log(app); //外面是访问不到app的 ...

  4. HTML中body元素的属性

    body元素的属性 属性 描述 text 设定页面文字颜色 bgcolor 设定页面背景颜色 background 设定页面背景图像 bgproperties 设定页面的背景图像为固定状态(不随页面的 ...

  5. Java 产生一个大于等于200,小于300的随机数,且是10的整数倍

    public class Random200_300 { public static void main(String[] args) { int r1 = 0; while (true) { r1 ...

  6. 极光推送>>java SDK服务端集成后台项目(使用详解)

    PS:如果你是第一次用推送,那就直接按照我的步骤来,再去看官方文档,这样,更容易能理解操作流程.还有——-请耐心看 极光文档(java SDK)请参考 [ 极光文档 ] 步骤一: 首先,你必须在 [极 ...

  7. C++ Primer 笔记——关联容器

    1.关联容器支持高效的关键字查找和访问,标准库提供8个关联容器. 2.如果一个类型定义了“行为正常”的 < 运算符,则它可以用作关键字类型. 3.为了使用自己定义的类型,在定义multiset时 ...

  8. 异常:Keyword not supported: 'data source'的解决办法

    将连接字符串中的&quot换为“'”,一个单引号即可. 详细解释:https://blogs.msdn.microsoft.com/rickandy/2008/12/09/explicit-c ...

  9. 页面注册系统--使用forms表单结合ajax

    页面注册系统--使用forms表单结合ajax 在Django中通过forms构建一个表单 1.urls.py 配置路由 from django.conf.urls import url from d ...

  10. T4模版自动生成MSSQL实体类

    在Model层建立ModelAuto.ttinclude文件 <#@ assembly name="System.Core"#> <#@ assembly nam ...