你对jdk1.8了解多少?

由于今年起,公司要求新项目一律改用SpringBoot框架,而从SpringBoot 2.0.0开始,对于jdk的版本要求从原来的1.7改至1.8,与同事交流发现,他们对于jdk1.8特性的认知并不是那么的全面,有些能说出Lambda 表达式,有些则完全没有概念。那么对于2014年发布的jdk1.8的特性,你了解多少呢?在实际的编码中,你会想起用到的特性又有哪些?

  • 1. 对于HashMap的优化

在jdk1.8之前,HashMap集合一直以数组+链表的数据结构来存储数据,而在JDK1.8版本中对其做了优化,引入了红黑树,当链表的长度超过阈值时,链表就转换为红黑树,利用红黑树的快速增删改查的特点来提高HashMap的性能。

 

 

  • 2. 引入default关键字,允许给接口添加一个非抽象方法。

在jdk1.8之前,我们通常认为接口中只能有抽象方法,而在jdk1.8,通过default关键字可以添加一个非抽象的方法,其实就是给接口定义了一个默认的方法,该接口的实现类,可以直接调用接口中用default修饰的方法,可以不用去实现它。这样可以简化代码量。

 

  • 3. Lambda 表达式

这里引用百度百科对于Lambda表达式的定义:

Lambda表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

其实Lambda表达式对于java来说,算是一种新的语法,但它在C#,Pytyon,c++中都有应用。在Java中通过“->”这一新的操作符,使得代码变得简洁,灵活。

  • 4. 函数式接口

函数式接口就是指仅有一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为 默认方法 不算抽象方法,所以你也可以给你的函数式接口添加默认方法。而在jdk1.8中,则使用@FunctionalInterface注解来定义函数式接口。这个注解可以起到校验的作用,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的(不加也对)。

 

  • 5.方法与构造函数的引用

jdk1.8提供了另外一种调用方式::,当你需要使用方法引用时,目标引用放在分隔符::前,方法的名称放在后面,即ClassName :: methodName。

 

  • 6. 局部变量限制

Lambda表达式也允许使用自由变量(不是参数,而是在外层作用域中定义

的变量),就像匿名类一样。 它们被称作捕获Lambda。 Lambda可以没有限制地捕获(也就是在其主体中引用)实例变量和静态变量。但局部变量必须显式声明为final,或事实上是final。
  为什么局部变量有这些限制?
  (1)实例变量和局部变量背后的实现有一个关键不同。实例变量都存储在堆中,而局部变量则保存在栈上。如果Lambda可以直接访问局部变量,而且Lambda是在一个线程中使用的,则使用Lambda的线程,可能会在分配该变量的线程将这个变量收回之后,去访问该变量。因此, Java在访问自由局部变量时,实际上是在访问它的副本,而不是访问原始变量。如果局部变量仅仅赋值一次那就没有什么区别了——因此就有了这个限制。
  (2)这一限制不鼓励你使用改变外部变量的典型命令式编程模式。

  • 7. Optional类

空指针异常是导致Java应用程序失败的最常见原因,以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到 Google Guava的启发,Optional类已经成为Java 8类库的一部分。Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

创建Optional对象的几个方法:

  1. Optional.of(T value), 返回一个Optional对象,value不能为空,否则会出空指针异常

2. Optional.ofNullable(T value), 返回一个Optional对象,value可以为空

3. Optional.empty(),代表空

其他API:

1. optional.isPresent(),是否存在值(不为空)

2. optional.ifPresent(Consumer<? super T> consumer), 如果存在值则执行consumer

3. optional.get(),获取value

4. optional.orElse(T other),如果没值则返回other

5. optional.orElseGet(Supplier<? extends T> other),如果没值则执行other并返回

6. optional.orElseThrow(Supplier<? extends X> exceptionSupplier),如果没值则执行exceptionSupplier,并抛出异常。

 

  • 8. Stram类

流是Java API的新成员,它允许我们以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,我们可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,也就是说我们不用写多线程代码了。

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。

 

  • 9. 新的日期Api

在JDK1.7中,处理日期相关的数据我们使用java.util.Data,算得上是一个万能的接口,他包含了日期、时间、还有毫秒数。当使用他存储日期或者只存储时间,那么只有定义的人才知道哪些数据是有用的。而且在java.util.Date中的月份从0开始,一月是0,十二月是11。在JDK1.8及以后的API中,对于时间的使用我们更加便利。新增了LocalDate、LocalTime、LocalDateTime,分别表示ISO-8601日历系统(国际标准化组织制定的现代公民的日期和时间的表示法)的日期,时间、日期和时间。他们提供简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息。并且他们类的实例是不可变的对象,不但线程安全,而且不能修改。

 

  • 10. 重复注解和扩展注解

在jdk1.8中,支持多重注解的,只需要在自定义的注解中添加@Repeatable元注解,并且指定多重注解的存储注解。同时,反射相关的API提供了新的函数getAnnotationsByType()来返回重复注解的类型。

在扩展注解方法,添加了两种:

1. TYPE_PARAMETER,表示该注解能写在类型变量的声明语句中。

2. TYPE_USE,表示该注解能写在使用类型的任何语句中

为此,jdk1.8相比于之前的版本来说,新增的一些特性暂说这些,后续我会通过代码的方式解释常用的特性。

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值