jdk1.8

一、Java1.8新特性

1.Lambda表达式;

2.函数式接口;

3.方法引用和构造器引用;

4.Stream API;

5.接口中的默认方法与静态方法;

6.新时间日期API;

7.其他新特性。

二、Java1.8新特性简介

1.速度更快;

2.代码更少(新增了新的语法Lambda表达式);

3.强大的Stream API;

4.便于并行;

5.最大化减少空指针异常 Optional。

其中最为核心的是Lambda表达式与Stream API.

1.Lambda表达式

为什么使用Lambda表达式

(1)Lambda是一个匿名函数,我们可以把Lambda表达式理解为一段可以传递的代码(将代码像数据一样传递)。可以写出更加简洁、灵活的代码。作为一种更加紧凑的代码风格,使java的语言表达能力得到了提升。

(2)Lambda表达式的应用

从匿名类到Lambda的转换

匿名内部类作为参数传递

2.Lambda表达式语法

Lambda表达式在Java语言中引入了一个新的语法元素和操作符。这个操作符号为"->",该操符被称为Lambda操作符 或箭头操作符。它将Lambda分为两个部分:

左侧:指定了Lambda表达式的所有参数。

右侧:制指定了Lambda体,即Lambda表达式要执行的功能。

语法格式一:无参,无返回值,Lambda体只需一条语句

语法格式二:Lambda需要一个参数

格式语法三:Lambda只有一个参数的时候,参数的小括号可以省略

格式语法四:需要两个参数,并且有返回值

格式语法五:当lambda体中只有一条语句的时候,return与大括号可以省略

格式语法六:数据类型可以省略,因为可以由编译器推断得出称为“类型判断”

类型判断:

上述Lambda表达式中的参数类型都是有编译器推断得出的。Lambda表达式中无序指定类型,程序依然可以编译,这是因为javac根据程序上下文,在后台推断出参数的类型,Lambda表达式的类型依赖于上下文环境,是由编译器推断出来的,这就是所谓的“类型推断”。

2.函数式接口

什么是函数式接口

值包含一个抽象方法的接口,称为函数式接口。

你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)。

我们可以在任意函数式接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口,同事javac也会包含一条声明,说明这个接口是一个函数式接口。

自定义函数式接口

函数式接口中使用泛型:

作为参数传递的Lambda表达式:

作为参数传递的Lambda表达式:为了将Lambda表达式作为参数传递,接受Lambda表达式的参数类型必须是与该Lambda表达式兼容的函数式接口的类型。

Java内置的四大核心函数式接口

3.方法引用与构造器引用

方法引用

当要传递给Lambda体的操作,已经有实现方法了,可以使用方法引用!(实现抽象方法的列表,必须与方法引用方法的参数列表保持一致)

方法引用:使用操作符“::”将方法名和对象或类的名字分隔开来。

有如下三种情况:

对象::实例方法

类::静态方法

类::实例方法

方法引用范例:

例如:

等同于:

注意:当需要引用方法的第一个参数是调用对象,并且第二个参数是需要引用方法的第二个参数(或无参)时,ClassName::methodName

构造器引用

格式:ClassName::new

与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中的抽象方法的参数列表一致!

数组引用

格式:type[]::new

4.强大的Stream API

了解Stream

Java8中有两大最为重要的改变。第一个是Lambda表达式;另一个就是Stream API.

Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤映射数据等操作。使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。简而言之,Sream API提供了一种高效且易于使用的处理数据方式。

什么是Stream?

就是数据渠道,用于操作数据源(集合、数组)所产生的元素序列。“集合讲的是数据,流讲的是计算。”

注意:

1.Stream 自己不会存储元素。
2.Stream 不会改变源对象。相反,他们会返回一个持有结果的新的Stream。

3.Stream 操作时延迟执行的。这意味着他们会等到需要的结果的时候才会执行。

Stream操作的三个步骤

1.创建Stream

一个数据源(如:集合、数组),获取一个流

2.中间操作

一个中间操作链,对数据源的数据进行处理

3.终止操作(终端操作)

一个终止操作,执行中间操作链,并产生结果

1.创建Stream

Java8中的Collection接口被扩展,提供了两个获取流的方法:

default Stream<E>  stream() : d=返回一个顺序流;

default Stream<E> parallelStream() : 返回一个并行流。

由数组创建流

Java8中的Arrays的静态发方法stream()可以获取数组流:

String[] str=new String[16];

Stream s=Arrays.stream(str);

由值创建流

由函数创建流:创建无限流

Stream的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上出发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性安全的全部处理,称之为“惰性求值”;

Stream的终止操作

终端操作会从流水线上生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至void。

备注:map和reduce的链接通常称为map-reduce模式,因Google用它来进行网络搜索而出名。

Collector接口中方法的实现决定了如何对流执行收集操作(如收集到List、Set、Map)。但是Collectors实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

并行流与串行流

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。

Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性的通过parallel()与sequential()在并行流与顺序流之间进行切换。

5.新时间日期API

后续补充

6.接口中的默认方法与静态方法

Java8 中允许接口中包含具有具体实现的方法,该方法称为“默认方法”,默认方法使用default关键字修饰。

例如:

接口中的默认方法

接口中的默认方法的“类优先”原则

若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名的方法时:

1.选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。

2.接口冲突。如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法解决冲突。

接口中的静态方法

Java8中,接口中允许添加静态方法。

7.其他新特性

Optional类

Optional<T>类是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。

常用方法:

Optional.of(T t) : 创建一个Optional实例;

Optional.empty() : 创建一个空的Optional实例;

Optional.ofNullable(T t) :若t不为空创建一个Optional实例否则创建一个空实例;

isPresent() : 判断是否包含值;

orElse(T t) :如果调用对象包含值,返回该值,否则返回t;

orElseGet(Supplier s) : 如果调用对象包含值,返回该值,否则返回s获取的值;

map(Function f) : 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty();

flatMap(Function mapper) : 与map类似,要求返回值必须是Optional。

原文地址:https://www.cnblogs.com/yangsanluo/p/14156171.html