浅谈Java1.8的新特性

基本上很多面试者会被问到了,你了解一下JDK 1.8的新特性请说说看,这个时候才意识到它的重要,其实好多已经用在了项目中,在这里给大家总结一下。

1.速度更快

 1.1 优化了HashMap以及ConcurrentHashMap

在1.8之后,在数组+链表+红黑树来实现hashmap,当碰撞的元素个数大于8时并且总容量大于64,会有红黑树的引入。除了添加之后,效率都比链表高,1.8之后链表新进元素加到末尾 ConcurrentHashMap (锁分段机制),1.8采用CAS算法(无锁算法,不再使用锁分段),数组+链表中也引入了红黑树的使用。

CAS(Compare-And-Swap) 算法保证数据变量的原子性,是硬件对于并发操作的支持,这个会在后面的文章中详细讲解。

 1.2 内存 

JDK1.8以前内存分为栈、堆、方法区。JDK1.8之后,方法区变成了MetaSpace元空间(采用的物理内存),元空间属于本地内存,所以元空间的大小仅受本地内存限制,但是可以通过-XX:MaxMetaspaceSize进行增长上限的最大值设置,默认值为4G,元空间的初始空间大小可以通过-XX:MetaspaceSize进行设置。

2.代码更少 

2.1 新增语法lambda表达式 

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

2.2 Lambda的语法元素和操作符 

Consumer fun=(args)->System.out.println(args);

操作符(—>)左侧:指定了Lambda表达式需要的所有参数。

操作符(—>)右侧:指定了Lambda体,即Lambda 表达式要执行的功能。

2.3 函数式接口

消费型接口 Consumer 有参数无返回 对类型为T的对象应用操作,包含方法:void accept(T t)
供给型接口 Supplier 有参数有返回T 返回类型为T的对象,包含方法:T get()
函数型接口 Function 有参数有返回R 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t)
断定型接口 Predicate 有参数有返回boolean 确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法boolean test(T t)

2.4 方法&构造器&数组引用

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

  1. 方法引用 ClassName::methodName
  2. 构造器ClassName::new
  3. 数组引用type[]::new

比如数组引用:

Function fun = (n) -> new Integer[n];//原生方式实现

Function fun = Integer[]::new;//数组引用方法实现

3.强大的Stream API

Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用StreamAPI对集合数据进行操作,就类似于使用SQL执行的数据库查询。 

3.1 创建流

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

3.2 中间操作

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

3.2.1 筛选与切片

filter(Predicate p) 接收Lambda从流中排除某些元素。
distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
limit(long maxSize) 截断流,使其元素不超过给定数量。
skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补

3.2.2 映射

map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

3.2.3 排序

sorted() 产生一个新流,其中按自然顺序排序。
sorted(Comparator comp) 产生一个新流,其中按比较器顺序排序。

3.2.4 查找与匹配

allMatch(Predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
count() 返回流中元素总数
max(Comparator c) 返回流中的最大值
min(Comparator c) 返回流中的最小值
forEach(Consumer c c) 内部迭代( (使用Collection接口需要用户去做迭代,称为外部迭代。相反,Stream API使用内部迭代)

3.2.5 归约

reduce(T iden, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T
reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 Optional

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

3.2.6 收集

collect(Collector c) 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

3.3 终止操作

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

4.便于并行

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。Stream API 可以声明性地通过 parallel() 与sequential() 在并行流与顺序流之间进行切换。

Fork/Join框架是Java 7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

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

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。常用方法如下:

Optional.of(T t)  创建一个 Optional实例
Optional.empty() 创建一个空的 Optional 实例
Optional.ofNullable(T t) 若 t 不为 null,创建 Optional 实例,否则创建空实例。
isPresent() 判断是否包含值。
orElse(T t) 如果调用对象包含值,返回该值,否则返回 t
orElseGet(Supplier s) 如果调用对象包含值,返回该值,否则返回 s 获取的值。
map(Function f) 如果有值对其处理,并返回处理后的 Optional,否则返回 Optional.empty()
flatMap(Function mapper) 与 map 类似,要求返回值必须是 Optional

6.新时间日期API

使用LocalDate 、LocalTime 、LocalDateTime分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。

Duration用于计算两个时间间隔,Period用于计算两个日期间隔。

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

7.1 Java8中允许接口中包含具有具体实现的方法

该方法称为默认方法,默认方法使用 default 关键字修饰。

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

7.3 接口默认方法的类优先原则

若一个接口中定义了一个默认方法,而另外一个父类或接口中又定义了一个同名的方法时选择父类中的方法。如果一个父类提供了具体的实现,那么接口中具有相同名称和参数的默认方法会被忽略。接口冲突。如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突。

 

--------------如果大家喜欢我的博客,可以点击左上角的关注哦。

你可能感兴趣的:(Java进阶)