JAVA8的新特性详解

简介

Oracle在2014年3月份发布了java8正式版,该版本增加了很多新特性,比如:函数式接口、lambda表达式、集合的流式操作、注解的更新、安全性增强、IO\NIO的改进

函数式接口

什么是函数式接口

这是java8的一个核心概念,(Functional Interfaces).通过在接口中添加一个抽象方法,这些方法可以直接从接口中运行。我们有两种方法去实现一个函数式接口 
1. 在一个接口中定义唯一一个抽象方法,那么这个接口就成为函数式接口 
2. 通过注解@functionalInterface,用来标注这个接口是一个函数式接口。推荐这种写法,好处是如果接口不符合函数式接口的定义时,编译器会报错 
Java.lang.Runnable就是一个典型的函数式接口;

函数式接口的用途

主要用在Lambda表达式和方法引用上

代码演示

JAVA8的新特性详解

 

函数式接口的特性

JAVA8的新特性详解

  1. 函数式接口允许定义静态方法
  2. 函数式接口允许定义default方法
  3. 函数式接口里允许定义java.lang.Object里的public方法 

泛型及继承关系

接口可以继承接口,如果一个父接口是一个函数接口,那么子接口也有可能是一个函数式接口,那么它的判断依据是什么呢? 
对于接口I, 假定M是接口成员里的所有抽象方法的继承(包括继承于父接口的方法), 除去具有和Object的public的实例方法签名的方法, 那么我们可以依据下面的条件判断一个接口是否是函数式接口, 这样可以更精确的定义函数式接口。 
如果存在一个一个方法m, 满足: 
• m的签名(subsignature)是M中每一个方法签名的子签名(signature) 
• m的返回值类型是M中的每一个方法的返回值类型的替代类型(return-type-substitutable) 
那么I就是一个函数式接口。

情况一

 JAVA8的新特性详解


接口Z继承了X,Y接口的m方法,由于这两个方法的签名相同,返回值也一样,所以Z有唯一的一个抽象方法int m(List arg);,可以作为函数式接口。

情况二

JAVA8的新特性详解
方法签名Y.m既满足签名是X.m,并且返回值也满足,所以Z仍然是函数式接口

情况三

 JAVA8的新特性详解
编译出错,因为没有一个方法的签名是所有方法的子签名

Java.util.function

Lambda表达式在运行期间表示为一个接口函数,而接口函数只是一种只定义了一个抽象方法的接口。尽管java8里面已经有一些接口符合函数式接口的定义,比如Runnable , Comparator。但是对于我们来说显然是不够的。而如果我们需要在程序里使用非函数数接口来实现lambda表达式的操作,那么怎么去做? Java8引入了一个新增的包java.util.function, 专门用来解决这个问题。这个包里提供了很多接口 

JAVA8的新特性详解

Lambda表达式

函数式接口的重要属性是:我们能够使用Lambda来实例化他们,Lambda表达式让你能够将函数作废方法参数,或者将代码作为数据对待。

优点

在java8出现之前,匿名内部类,监听器和事件处理的使用都显得很冗长,代码可读性差,而Lambda表达式的应用能够是代码变得更加紧凑,可读性增强

语法

Lambda表达式由三个部分组成: 
第一部分:一个括号内用逗号分割形式参数,参数是函数式接口里面方法的参数 
第二部分:一个箭头号 -> 
第三部分:方法体,可以是表达式和代码块

情况一

方法体为表达式,则该表达式的值作为返回值返回: 
JAVA8的新特性详解

情况二

方法体为代码块,必须要用{}包裹起来,如果该接口有返回值,则需要return返回值,反之则不需要 

JAVA8的新特性详解

代码演示

情况1, 对内部类进行简化 
 JAVA8的新特性详解

情况2,我们用list排序来演示效果 
JAVA8的新特性详解

简化处理后

JAVA8的新特性详解

方法引用

有时候Lambda表达式的代码只是一个简单的方法调用而已,而遇到另外一种情况我们可以更进一步去简化,我们称之为方法引用;

引用静态方法

引用对象的实例方法

引用某个类型的任意对象的实例方法

引用类构造函数

代码演示 
我们同样针对一个数组进行排序,综合以上所有提到的方法引用类型 
第一步 
 JAVA8的新特性详解


第二步 

 JAVA8的新特性详解
第三步 
 JAVA8的新特性详解

集合流式操作

Java8引入了流式操作(Stream),通过该操作可以实现对集合的并行处理和函数式操作。 
1. 根据操作返回的结果不同,流式操作又分为中间操作和最终操作。最终操作返回的是一个特定类型的结果;而中间操作返回的是流本身,因此就可以将多个操作一次串联起来; 
2. 根据流的并发性、又可以分为串行和并行两种,流式操作实现了对集合的过滤、排序、映射等功能

串行流和并行流

通过串行流操作是在一个线程中依次完成,而并行流则是在多个线程上同时执行。并行和串行的流操作可以相互切换:通过 
Stream.sequential()返回串行流 
Stream.parallel() 返回并行流 
相比于串行流,并行流可以很大程度上提高程序的执行效率 
串行/并行排序演示 

JAVA8的新特性详解

JAVA8的新特性详解

中间操作

该操作会保持 stream 处于中间状态,允许做进一步的操作。它返回的还是的 Stream,允许更多的链式操作。常见的中间操作有: 
filter():对元素进行过滤; 
sorted():对元素排序; 
map():元素的映射; 
distinct():去除重复元素; 
subStream():获取子 Stream 等。

终止操作

该操作必须是流的最后一个操作,一旦被调用,Stream 就到了一个终止状态,该操作之后不能再链式的添加其他操作。常见的终止操作有: 
forEach():对每个元素做处理; 
toArray():把元素导出到数组; 
findFirst():返回第一个匹配的元素; 
anyMatch():是否有匹配的元素等。

788692365阿里P8在此群,可以在这里和他进行java高级、架构方面的经验学习交流。

JAVA8的新特性详解

另有咕泡Java架构VIP七夕520告白金抽取机会

JAVA8的新特性详解