文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java8函数式接口和Lambda表达式,你真的会了吗

2024-12-03 18:35

关注

本文转载自微信公众号「爱笑的架构师」,作者雷架 。转载本文请联系爱笑的架构师 公众号。    

Java8 由Oracle在2014年发布,是继Java5之后最具革命性的版本了。Java8吸收其他语言的精髓带来了函数式编程,lambda表达式,Stream流等一系列新特性,学会了这些新特性,可以让你实现高效编码优雅编码。

Lambda表达式小试牛刀

Lambada表达式可以理解为:可传递的匿名函数的一种简洁表达方式。Lambda表达式没有名称,同普通方法一样有参数列表、函数主体、返回类型等;

下面简单看一个例子,new一个线程打印字符串,采用lambda表达式非常简洁:

  1. new Thread(() -> System.out.println("hello java8 lambda")).start() 

 Thread类接受一个Runnable类型实例,查看Jdk源码发现Runnable接口是一个函数式接口,可以直接用lambda表达式替代。

  1. @FunctionalInterface 
  2. public interface Runnable { 
  3.     public abstract void run(); 
  4. [[346665]]

Lambda表达式语法非常简单:

  1. () -> System.out.println("hello java8 lambda"[[346665]]

 

  1. (a, b) -> {int sum = a + b; return sum;} 

 综上,Lambda表达式模块可以固化为:

  1. (parameter) -> {expression} 或者 (parameter) -> {statements; statements; } 

 数只有一个可以省略括号

如果不用Lambda表达式,使用匿名内部类的方式,写法就不是那么优雅了。

  1. // before Java8 
  2. new Thread(new Runnable() { 
  3.     @Override 
  4.     public void run() { 
  5.         System.out.println("hello java8 without lambda"); 
  6.     } 
  7. }).start(); 

 Lambda高阶用法

(1)函数式接口

函数式接口是只定义了一个抽象方法的接口。注意Java8中允许存在默认方法(default),哪怕有很多默认方法,只要有且仅有一个抽象方法,那么这个接口仍然是函数式接口。

函数式接口通常在类上有一个注解@FunctionalInterface,如:

  1. @FunctionalInterface 
  2. public interface Runnable { 
  3.     public abstract void run(); 

 (2)函数式接口可以干什么?

通常lambda表达式与函数式接口结合一起用,lambda表达式以内联的形式为函数式接口的抽象方法提供实现,把整个表达式作为函数式接口的实例。在没有lambda表达式之前,我们通常会使用匿名内部类的方式实现,详细对比见第一小节的实例代码。

(3)函数描述符

函数式接口抽象方法的签名基本上就是lambda表达式的签名,我们可以将这种对应关系称为函数描述符。由一个函数式接口的抽象方法抽象为一个函数描述符,这个过程非常重要,知道了函数描述符去写lambda表达式也就非常容易了。举个例子:

Runnable接口有一个抽象方法 void run(), 接受空参数返回void,那么函数描述符可以推导为:

(4)常用函数式接口

java8 中常用函数式接口,针对基本类型java还定义了IntPredicate, LongPredicate等类型,详细可以参考jdk源码。

函数式接口 函数描述符
Predicate T->boolean
Consumer T->void
Function T->R
Supplier () -> T
UnaryOperator T -> T
BinaryOperator (T,T)->T
BiPredicate (L,R)->boolean
BiConsumer (T,U)->void
BiFunction (T,U)->R

至于 Predicate, Consumer, Function这些函数式接口具体作用,在后面的文章中会详细介绍,这里只需有个大体印象即可。

(5)将lambda表达式重构为方法引用

方法引用可以看作是lambda表达式的一种快捷写法,它可以调用特性的方法作为参数传递。你也可以将方法引用看作是lambda表达式的语法糖,让lambda表达式写起来更加简介。举个栗子,按学生年龄排序:

  1. // before 
  2. students.sort((s1, s2) -> s1.getAge.compareTo(s2.getAge())))); 
  3. // after 使用方法引用 
  4. students.sort(Comparator.comparing(Student::getAge())))); 

 方法引用主要有三类:

valueOf是String类的静态方法,方法引用写为 String::valueOf, 对应lambda表达式:a -> String.valueOf(a)

length是String类的实例方法,方法引用写为 String::length,对应lambda表达式:(str) -> str.length()

第三种容易与第二种混淆,现有对象指的是在lambda表达式中调用外部对象(不是入参对象)的实例方法,比如:

  1. String str = "hello java8"
  2. () -> str.length(); 

 对应方法引用写为 str::length, 注意不是 String::length

最后我们将三类方法引用归纳如下:

lambda表达式 方法引用  
(args) -> ClassName.staticMethod(args) ClassName::staticMethod 静态方法方法引用
(arg0, params) -> arg0.instanceMethod(params) ClassName::instanceMethod 内部实例方法引用
arg0
(params) -> arg0.instanceMethod(params)
arg0.instanceMethod 外部实例方法引用

总结:通过这篇文章的学习应该是对java8函数式编程和lambda表达式有了一个初步的了解,后面会有真实项目实战演练,敬请期待吧~

 

来源:爱笑的架构师内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