目录 [−]
Java 8 Lambdas是O'Reilly 2014年3月出版的一本介绍最新Java Lambda技术的书。网上评价也不错。正好我需要找一本全面介绍Java Lambda数据, 来整理一下我脑海中的关于Java Lambda非系统的知识点。
Lambda对于我来讲,并不是一个很新的技术。因为微软很早就在C#中加入了Lambda的特性。 而Java Lambda的语法和C#的语法非常的相像。 这篇文章算是对Java Lambda语法的一个整理。
这本书一共十个章节。 第一章是简单介绍,没有实质内容。 第二章主要介绍了Java Lambda
的语法。第三章介绍了Stream
接口。第四章介绍了Functional Interface
。第五章 首先介绍了方法引用,然后主要介绍了集合类新的Stream处理方式。 第六章 介绍了数据的并行处理。 第七章介绍了测试,调试和重构技术。第八章介绍了使用lambda的设计和架构原则。
第九章介绍了并发编程中的Lambda的应用。 第十章 前瞻,无实质内容
第二章 Lambda表达式 (lambda expression)
介绍Lambda表达式一般都以匿名函数为例子, 说明Lambda表达式的简介。 例子一般为两个: 一个是Swing的事件处理, 如本书中举例, 另外一个以Runnable接口的实现为例。
|
|
Lambda表达式有很多简写方法, 如
|
|
无参数, 一个参数, 方法体只有一个表达式的情况,多个表达式的情况。 多个参数的情况。 定义表达式的参数类型等。
Lambda表达式的target type是指表达式出现的上下文的类型, 如上面的本地变量
noArguments
的类型, 或者作为方法参数调用时的方法参数的类型。
使用值
内部类是会遇到final 变量的情况。 lambda稍微放松了一些。 你可以使用非final的变量,但是你也不能在Lambda中更改它的值。
Functional Interfaces
没有上下文的Lambda表达式是没有意义的。一个Lambda表达式的target type总是一个Functional interface.
一些重要的Functional interface:
Interface name | Arguments | Returns | Example |
---|---|---|---|
Predicate | T | boolean | Has this album been released yet? |
Consumer | T | void | Printing out a value |
Function<T,R> | T | R | Get the name from an Artistobject |
Supplier | None | T | A factory method |
UnaryOperator | T | T | Logical not (!) |
BinaryOperator | (T, T) | T | Multiplying two numbers (*) |
Functional interface只能拥有一个显示声明的abstract方法。 可以包含多个default method。所以Functional interface也叫Single Abstract Method (SAM) interfaces。
类型推断
Java 8相比Java 7对类型推断更智能, 一般lambda 表达式中的参数类型可以省略,可以根据上下文推断得出。
Stream
为了充分利用Lambda, Java 8为集合框架增加了流式处理。
Stream接口提供了很多集合处理的方法。
调用集合类的stream方法:
|
|
filter是lazy的,不会马上执行一个loop, count是eager的会执行一次loop。 所以上面的只执行一次loop。勿用担心。
判断一个操作是lazy还是eager的方法是: 看返回结果。 返回结果还是stream, 那么它就是lazy的。如果返回其它值或者void, 它就是eager的。
整个处理有点像builder设计模式。
一些stream操作:
- collect(toList()): 得到一个List
- map: 将值映射成另外一个值
- flatMap: 将值替换成stream并将所有的stream合并成一个
- max and min
- reduce: 将得到的集合的值处理成单一的结果
|
|
多stream链式处理
|
|
可以写成
|
|
Higher-Order Functions
高位函数只它的参数可以是函数或者返回结果是函数。 map就是一个高位函数。它的mapper参数就是一个函数。
库Libraries
Java 8另一个重大改变是default method和接口的静态方法。
一个lambda应用的例子
我们输出log的时候考虑性能:
|
|
我们可以实现下面的logger:
|
|
基本类型
为基本类型特制的stream如LongStream.
重载
java无法区分的重载则编译失败
|
|
@FunctionalInterface
Binary Interface Compatibility
兼容性问题, 以及default method解决方案
Default Method
Collection增加了stream, Iterable增加了forEach.
|
|
继承中覆盖default method
菱形继承的问题: class win
多继承
可能会编译出错。 如果继承的几口中有相同的default method,必须显式继承。
三条原则
- Any class wins over any interface
- Subtype wins over supertype
- No rule 3 不满足上面两条则必须显示声明
接口可以定义静态方法!
Stream.of
Optional
|
|
Advanced Collections and Collectors
方法引用
Classname::methodName
Classname::new
String[]::new
元素排序
Collector
转换成其它集合类
得到单一值
分区
分组
字符串拼装
组合Collector
Collector复杂应用
数据并行处理
Parallelism vs. Concurrency
Concurrency 两个task处理时有重叠的时刻。
Parallelism是只两个task同时处理。 发生在多核的机器上。
Parallel Stream Operations
collection.stream().parallel()或者collection.parallelStream。
并不是parallelStream更快。 考虑你的数据量。 可能在很大的数据量的情况下才去用parallelStream。
Parallel Array Operations
Arrays类
Name | Operation |
---|---|
parallelPrefix | Calculates running totals of the values of |
parallelSetAll | Updates the values in an array using a lam |
parallelSort | Sorts elements in parallel |
测试, 调试和重构
point lambdafication
logger例子。
ThreadLocal例子:
|
|
|
|
将类似代码(并不是重复代码)重构成lambda表达式。
测试
lambda表达式没有名字,不能直接测试。
可以整体测试。
lazy and debugging
使用peak去输出对象。
设计和架构原则
SOLID原则: 单一功能、开闭原则、里氏替换、接口隔离以及依赖反转