【腾讯云】11.11 云上盛惠,云产品限时抢购,1核2G云服务器首年88元

搜搜吧

查看: 24|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    8 分钟前
  • 签到天数: 698 天

    [LV.9]以坛为家II

    博士生

    1万

    主题

    2万

    帖子

    5万

    积分

    Rank: 8Rank: 8

    UID
    15343
    威望
    -561
    贡献
    8107
    在线时间
    369 小时
    注册时间
    2015-10-12
    发表于 2020-10-16 15:12:03 | 显示全部楼层 |阅读模式

    2b4e6fb83fa5459daeb31dac02cbe2df.jpg-wh_651x-s_3265978323.jpg

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

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

    Lambda表达式小试牛刀

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

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

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

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

    • @FunctionalInterface
    • public interface Runnable {
    •     public abstract void run();
    • }

    Lambda表达式语法非常简单:

    • () -> System.out.println("hello java8 lambda")
    • ()括号里面是参数列表,如果只有一个参数还可以写为:a -> System.out.println(a)
    • -> 箭头为固定写法;
    • System.out.println("hello java8 lambda") 为函数主体,如果有多条语句要用花括号包裹起来, 比如下面这样:
    • (a, b) -> {int sum = a + b; return sum;}

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

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

    数只有一个可以省略括号

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

    • // before Java8
    • new Thread(new Runnable() {
    •     @Override
    •     public void run() {
    •         System.out.println("hello java8 without lambda");
    •     }
    • }).start();

    Lambda高阶用法

    (1)函数式接口

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

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

    • @FunctionalInterface
    • public interface Runnable {
    •     public abstract void run();
    • }

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

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

    (3)函数描述符

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

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

    • () -> void
    • lambda表达式可以写为
    • () -> System.out.println("hello java8 lambda")

    (4)常用函数式接口

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

    [td]
    函数式接口
    函数描述符
    PredicateT->boolean
    ConsumerT->void
    FunctionT->R
    Supplier() -> T
    UnaryOperatorT -> 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表达式写起来更加简介。举个栗子,按学生年龄排序:

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

    方法引用主要有三类:

    • 静态方法的方法引用

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

    • 任意类型实例方法的方法引用

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

    • 现有对象的实例方法的方法引用

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

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

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

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

    [td]
    lambda表达式
    方法引用

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

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


    搜搜吧社区温馨提示:
    搜搜吧(www.sosoba.org)十分重视网络版权及其他知识产权的保护,针对网络侵权采取如下版权政策:
    1、本站有理由相信网友侵犯任何人的版权或作品,(图文,文字,下载,视频,非法传播),本站有权不事先通知即删除涉嫌侵权的作品和内容
    2、本站将采取必要的网络技术手段,确认为侵权作品或内容的用户有权进行警告、屏蔽、删除的行为,尽可能的防止侵权行为的发生
    3、搜搜吧影视资源均收集自互联网,没有提供影片资源存储,也未参与录制上传,若本站收录的资源涉及您的版权或知识产权或其他利益,我们会立即删除
    4、搜搜吧,删帖,投诉,举报,侵权,若本站侵犯您的权益,附上身份及权利证明,请直接发送邮件到 kefu-sosoba@qq.com 我们将在一个工作日内删除
    Powered by www.sosoba.org Copyright © 2013-2020 搜搜吧社区 小黑屋|手机版|地图|联系站长|腾讯云代金券|帮助中心|公共DNS|seo优化服务|搜搜吧
    广告服务/项目合作/会员购买:QQ 侵权举报邮箱: kefu-sosoba@qq.com  搜搜吧建站时间:创建于2013年07月23日
    免责声明:本站所有的内容均来自互联网以及第三方作者自由发布,版权归原作者版权所有,搜搜吧不承担任何的法律责任,若有侵权请来信告知,我们立即删除!

    GMT+8, 2020-10-29 13:54 , Processed in 0.198097 second(s), 9 queries , MemCache On.

    快速回复 返回顶部 返回列表