关于Lambda表达式的整理

前段时间的面试基本结束了,最后也有了不错的结果,之后一段时间到入职打算好好整理一些东西。
想到马上Java9也要出来了,Android也马上支持Java8,自己都没有好好整理过java8比较重要的知识点,可以说8很多改动都是为了Lambda服务的,所以整理一下Lambda的内容。

关于闭包

首先闭包是指,将当前作用域中的变量通过值或者引用的方式封装到lambda表达式中,成为表达式的一部分,它使你的lambda表达式从一个普通的函数变成带隐藏参数的函数,当然闭包也可以不通过lambda实现

简单理解为闭包就是定义在函数内部的函数

Lambda 表达式与匿名类的区别

  • Lambda 表达式与匿名类的主要不同在于两者的编译方法
  • 对于匿名类,关键词 this 解读为匿名类,而对于 Lambda 表达式,关键词 this 解读为写就 Lambda 的外部类

什么时候用

任何可以接受一个函数式接口的地方都可以用lambda表达式
lambda作用在于

  • 逻辑更紧凑
  • 引入闭包,更简洁的实现闭包
  • 允许函数方法作为对象传递

函数式接口

定义

所谓的函数式接口,也叫SAM接口(Single Abstract Method interfaces),当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法

  • 函数式接口里允许定义默认方法
  • 函数式接口里允许定义静态方法
  • 函数式接口里允许定义java.lang.Object里的public方法
    //以下都是不会报错的
    @FunctionalInterface
    interface GreetingService{
        void sayMessage(String message);

        default void doSomeMoreWork1()
        {
            // Method body
        }
        static void printHello(){
            System.out.println("Hello");
        }
        @Override
        boolean equals(Object obj);
    }

@FunctionalInterface注解

加不加@FunctionalInterface对于接口是不是函数式接口没有影响,只是提醒编译器去检查该接口是否仅包含一个抽象方法,用于编译级错误检查

新增java.util.function

  • Predicate:用于判断一个对象是否满足某种条件,只有一个test抽象函数,接受一个泛型T对象返回boolean
  • Consumer:用于对对象进行消费操作,只有一个accept抽象函数,接受一个泛型对象无返回
  • Function:用于对象的转换,只有一个apply抽象函数,接受一个泛型T,返回一个泛型R
  • Supplier:用于创建对象
  • 还有一些衍生的可以自己看包下源码

使用

使用相信大家都会一些,我就不列举,网上大把的文章,下面两篇总结不错

深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)

10个实例表达式

原理

Java 编译器编译 Lambda 表达式并将他们转化为类里面的私有静态函数

  • 它使用 Java 7 中新加的 invokedynamic,运行时调用LambdaMetafactory.metafactory动态的生成内部类,实现了接口
  • 生成一个类私有静态函数,在生成的实现类中调用

关于 Java 如何将 Lambda 表达式编译为字节码

国外的一篇写的不错

通俗易懂的解释

interface Print<T> {
    public void print(T x);
}
public class Lambda {   
    public static void PrintString(String s, Print<String> print) {
        print.print(s);
    }
    public static void main(String[] args) {
        PrintString("test", (x) -> System.out.println(x));
    }
}

通过编译最终等价于

interface Print<T> {
    public void print(T x);
}
public class Lambda {   
    public static void PrintString(String s, Print<String> print) {
        print.print(s);
    }
    private static void lambda$0(String x) {
        System.out.println(x);
    }
    final class $Lambda$1 implements Print{
        @Override
        public void print(Object x) {
            lambda$0((String)x);
        }
    }
    public static void main(String[] args) {
        PrintString("test", new Lambda().new $Lambda$1());
    }
}

关于性能

Oracle写的lambda表现文档

16页讲到最差(capture)也和inner class一样, non-capture好的情况是inner class的5倍

image1
image1

但是在使用Stream的时候并不是所有情况都比普通迭代快的

下面这篇文章比较了各种情况下imperative code与functional code的性能表现

The effects of programming with Java 8 Streams on algorithm performance

关于Streams

Lambda最佳结合应该就是Stream了,函数式编程与简洁的结合
Java 8的Stream内置了许多类似于数据库的操作filter、sort、map、reduce等
用法就不贴了,大把文章
官方的在这里

Stream优点:

  • 以数据库操作数据的方式,专注于如何做这个某个步骤,表达式的方式

  • 高并发(看到map、reduce就应该能想到了)

刚开始看Stream感觉和RxJava非常像,但是仔细思索后有发现其实是两个不同的东西,只是长得像而已。
下面这个最高票回答总结的非常好,总体来说

  • stream是单次使用,是基于被动PULL
  • rx是基于观察者模式,可多次订阅,是基于主动PUSH

Stream与Rxjava的不同

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

推荐阅读更多精彩内容

  • 本文是对 Brian Goetz 的 State of Lambda 一文的翻译 为什么要翻译这个系列? andr...
    aaron688阅读 3,864评论 4 31
  • 摘要:此篇文章主要介绍 Java8 Lambda 表达式产生的背景和用法,以及 Lambda 表达式与匿名类的不同...
    OneAPM阅读 2,071评论 0 26
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,626评论 18 139
  • lambda表达式(又被成为“闭包”或“匿名方法”)方法引用和构造方法引用扩展的目标类型和类型推导接口中的默认方法...
    183207efd207阅读 1,473评论 0 5
  • 《断剑》 文/刘汉皇 剑死了,在绝望中死去在轰鸣的车间死去在高大的炼钢炉融化死去的还有他的魂,他的梦 他饮过匈奴的...
    刘汉皇阅读 504评论 15 8