前言

Java8新特性-Lambda表达式,好像很酷炫的样子,直接搬运官方文档:

Purpose
This tutorial introduces the new lambda expressions included in Java Platform Standard Edition 8 (Java SE 8). Time to Complete
Approximately 1 hour Introduction
Lambda expressions are a new and important feature included in Java SE 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection. In addition, new concurrency features improve performance in multicore environments.

所以学习这么酷炫的东西其实只需要大约一个小时就足够了;

介绍里面只有一句重点,其他都是废话:

Lambada表达式: 它们通过使用表达式来提供一种清晰简洁的方式来表示方法接口

然而,我还是不知道方法接口是个什么东西,直到我看完了文档,才发现这句也是废话;因为这个得懂了Lambada表达式是什么了才能理解这句话;

匿名内部类

学习Lambda表达式之前,先感受下匿名内部类使用:

  /**创建一个Runnable接口的实例*/
Runnable runnable = new Runnable() {
@Override
public void run() {
//
}
}; /**如果是创建一个线程可以这样*/
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//
}
});

以上代码创建一个线程,我们知道得到一个接口实例只能实例化其实现类,但是这里我并没有创建一个具体的实现类,因为我不需要再次使用它;而是使用了匿名类代替,相比之下这样的做法使得代码更紧凑简洁;

函数式接口 和 Lambda表达式语法

函数式接口:

  • Java8 将只有一个抽象方法的接口叫做 函数式接口

  • @FunctionalInterface注解只是显示表示这个接口是函数式接口,在定义函数式接口时就会检查是否符合函数式接口规范,Java自己实现的函数式接口都有这个注解,所以你懂的,规范是好事情

Lambda表达式语法(三部分组成):

参数列表 -> 方法体

比如: (int x)-> {System.out.println(x);}

实现函数式接口并使用Lambda表达式:

@FunctionalInterface
interface A{
void opration(); } class B {
void realOpration(A fi){
fi.opration();
} }
public class Tests { @Test
public void test(){
/**创建接口A的实例*/
A a = ()-> System.out.println("this is A ");
a.opration();
/**再来试试这个支持Lambda表达式的方法*/
B b = new B();
b.realOpration(()-> System.out.println("this is A"));
} }

所以Lambda表达式是什么?

看了上面简单的demo,所以Lambda表达式干了什么事情,System.out.println("this is A ") 就是函数式接口的匿名实现,只是用了一种特殊的非常简洁的形式来表示而已,那么这种表示方法就是Lambda表达式;为什么这么简洁,因为它不仅是匿名类,还特么把方法都匿名了,因为函数式接口只有一个抽象方法,它可以自动将Lambda表达式绑定到函数式接口的抽象方法;

当然这是我个人理解,文档中可以找到这样一句话,它是将其类比为方法:

A lambda expression is like a method: it provides a list of formal parameters and a body - an expression or block - expressed in terms of those parameters.

所以它其实就一个匿名类?然而:

 @Test
public void test() {
System.out.println(this.getClass().getName());
A a = new A() {
@Override
public void opration() {
System.out.println(this.getClass().getName());
}
};
a.opration();
A a2 = ()->{System.out.println(this.getClass().getName());};
a2.opration();
}
输出:
Basic.JavaBasicTests
Basic.JavaBasicTests$3
Basic.JavaBasicTests Process finished with exit code 0

所以这里可以看出来,匿名类中this关键字指向的是匿名类本身对象,而在Lambda表达式中this关键字竟然指向当前对象,这也解释了为了什么我当初在Lambda表达式中用this关键字死活访问不到函数式接口的默认方法和常量的原因;

实战应用

再说函数式接口

我们已经知道函数式接口的作用了,但其实我们不需要自己去实现函数接口,Java8已经根据内置了几种不同类型的函数式接口;

  • Predicate: A property of the object passed as argument
  • Consumer: An action to be performed with the object passed as argument
  • Function: Transform a T to a U
  • Supplier: Provide an instance of a T (such as a factory)
  • UnaryOperator: A unary operator from T -> T
  • BinaryOperator: A binary operator from (T, T) -> T

这里没必要一一列举了,如果自己需要实现一个支持Lambda表达式的方法,只需要选用合适的函数式接口就行了,其实只是一种规范;

下面一个demo足够:

Consumer的应用demo

class Class {
private List<Student> list = new ArrayList<>();
public void addStudent(Student student){
list.add(student);
}
public void showStudents(Consumer<Student> consumer){
for (Student student : list){
consumer.accept(student);
}
}
}
class Student{
private String name;
private char sex;
private Double height; public String getName() {
return name;
} public Student setName(String name) {
this.name = name;
return this;
} public char getSex() {
return sex;
} public Student setSex(char sex) {
this.sex = sex;
return this;
} }
public class Tests {
@Test
public void test(){
Class clazz = new Class();
clazz.addStudent(new Student().setName("000").setSex('男'));
clazz.addStudent(new Student().setName("002").setSex('女'));
clazz.showStudents((s)-> System.out.println(s.getName()));
} }

总结

所以总的来说,就是为了简化代码,封装我们的操作,所以引入了函数式接口的概念,而Lambda表达式表示了函数式接口中抽象方法的匿名实现;但是,因为这个接口只有一个抽象方法,因此Lambda表达式可以看做是这个接口的匿名实现;不过和匿名类相比其实还是有很多限制的;

