Java8(又称jdk1.8)是Java语言开发的一个主要版本。Oracle公司与2014年3月18日发布Java8,它支持函数式编程,新的JavaScript引擎,新的日期API,新的StreamAPI等。今天,让我们一起来学习Java8的新特性。
目录:
一、接口内允许添加默认实现的方法
二、Lambda表达式
三、函数式接口Functional Interface
四、便捷的引用类的构造器及方法
五、Lambda访问外部变量节接口默认方法
5.1 访问局部变量
5.2 访问成员变量及接口默认方法
5.3 访问接口的默认方法
六、内置的函数式接口
6.1 Prdicate断言
6.2 Function
6.3 Supplier生产者
6.4 Consumer消费者
6.5 Comparator
七、Optioal
八、Streams流
8.1 Filter流
8.2 Sorted 排序
8.3 Map转换
8.4 Match匹配
8.5 Count计数
8.6 Reduce
九、Parallel Streams并行流
9.1 顺序流排序
9.2 并行流排序
十、Map集合
十一、新的日期API
11.1 Clock
11.2 Timezones时区
11.3 LocalTime
11.4 LocalDate
11.5 LocalDateTime
十二、Annotations注解
更多的新特性可以参阅官网:What's New in JDK 8
正文:
接口内允许添加默认实现的方法
Java8允许我们通过default关键字对接口中定义的抽象方法提供一个默认的实现。
请看下面示例代码:
在上面个这个接口中,我们除了定义了一个抽象方法calculate,还定义了一个带有默认实现的方法sqrt。我们在实现这个接口时,可以只需要实现calculate方法,默认方法sqrt可以直接调用即可,也就是说我们可以不必强制实现sqrt方法。
补充:通过default关键字这个新特性,可以非常方便地对之前的接口做扩展,而此接口的实现类不必做任何改动。
上面通过匿名对象实现了Formula接口。但是即使是这样,我们为了完成一个sqrt(a*100)简单计算,就写了6行代码,很是冗余。
Lambda表达式
在学习Lambda表达式之前,我们先看一段老版本的示例代码,其对一个含有字符串的集合进行排序:
Collections工具类提供了静态方法sort方法,入参是一个List集合,和一个Comparator比较器,以便对给定的List集合进行排序。上面的示例代码创建了一个匿名内部类作为入参,这种类似的操作在我们的日常工作中随处可见。
Java8中不再推荐这种写法,而是推荐使用Lambda表达式。
Java8中不再推荐这种写法,上面的这段代码变得简短很多而且易于阅读。但是我们可以载精炼一点。
对于只包含一行方法的代码块,我们可以省略大括号,直接return关键代码即可。追求极致,我们还可以让它再短点。
List集合现在已经添加了sort 方法。而且Java编译器能够根据类型推断机制判断出参数类型,这样,你连入参的类型都可以省略啦,怎么样,是不是感觉很强大呢!
函数式接口Functional Interface
抛出一个疑问:在我们书写一段Lambda表达式后(比如上一章节中匿名内部类的Lambda表达式缩写形式),Java编译器是如何进行类型判断的,它又是怎么知道重写的哪个方法的?
需要说明的是,不是每个接口都可以缩写成Lambda表达式。只有那些函数式接口(Functional Interface)才能缩写成Lambda表达式。
那么什么是函数式接口(Functional Interface)呢?
所谓函数式接口(Functional Interface)就是只包含一个抽象方法的声明。针对该接口类型的所有Lambda表达式都会与这个抽象方法匹配。
注意:你可能会有疑问,Java8中不是允许通过default关键字来为接口添加默认方法的吗?那它算不算抽象方法呢?答案是:不算。因此,你可以毫无顾忌的添加默认方法,它并不违反函数式接口(Functional Interface)的定义。
总结一下:只要接口中仅仅包含一个抽象方法,我们就可以将其改写为Lambda表达式。为了保证一个接口明确的被定义为一个函数式接