JDK8:lambda表达式简介

背景

在Java编码中,经常性的会使用到匿名类,有些时候,这些匿名类非常简单,里面仅包含一个方法,类如Runnable接口,这种匿名类写起来会非常的难看。其实我们仅仅想把这个唯一的一个方法当做参数传递,在JDK8中,Lambda表达式这个特性就能满足你的这个需求。
From

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello lambda!");
            }
        });

To

new Thread(() -> System.out.println("hello lambda!"));

语法

一个Lambda表达式包含如下三个部分

参数列表 箭头符号 函数体
(int x, int y) -> x + y

函数体可以是一行表达式,也可以是一段代码块。几个例子如下:

(int x, int y) -> x + y
() -> 42
(String s) -> { System.out.println(s); }

第一个参数为x和y,返回x+y的结果
第二个无参,直接返回42
第三个接收一个String类型,并打印出来
一般仅包含一个方法的匿名类,均可以使用lambda表达式的方法书写。

java.util.function包

这里为什么提到这个包呢,因为lambda表达式要求,匿名类中仅有一个未实现的方法,这样才能写成上述的形式,在java.util.function包中,有一些大家较为熟悉的接口,如

  • Predicate: 测试一个传入的参数是否符合要求
  • Consumer: 消费传入的参数,对传入的参数进行对应的处理
  • Function: 对传入的T类型参数转换成R类型的返回
  • Supplier: 生成一个T类型的对象,类似Factory方法

示例

  • Predicate
    可以直接使用
        Predicate<String> p =(s)->s.indexOf("a")>-1;
        Predicate<String> p1=(s)->s.endsWith("b");
        System.out.println(p.test("sda")); //直接使用p校验
        System.out.println(p.and(p1).test("asdb")); //p和p1两个条件联合校验

或者结合类似filter方法使用

        Optional<String> optional=Optional.of("aaa");
        System.out.println(optional.filter(s -> s.indexOf("b")>-1)); 
  • Consumer
        Consumer<String> c = s -> System.out.println(s + "aaa");
        Consumer<String> c1 = s -> System.out.println(s + "bbb");
        c.accept("as");
        c.andThen(c1).accept("as");

或者结合类似Optional中的ifPresent使用

        Optional<String> optional = Optional.of("aaa");
        optional.ifPresent(s -> System.out.println(s));
  • Function
        Function<String,Integer> f=s -> Integer.parseInt(s);
        System.out.println(f.apply("123"));

或者结合Optional中的map方法使用

        Optional<String> optional = Optional.of("123");
        optional.map(s -> Integer.parseInt(s));
  • Supplier
        Supplier<String> s= () -> "asd";
        System.out.println(s);
        Supplier<String> s= () -> "asd";
        System.out.println(s);

实现

翻看源码,会发现上述的接口,均使用了@FunctionalInterface注解

@FunctionalInterface
public interface Consumer<T> {

查看其说明,这个注解仅适用于接口,且要求接口中仅包含一个未实现的方法(默认实现不算在内),若我们的接口中包含1个以上的未实现的方法的时候,编译的时候会提示错误

image.png

所以这个java.util.function包中的接口简直就是给lambda表达式定制的。

后注

然而,在性能方面,大部分的时候,直接使用lambda表达式的表现并不比传统的写作方式好,例如下面两块代码

        for (int i = 0; i < 10000; i++) {
            optional.filter((s) -> s.indexOf("b") > -1);
        }
        for (int i = 0; i < 10000; i++) {
            optional.filter(new Predicate<String>() {
                @Override
                public boolean test(String s) {
                    return s.indexOf("b") > -1;
                }
            });
        }

耗费的时间,一个是43,一个是3,相差接近10倍,但是如果我将上面的代码块写成如下

        Predicate<String> p = (s) -> s.indexOf("b") > -1;
        for (int i = 0; i < 10000; i++) {
            optional.filter((s) -> s.indexOf("b") > -1);
        }

两种的时间消耗就差不多,所以就现在的编译器(本地使用的1.8_111的版本)而言,在lambda上面的优化显然没有传统的匿名类做的好,所以个人有如下几点建议

  • 在有大量循环的时候,建议使用传统方式
  • 在无性能要求或者相差不大的情况下,当然是lambda
  • 当使用到Stream API的时候,优先考虑使用parallelStream并行流来处理
  • 现在JDK的版本已经发布到10,后面针对lambda的优化一定会提上日程,所以还是建议大家可以现在开始尝试使用,感受一下函数式变成的魅力

借鉴

感谢阅读!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354