赞
踩
JDK1.8中的lambda表达式到底实际工作中该怎么用啊?各种百度文章,不明所以,还是自己记录一下,留给自己做参考。
Lambda 表达式(lambda expression)是一个匿名函数,是一种函数式编程思想,是Java面向对象编程思想的进阶。Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Java,C#,Pythod都有其对应的lambda表达式(源自百度百科)。
还是有些不明白?知道算数表达式4*5=20,逻辑表达式a>b结果为true,那JDK1.8中的lambda表达式到底是个什么东西?都知道Java中可以对变量赋值People p=null,JDK1.8中的lambda表达式功能更强大了,可以将一段代码赋值给变量了,如下:
- //仅示例,实际编译不通过
- People p = public void eat(String food){
- System.out.println("正在吃"+food);
- };
将一些可以省略的东西进行省略——先省略public 关键字,其次是根据上面介绍的匿名函数的概念(重点是在于匿名),可以省略方法名eat;编译器可以自行推断返回类型void,这个可以进行省略;参数类型String,编译器也可推断;如果函数体中只有一行代码的话,也可以将花括号{}省略;最后将参数通过->传到函数体中,一个lambda表达式就这样形成了。
People p = (food)->System.out.println("正在吃"+food);
上述的People p只是示例,那么真正接收lambda表达式的变量是个什么类型?lambda表达式如何直白的总结?下面用熟知的Runnable接口来演示和解释:
- public static void main(String[] args) {
- //匿名内部类的方式创建线程
- Thread t1 = new Thread(new Runnable() {
- @Override
- public void run() {
- System.out.println(Thread.currentThread().getName());
- }
- });
- t1.start();
-
- //lambda表达式的方式创建线程
- Runnable r =()-> System.out.println(Thread.currentThread().getName());
- Thread t = new Thread(r);
- t.start();
- }
在用lambda表达式创建线程的方式上,接收lambda表达式的是一个Runnable接口,其实这个Runnable是一个函数式接口(细讲)。通过与匿名函数创建线程的方式比对发现,个人片面的理解其实lambda表达式就是函数式接口的一种具体实现。
(参数类型 参数名称, 参数类型 参数名称) ‐> { 表达体 }
规则一:无参无返回值
- Runnable r =()-> System.out.println(Thread.currentThread().getName());
- new Thread(r).start();
规则二:无参有返回值
lambda表达体只有一行语句时,可以省略return和花括号。
- Supplier<String> supplier = ()->new String("中国万岁");
- System.out.println(supplier.get());
规则三:有参无返回值
当有一个参数时,参数的小括号可以省略。
- Consumer<String> con = x -> System.out.println(x);
- con.accept("有参无返回值");
规则四:有参有返回值
有花括号存在,多条语句时,return不可省略。
- Comparator<Integer> com = (x, y) -> {
- System.out.println("函数式接口");
- return Integer.compare(x, y);
- };
- System.out.println(com.compare(10, 8));
Lambda表达式精简总结:
*简化参数类型,参数类型可以不写。
*当有一个参数时,参数的小括号可以省略。
*当只有一行语句时,可以省略表达体中的return和花括号。
1.遍历集合,不再使用for,foreach。
- List<String> stringList = Arrays.asList("a", "ab", "abc");
- stringList.forEach(x-> System.out.println(x));
2.对集合排序
- package com.sinosoft.service.impl;
- /**
- * @Author: qw
- * @Description: 学生类
- * @Date: 2021/5/10 23:34
- */
- public class Student {
-
- private String name;
- private int age;
-
- public Student(String name,int age){
- this.name=name;
- this.age=age;
- }
- //............
- @Override
- public String toString() {
- return name+":"+age;
- }
- }
- public static void main(String[] args) {
- //对集合排序
- List<Integer> list = Arrays.asList(10, 5, 8);
- Collections.sort(list, (x, y) -> Integer.compare(x,y));
- list.forEach(x-> System.out.println(x));
-
- Student stu1 = new Student("张三", 26);
- Student stu2 = new Student("李四", 22);
- Student stu3 = new Student("王五", 28);
-
- List<Student> studentList = new ArrayList<>();
- studentList.add(stu1);
- studentList.add(stu2);
- studentList.add(stu3);
- Collections.sort(studentList, (s1, s2) ->Integer.compare(s1.getAge(),s2.getAge()));
- studentList.forEach(x-> System.out.println(x.toString()));
- }
3.结合函数式接口,比如常用的断言型函数式接口,可以封装过滤操作(通过某些业务条件,删选一个集合的数据到一个新的集合中)。
- public static void main(String[] args) {
- List<Integer> list = new ArrayList<>();
- List<String> list1 = new ArrayList<>();
- List<Integer> numbers = Arrays.asList(10, 5, 8);
- List<String> strList = Arrays.asList("15588888888", "16788888888", "15888888888");
- //扩展用法一:筛选偶数集合
- filter(numbers,list,x ->(int)x % 2 == 0);
- list.forEach(System.out::println);
- //扩展用法二:筛选155开头的手机号
- filter(strList,list1,s->String.valueOf(s).startsWith("155"));
- list1.forEach(System.out::println);
- //扩展用法n.....
- }
-
- public static void filter(List oldList, List newList,Predicate condition) {
- oldList.forEach(x -> {
- if (condition.test(x)) {
- newList.add(x);
- }
- });
- }
4.结合StreamAPI,完成更复杂的操作。
本文参考文章及资料
https://www.cnblogs.com/myseries/p/13873670.html
https://www.runoob.com/java/java8-functional-interfaces.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。