JDK1.8新特性面经整理

JDK1.8新特性中最值得注意的当然就是Lambda表达式了,还有新增了很多关于Lambda表达式的新特性,比如函数式接口、方法引用和构造器调用。处理之外还有Stream API、接口中的默认方法和静态方法、新的时间日期API,HashMap以及ConcurrentHashMap结构的更改等等。

1、Lambda表达式

(1)什么是Lambda表达式呢?Lambda表达式本质上就是一段匿名内部类,也可以是一段可以传递的代码。

语法如下:

Lambda表达式语法

(2)Lambda表达式到底方便在哪里?举例说明

例1-iif过滤筛选

我们发现实际上这些过滤方法的核心就只有if语句中的条件判断,其他均为模版代码,每次变更一下需求,都需要新增一个方法,然后复制黏贴,假设这个过滤方法有几百行,那么这样的做法难免笨拙了一点。如何进行优化呢?

a.使用设计模式

例1-设计模式过滤筛选

看起来好像代码更多了一点,不过这是在只有两个例子的情况下,如果有100个过滤那么会发现还是设计模式比较简洁一点,而且设计模式好在的地方是对代码进行了整合,看起来逻辑更简洁明了。不过对于程序员来说,还是要搬运很多代码,接下来进一步优化

b.使用匿名内部类

匿名内部类:没有显示名字的内部类

本质:匿名内部类会隐式得继承一个类或实现一个接口,或者说,匿名内部类时一个继承了该类或者实现了该接口的子类匿名对象

格式:new 类名/接口/抽象类(){}

例1-匿名内部类过滤筛选

使用匿名内部类,就不需要每次都新建一个实现类,直接在方法内部实现。看起来是不是更简洁明了一点。

c.使用Lambda表达式

例1-Lambda表达式过滤筛选  

Lambda表达式就是一段更加简洁明了的匿名内部类。

d.还可以使用Stream API

例1-Stream API过滤筛选

2、函数式接口

问题一:为什么要新增函数式接口?

答案是为了配合lambda表达式使用,当接口中存在多个抽象方法的时候,单纯使用lambda表达式并不能智能匹配对应的抽象方法,因此引入了函数式接口的概念

问题二:什么是函数式接口

概念:只定义了一个抽象方法的接口(Object类的public方法除外),就是函数式接口,并且还提供了注解:@FunctionallInterface

理解:首先要理解什么是函数,这里的函数跟编程中的函数并不一样,而是与数学中函数的概念一样——一种映射的关系,接下来看看分类就就很明了了。

常见的四大函数式接口:

a.Consumer:消费型接口,有参无返回值

消费型接口

b.Supplier:供给型接口,无参有返回值

:供给型接口

c.Function:函数式接口,有参有返回值

函数式接口

d.Predicate:断言型接口,有参有返回值,返回值是boolean类型

断言型接口

在四大核心函数式接口基础上,还提供了诸如BiFunction、BinaryOperation、toIntFunction等扩展式的函数式接口,都是在这四种函数式接口上扩展而来的


三、方法引用和构造器调用

方法引用和构造器调用是在基于Lambda表达式的基础之上的:若lambda体中的内容有方法已经实现了,那么可以使用"方法引用"。可以理解为方法引用是lambda表达式的另外一种表现形式并且其语法比lambda表达式更加简单

1、方法引用

三种表现形式:

a.对象::实例方法名

b.类::静态方法名

c.类::实例方法名(lambda参数列表中的第一个参数是实例方法的调用这,第二个参数是实例方法时可用)

例2- 方法引用

2、构造器调用

格式:ClassName::new

例3-  构造器调用

还有一种数组引用

格式:Type[]::new

例4- 数组引用

4、Stream API

Stream操作的三个步骤:

(1)创建stream

创建stream

(2)中间操作(过滤、map)

中间操作(过滤、map)

(3)终止操作

终止操作-1
终止操作-2

还有功能比较强大的两个终止操作 reduce和collect

reduce操作: reduce:(T identity,BinaryOperator)/reduce(BinaryOperator)-可以将流中元素反复结合起来,得到一个值

