java8中的lambda表达式实用详解

1. lambda简介

​ Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。Lambda表达式是Java8中的新特性,编码一般是尽可能轻量级的将代码封装为数据,传统的解决方案是通过接口和实现类(匿名内部类)实现,这种方式存在语法冗余,this关键字,变量捕捉,数据控制等问题lambda概述

2. lambda特点

  • Lambda表达式理解为一段可以传递的代码,可以写出更简洁、更灵活的代码。

  • 使代码更简洁,紧凑

  • 可以使用并行流来并行处理,充分利用多核CPU的优势,有利于JIT编译器对代码进行优化

3. lambda经典案列

  • 线程创建的两种方式:继承Thread方式、实现Runnable方式
public interface Runnable{void run();
}
  • 匿名内部方式创建一个线程

Tread类传递了一个匿名的Runnable对象,重载Runnable接口的run()方法来实现相应逻辑。

public static void main(String[] args) {Thread thread = new Thread(new Runnable() {@Override  //重写Runnable接口里面的run()方法public void run() {System.out.println("匿名内部类方式--线程1");}});thread.start(); //启动线程
}
  • Lambda表达式创建一个线程
public static void main(String[] args) {Thread thread = new Thread(() -> System.out.println("匿名内部类方式-启动线程2"));thread.start();
}

4.lambda语法格式

4.1 Lambda表达式的标准语法格式

Lambda表达式就是对函数式接口中抽象方法的实现,是对其匿名内部类的一个简写,只保留了方法的参数列表和方法体,其他的成分可以省略。因此,Lambda表达式的格式非常简洁,只有三部分组成:

  • 参数:指定了Lambda表达式需要的所有参数,如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
  • 箭头:由英文中画线和大于符号组成,固定写法。代表指向动作
  • 方法体:Lambda表达式要执行的功能,具体的代码方法内容
(参数,…,参数)->{方法体}基本语法:(parameters) -> expression 或 (parameters) ->{ statements; }

注:

  • 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  • 可选的参数圆括号:一个参数无需定义圆括号,但无参数或多个参数需要定义圆括号。
  • 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  • 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

4.2 Lambda表达式省略语法格式

在Lambda标准语法格式的基础上,可以使用省略写法的规则:

  • 若小括号内参数只有一个可以省略。
  • 若小括号内没有参数或有两个及以上的参数,则 小括号不能省略。
  • 若大括号内只有一条语句,无论是否有返回值,大括号、return关键字、分号可以省略。
案例一:无参,无返回值,只有一条语句
public static void main(String[] args) {Runnable runnable = () -> System.out.println("lambda 运行1");runnable.run();}//结果
lambda 运行1
案例二:一个参数,无返回值
public static void main(String[] args) {Consumer<String> consumer = (x) -> System.out.println(x);//可简化   Consumer<String> consumer = System.out::println;consumer.accept("lambda 运行2");}//结果
lambda 运行2
案例三:一个参数时,参数的小括号可以省略
public static void main(String[] args) {Consumer<String> consumer3 = x -> System.out.println(x);//可简化 Consumer<String> consumer3 = System.out::println;consumer3.accept("lambda 运行3");}//结果
lambda 运行3
案例四:有两个参数,并且Lambda体中有多条语句。
public static void main(String[] args) {Comparator<Integer> com4 = (x, y) -> {System.out.println("lambda 运行4");return Integer.compare(x, y);};System.out.println(com4.compare(1, 2));}//结果
lambda 运行4
-1
案例五:有两个以上参数,有返回值,若Lambda体中只有一条语句,return和大括号都可以省略不写
public static void main(String[] args) {Comparator<Integer> com5 = (x, y) -> Integer.compare(x, y);//可简化   Comparator<Integer> com5 = Integer::compare;System.out.println(com5.compare(1, 2));}//结果
-1
案例六:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM可以通过上下文推断出数据类型,即“类型推断”
public static void main(String[] args) {Comparator<Integer> com = (Integer x, Integer y) -> Integer.compare(x, y);//可简化   Comparator<Integer> com = Integer::compare;System.out.println(com.compare(1, 2));}//结果
-1

**口诀:**左右遇一括号省,左侧推断类型省,能省则省。

5. 方法引用

方法引用的三种形式

  • 类 :: 静态方法

  • 类 :: 非静态方法

  • 对象 :: 非静态方法

注:

方法引用规定,对象不能调用静态方法,这和面向对象的思想一致。但类可以调用非静态方法,这是面向对象中不允许的。

5.1 类引用静态方法

语法格式:类::静态方法名

public static void main(String[] args) {Comparator<Integer> comparable= Integer::compare;//使用方法引用实现相同效果Comparator<Integer> integerComparable=Integer::compare;System.out.println(integerComparable.compare(2,1));System.out.println(comparable.compare(2,1));
}//结果
1
1
5.2 类引用普通方法

语法格式:类::实例方法名

public static void main(String[] args) {BiPredicate<String, String> biPredicate = String::equals;//使用方法引用实现相同效果BiPredicate<String, String> bp2 = String::equals;System.out.println(biPredicate.test("1", "2"));System.out.println(biPredicate.test("1", "2"));
}//结果
false
false
5.3 对象引用非静态方法

语法格式: 实例化对象::普通方法;

public static void main(String[] args) {Consumer<String> consumer = System.out::println;consumer.accept("java");
}//结果
java

6. 构造引用

构造引用语法格式: 类名称::new

  • 和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。

  • 抽象方法的返回值类型即为构造器所属的类的类型

//data:
public static class Employee {private Integer id;private String name;private Integer age;@Overridepublic String toString() {return "Employee{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}public Employee(){}public Employee(Integer id) {this.id = id;}public Employee(Integer id, Integer age) {this.id = id;this.age = age;}public Employee(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}}

实例:

public static void main(String[] args) {//原始写法Supplier<Employee> sup = new Supplier<Employee>() {@Overridepublic Employee get() {return new Employee();}};// Lambda写法Supplier<Employee>  sup1 = () -> new Employee();//构造器引用写法//Supplier中的T get()//Employee的空参构造器:Employee()Supplier<Employee>  sup2 = Employee :: new;}
// Lambda写法
Function<Integer,Employee> func1 = id -> new Employee(id);//构造器引用写法
//Function中的R apply(T t)
Function<Integer,Employee> func2 = Employee :: new;
// Lambda写法
BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);//构造器引用写法
//BiFunction中的R apply(T t,U u)
BiFunction<Integer,String,Employee> func2 = Employee :: new;

7. 数组引用

数组引用的格式:type[]:new

public static void main(String[] args) {Function<Integer,String[]> function=String[]::new;String[] apply = function.apply(5);System.out.println(apply.length);
}//结果
5

8. Lambda表达式的作用域

​ Lambda表达式可以看作是匿名内部类实例化的对象,Lambda表达式对变量的访问限制和匿名内部类一样,因此Lambda表达式可以访问局部变量、局部引用,静态变量,实例变量。

8.1 访问局部变量

可以直接在 lambda 表达式中访问外部的局部变量

public static void main(String[] args) {final int num = 1;
//不用声明为final 也可以
//int num = 1;
Converter<Integer, String> stringConverter =(from) -> String.valueOf(from + num);stringConverter.convert(2);
}//结果
3
8.2 访问对象字段,静态变量

和局部变量不同的是,Lambda内部对于实例的字段(即:成员变量)以及静态变量是既可读又可写。

import org.springframework.core.convert.converter.Converter;public static void main(String[] args) {Lambda4 lambda4 = new Lambda4();lambda4.testScopes();
}class LambdaTest {static int myStaticNum;int myNum;void testScopes() {Converter<Integer, String> stringConverter1 = (from) -> {outerNum = 23;return String.valueOf(from);};String convert = stringConverter1.convert(1);System.out.println("Integer转化String结果" + convert);Converter<Integer, String> stringConverter2 = (from) -> {outerStaticNum = 72;return String.valueOf(from);};String convert2 = stringConverter2.convert(2);System.out.println("Integer转化String结果" + convert2);}
}//结果
Integer转化String结果 1
Integer转化String结果 2

9. 总结

​ java8新特性之lambda表达式知识总结的文章就介绍到这了,这边列举了部分例子供参考,仅作为学习笔记使用,欢迎批评指正,要是感兴趣可以关注微信订阅号 程序own

java8中的lambda表达式实用详解相关推荐

  1. 项目中使用 java函数式编程_函数式编程在Java8中使用Lambda表达式进行开发

    事情起因 如果不喜欢看故事的同学,请前往下一章节. 事情起因是我打算集成Redis缓存,配置了Redis以后,发现@Cacheable注解始终不生效,折腾了大半天以后,我的心态已经崩了,决定不使用@C ...

  2. java lambda表达式详解_java8新特性-Lambda表达式的详解(从0开始)

    这几天复习了java8的一些新特性,作为一个从java5以来最具革命性的版本,一直没有来得及总结.本系列文章主要是从<java8实战>总结的.这是第一篇文章主要介绍java8的lambda ...

  3. Struts2中的OGNL表达式的详解

    首先了解下OGNL的概念: OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的 ...

  4. C++中的Lambda表达式详解

    函数对象与Lambdas 你编写代码时,尤其是使用 STL 算法时,可能会使用函数指针和函数对象来解决问题和执行计算.函数指针和函数对象各有利弊.例如,函数指针具有最低的语法开销,但不保持范围内的状态 ...

  5. JSP 中EL表达式用法详解

    EL 全名为Expression Language EL 语法很简单,它最大的特点就是使用上很方便.接下来介绍EL主要的语法结构: ${sessionScope.user.sex} 所有EL都是以${ ...

  6. 【java8新特性】——Stream API详解(二)

    一.简介 java8新添加了一个特性:流Stream.Stream让开发者能够以一种声明的方式处理数据源(集合.数组等),它专注于对数据源进行各种高效的聚合操作(aggregate operation ...

  7. Lambada表达式全面详解

    Lambada表达式全面详解 文章目录 Lambada表达式全面详解 前言 入门 类名引用静态方法 对像名引用方法 构造器引用 前言 Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿 ...

  8. python lambda函数加法_python lambda的使用详解

    1. lambda语法 lambda argument_list: expression lambda是Python预留的关键字,argument_list(参数列表)和expression(关于参数 ...

  9. 线程,Java8,10个lambda表达式

    1. 线程. 同步,异步,线程互斥, 锁. .join, sleep, wait.. 三种创建模式 Thread class 继承 Thread 类 Runnable接口 实现 Runnable接口 ...

最新文章

  1. C语言下标要求数组或指针,c语言改错 error C2109: 下标要求数组或指针类型怎么改?...
  2. web中用纯CSS实现筛选菜单
  3. Leetcode 455.分发饼干 (每日一题 20210708 同类型题)
  4. python验证卡普耶卡(D.R.Kaprekar)6174猜想
  5. 回调函数自定义传参_10分钟教你手写8个常用的自定义hooks
  6. SQL2005 数据库数据同步
  7. [css] 怎样去除图片自带的边距?
  8. php proc open 返回,PHP proc_open多次打开
  9. 高光谱成像技术在茶叶中的应用研究进展
  10. 计算机网络波特率定义,传输速率——比特率和波特率
  11. ZEMAX | 如何使用渐晕系数
  12. vuex存储什么数据_Redis除了存储数据以外还能做什么?
  13. 一个人不孤单 想一个人才孤单
  14. 随着人工智能发展的少儿编程教育
  15. 安卓投屏神器scrcpy
  16. legacy服务器安装系统,支持UEFI和LEGACY的多系统安装U盘
  17. python爬虫之壁纸的下载
  18. VIPS算法对搜索引擎的意义[转载]
  19. 【密码学Sage代码】椭圆曲线加密/解密(基于《密码编码学与网络安全——原理与实践(第七版)》)
  20. Active Perl的PPM的repository添加

热门文章

  1. ocr文字识别html,LEADTOOLS 创建基于HTML5的零占用OCR文字识别
  2. uniapp Apple iOS 绑定解绑
  3. openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
  4. 计算机中丢失rtutil,api-ms-win-core-winrt-string-l1-1-0.dll从您的计算机中丢失
  5. Python版实现12306抢票功能,真的能帮你抢到春运回家的票吗?
  6. JAVA常见面试题及解答
  7. 使用Android Studio打包遇到的问题
  8. 0x0F1AFD76 (libcocos2d.dll) (Plane.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0x00000018 时发生访问冲突。
  9. JavaWeb之上传与下载
  10. html border线条重叠,关于border边框重叠颜色设置问题