Lambda表达式在Java8中的应用比较多,特别是对集合类的操作;比如sort方法、foreach方法等等;其中Stream API也是一大特点,但是也不过是对函数式接口的具体应用,还有Method Reference(方法引用)这些新特性,详细的了解需要看官方文档或者源码,文档才是最完整和权威的;

综上:

They provide a clear and concise way to represent one method interface using an expression.

Java SE 8: Lambda Quick Start

The Java® Language Specification(Java SE 8 Edition)

Java™ Platform API Doc Standard Ed. 8

Java8新特性-Lambda表达式是什么?的更多相关文章

  1. 乐字节-Java8新特性-Lambda表达式

    上一篇文章我们了解了Java8新特性-接口默认方法,接下来我们聊一聊Java8新特性之Lambda表达式. Lambda表达式(也称为闭包),它允许我们将函数当成参数传递给某个方法,或者把代码本身当作 ...

  2. java8新特性——Lambda表达式

    上文中简单介绍了一下java8得一些新特性,与优点,也是为本次学习java8新特性制定一个学习的方向,后面几篇会根据上文中得新特性一一展开学习.本文就从java8新特性中比较重要的Lambda表达式开 ...

  3. Java8新特性 - Lambda表达式 - 基本知识

    A lambda expression is an unnamed block of code (or an unnamed function) with a list of formal param ...

  4. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

  5. Java8新特性: lambda 表达式介绍

    一.lambda 表达式介绍 lambda 表达式是 Java 8 的一个新特性,可以取代大部分的匿名内部类,简化了匿名委托的使用,让你让代码更加简洁,优雅. 比较官方的定义是这样的: lambda ...

  6. Java8 新特性lambda表达式(一)初始

    本篇参考Richard Warburton的 java8 Lambdas :Functional Programming for the Masses 学习lambda表达式之前,需要知道什么是函数式 ...

  7. Java8新特性——Lambda 表达式

    Lambda 表达式 ​ ​ ​ ​ ​ ​ ​ ​ Lambda 表达式的实质属于函数式编程. ​ ​ ​ ​ ​ ​ ​ ​ 语法格式为:(parameters) -> expression ...

  8. Java8新特性-Lambda表达式

    1.  什么是Lambda表达式? Lambda表达式就是可以把函数作为参数传递,或者说把代码作为数据传递给函数. 2. Lambda表达式的语法格式 基本语法格式如下: 基本语法下多个变体的说明: ...

  9. Java8新特性——lambda表达式.(案例:词频统计)

    需求:读入一个文本文件,确定所有单词的使用频率并从高到低排序,打印出所有单词及其频率的排序列表 先用传统方法解: package cn._1.wordfrequency; import java.ut ...

随机推荐

  1. [转]Kaldi语音识别

    转:http://ftli.farbox.com/post/kaldizhong-wen-shi-bie Kaldi语音识别 1.声学建模单元的选择 1.1对声学建模单元加入位置信息 2.输入特征 3 ...

  2. C++内存读写例子

    /************************************************************* // 声明头文件 #ifndef LyShark__h #define L ...

  3. JavaScript工作体系中不可或缺的函数

    一.函数的概念 日常生活中,我们要完成一件事,总是习惯先有一个计划,后期按照计划,一步一步执行,则能够完成,并且达到一定效果实现一定的功能.在编程的世界里,“功能”可称呼为“函数”,因此“函数”即一段 ...

  4. 多条SQL语句对查询结果集的垂直合并,以及表设计时如何冗余字段

    需求引入 你有一个销售单表A 和一个销售单详情表B 和一个收付款记录表C A---->B 一对多   A---->C一对多 如果一个销售单有两个详情,三条收款记录 对一个销售单 我们想查询 ...

  5. 线性整流函数(ReLU)

    线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元, 是一种人工神经网络中常用的激活函数(activation function),通常指代以斜坡函数及其变种为代 ...

  6. 第13组_16通信3班_045_OSPFv3作业

    IPv6 路由-OSPFv3 实验目的   1. 掌握 OSPFv3 的配置方法 2. 掌握在帧中继环境下 OSPFv3 的配置方法 3. 掌握 OSPFv3 NSSA 的配置方法 4. 学会查看 O ...

  7. git push 时发生 error: failed to push some refs to 错误 (解决办法)

    出现问题的原因:在github上更新了README.md,没有更新到本地仓库.而在本地git仓库又修改了文件,这时使用 git push origin master 推送到远程仓库后就出现了下面的问题 ...

  8. MemcachedUI-一款基于.NET MVC编写的Memcached监控软件

    一.起源 服务器上使用了Memcached做缓存加速,但是想查看Memcached状态的时候都只能telnet 127.0.0.1 11211 这样来查看,甚是累人,就想能不能做一款web端的软件,方 ...

  9. mysql 开发进阶篇系列 52 权限与安全(系统四个权限表的粒度控制关系)

    一.概述 接着上篇的权限介绍,当用户进行连接的时候,权限表的存取过程有以下两个阶段: (1) 先从user表中的host,user, authentication_string 这3个字段中判断连接的 ...

  10. 剑指offer-学习笔记

    前言:18/06/06开始学习,每个程序都会用C写一遍,因书中用C++举例,也会换种思路写,供学习和参考!!!很推荐这本书很不错,准备入手,一般不买实体书,都用电子书,因一般都看一遍,但这本会看很多遍 ...