脑图
代码地址:
https://github.com/hufanglei/daily-code/tree/first-java8/src/com/java8demo
jdk8
一、lambda
1.本质
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)
2.语法
可选类型声明
不需要声明参数类型,编译器可以统一识别参数值
可选的参数圆括号
一个参数无需定义圆括号,但多个参数需要定义圆括号
可选的大括号
如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字
如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
3.应用案例
4种可以简写的方式 简写参数类型,简写参数括号,简写方法主体的大括号,简写返回值,自定义方法类型接口:类似js的回调函数,比js笨重,需要,指定回调函数名和方法名,而js不需要
变量作用域
lambda 表达式只能引用标记了 final 的外层局部变量
内部final变量访问
1.lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
2,.在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
ambda简化匿名内部类案例:
本质
在匿名内部类中,有很多内容都是冗余的。
比如在使用匿名内部类实现多线程的代码中。
因为 Thread 构造方法中需要传递 Runnable 接口类型的参数,所以我们不得不 new Runnable。
因为要重写 Runnable 中的 run 方法,所以不得不写了public void run。
整个匿名内部类中最关键的东西是方法,方法中最关键的有前中后三点。
前:参数。
中:方法体
后:返回值
最好的情况是只关注匿名内部类中最核心的这些内容(方法参数,方法体,返回值)如果使用Lambda表达式,可以只关注最核心的内容,Lambda 表达式是匿名内部类的简化写法。
demo
lambda实现runable接口
lambda 实现集合排序
Lambda 表达式对中文排序
二.方法引用
1.方法引用通过方法的名字来指向一个方法。
2. 分类
构造器引用
Car::new
静态方法引用
Car::staticMethod
特定类的任意对象的方法引用
Car::method
特定对象的方法引用
car::method
三、函数式接口
1.函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
2.函数式接口可以被隐式转换为 lambda 表达式
3.java.util.function 包
Supplier
Consumer
Function
Operator
4.注意
@FunctionalInterface
主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错
函数式接口里允许定义静态方法
函数式接口里允许定义 java.lang.Object 里的 public 方法
函数式接口里是可以包含Object里的public方法,这些方法对于函数式接口来说,不被当成是抽象方法(虽然它们是抽象方法);因为任何一个函数式接口的实现,默认都继承了 Object 类,包含了来自 java.lang.Object 里对这些抽象方法的实现;
四、默认方法
1、定义
默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。
只需在方法名前面加个 default 关键字即可实现默认方法
为什么要有这个特性
当需要修改接口时候,需要修改全部实现该接口的类,目前的 java 8 之前的集合框架没有 foreach 方法,通常能想到的解决办法是在JDK里给相关的接口添加新的方法及实现。然而,对于已经发布的版本,是没法在给接口添加新方法的同时不影响已有的实现。所以引进的默认方法。他们的目的是为了解决接口的修改与现有的实现不兼容的问题。
2.多个默认方法
解决方案
Vehicle.super.print();
3.静态默认方法
可以声明(并且可以提供实现)静态方法
五、stream
1.本质
来自数据源的元素队列并支持聚合操作
元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
2.数据源流的来源
集合,数组,I/O channel, 产生器generator
3.聚合操作
类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等
4.特别注意点
Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代
以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现
5.生成流方式
stream() − 为集合创建串行流
parallelStream() − 为集合创建并行流
6.实操
stream forEach
map
filter count
limit sorted
Collectors 规约
tolist
joining
统计summaryStatistics
max
min
avg
sum
六、Optional 类
1.定义
是一个可以为null的容器对象
如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象
它可以保存类型T的值,或者仅仅保存null
Optional提供很多有用的方法,这样我们就不用显式进行空值检测
2. 好处
Optional 类的引入很好的解决空指针异常
3.实操
ofNullable
允许传递为 null 参数
of
如果传递的参数是 null,抛出异常 NullPointerException
isPresent
判断值是否存在,存在则返回true,不存在则返回false
orElse
果值存在,返回它,否则返回默认值
get
获取值,值需要存在
七、Nashorn JavaScript
1.定义
Nashorn 一个 javascript 引擎
从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java的嵌入式JavaScript引擎
Nashorn完全支持ECMAScript 5.1规范以及一些扩展
它使用基于JSR 292的新语言特性,其中包含在JDK 7中引入的 invokedynamic,将JavaScript编译成Java字节码
与先前的Rhino实现相比,这带来了2到10倍的性能提升
2.jjs
jjs 交互式编程
传递参数
3.Java 中调用 JavaScript
4.JavaScript 中调用 Java
八、日期时间 API
1.旧版的 Java 中,日期时间 API 存在诸多问题
非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的
2.设计很差 −
在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义
时区处理麻烦
日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类
3.Date-Time API (JSR 310)
Local(本地) − 简化了日期时间的处理,没有时区的问题
Zoned(时区) − 通过制定的时区处理日期时间。
4.实操
本地化日期时间 API
LocalDateTime
toLocalDate
getDayOfMonth getSecond()
withDayOfMonth withYear
LocalDate
of
LocalTime
parse
使用时区的日期时间API
ZonedDateTime
parse
ZoneId
of
systemDefault
九、Base64
①1.8中引入了Base64,不在需要引入第三方库就可以使用base64了
②内嵌类
解码Base64.Decoder
getDecoder()
getMimeDecoder()
getUrlDecoder()
编码Base64.Encoder
完