并行流和串行流:在jdk1.8新的stream包中针对集合的操作也提供了并行操作流和串行操作流。并行流就是把内容切割成多个数据块,并且使用多个线程分别处理每个数据块的内容。Stream api中声明可以通过parallel()与sequential()方法在并行流和串行流之间进行切换。

jkd1.8并行流使用的是fork/join框架进行并行操作

ForkJoin框架:在必要的情况下,将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆时),再将一个个的小任务运算的结果进行join汇总

关键:递归分合、分而治之

采用”工作窃取“工作模式(work-stealing):当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放到自己的队列中

相对于一般的线程池实现,fork/join框架的优势体现在对其包含的任务的处理方式上

一般的线程池中,如果一个线程正在执行的任务由于某些原因无法继续,那么该线程会处于等待状态

fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行,那么处理该子问题的线程会主动寻找其它尚未运行的子问题来执行,这个方式减少了线程的等待时间,提高了性能


五、接口中的默认方法和静态方法

在接口中可以使用default和static关键字来修饰接口中定义的普通方法

接口中的默认方法和静态方法

在JDK1.8中很多接口会新增方法,为了保证1.8向下兼容,1.7版本中的接口实现类不用每个都重新实现新添加的接口方法,引入了default默认实现,static的用法是直接用借口名去调方法既可。当一个类继承父类又实现接口时,若后两者方法名相同,则有限继承父类中的同名方法,即”类优先“,如果实现两个同名方法的接口,则要求实现类必须手动声明默认实现哪个接口中的方法


六、新的时间日期API

1、使用过时间日期API的都知道,之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便,新的java.time.LocalDate月份和星期都改成了enum;

2、java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。

之前SimpleDateFormat多线程环境下一般都是配合ThreadLocal使用,新的LocalDate显然更加简洁明了。

3、java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,更加明确需求取舍

4、新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对。


七、HashMap、ConcurrentHashMap数据结构优化(面试重点)

面试问题:你能说说HashMap/ConcurrentHashMap的结构吗?

(一)JDK1.8之前

hashMap采用的是哈希表(数组+链表)

ConcurrentHashMap采用的是哈希表(数组+链表),通过分段锁机制来实现线程安全。

1、hashMap默认大小16,一个0-15索引的数组。

2、存储方式:

(1)首先调用元素的hashcode方法计算出哈希码值,经过哈希算法算成数组的索引值;

(2)如果对应的索引处没有元素,直接存放,如果有对象在,那么比较它们的equals方法比较内容

a.如果内容一样,后一个value值会将前一个value值覆盖

b.如果不一样,后加的会放在前面,形成一个链表,形成了碰撞

3、缺点:加载因子:0.75,数组扩容,达到总容量的75%,就进行扩容,但是无法避免碰撞的情况发生

(二)JDK1.8之后

hashMap采用的是数组+链表+红黑树

ConcurrentHashMap采用的是数组+链表+红黑树,通过CAS+Synchronized来实现线程安全

1、当碰撞的个数>8时&&总容量>64,会有红黑树的引入,除了添加之后,效率都比链表高

2、链表新进元素加到末尾

3、ConcurrentHashMap(锁分段机制),concurrentLevel,JDK1.8采用CAS算法(无锁算法,不再使用锁分段)

4、红黑树(自平衡的二叉查找树,基于二叉查找树、完美平衡二叉树)

问题二:HashMap为什么不是线程安全的?

答:HashMap中的变量没有用volatile关键字修饰来保证可见性和有序性,也没有用任何锁来保证原子性,在多线程运行的环境下,可能会产生并发问题,如多个线程同时插入时,可能会导致闭环。

问题三:ConcurrentHashMap怎么保证线程安全?

答:JDK1.7中,ConcurrentHashMap采用锁分段机制来保证线程安全同时提高并发性;JDK1.8中,ConcurrentHashMap采用的是CAS加上Synchronized来保证线程安全,当没有发生冲突的使用使用CAS来保证线程安全,当发生冲突的时候用Synchronized来锁住。

PS:有关锁可以参考我之前写的JUC之Locks锁面经整理

你可能感兴趣的:(JDK1.8新特性面经整理)