常见面试题:java8有什么新特性?
常见面试题:java8有什么新特性?
主要有以下这些新特性:
lambda 表达式,经常配合函数式接口使用,可以有效减少代码量
Runnable 是一个函数式接口,下面展示了创建线程三种写法,显然最后一种最简洁:
class OldWay implements Runnable {
@Override
public void run() {
System.out.println("最原始的方法");
}
} public class Test {
public static void main(String[] args) { new Thread(new OldWay()).start(); new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类");
}
}).start(); new Thread(() -> {
System.out.println("lambda表达式");
}).start(); }
}
在 new 一个 Thread 时需要传入一个 Runnable 接口的实现类
- 第一种是最原始的做法,先创建一个 class 来实现 Runnable 接口,然后在创建线程时传入这个实现类,太麻烦了
- 第二种是匿名内部类的写法,把实现类的名字给省略掉了,稍微方便点,但
run这个方法名其实也有点冗余,因为 Runnable 里面就这么一个方法,不写出来应该也没关系啊 - 第三种是 lambda 表达式的写法,把方法名也省略掉了,最简洁,但注意,如果接口里有多个方法,那么只能采用前两种方法了
更直观的感受一下 lambda 表达式和函数式接口之间的关系:
public class Test {
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println("nb");
};
}
}
另一个常见应用就是集合类的
forEach方法,需要一个Consumer参数,这也是一个函数式接口,里面的accept方法需要一个参数并且没有返回值(不用记,在 IDEA 里点进去看就行),一个例子如下,它遍历 list 中的每个元素,加一后输出:public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//2 3 4
list.forEach((Integer num) -> {
num = num + 1;
System.out.println(num);
});
}
}
lambda 表达式还有些小细节,比如参数列表中参数的类型其实可以省略,如果代码块里只有一条语句那么花括号也可以省略,如果参数列表里只有一个参数那么圆括号也可以省略,但其实就算不省略也足够简洁了,我觉得没必要省略
方法引用,感觉有点说不清,可以看个例子,就比如前面遍历 list,如果我就是想遍历一次 list 然后输出,可以用到方法引用:
public class Test {
public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3); list.forEach((Integer num) -> {
System.out.println(num);
}); list.forEach(System.out::println); }
}
首先,
forEach是需要一个Consumer参数的,这个函数式接口的accept方法需要一个参数并且没有返回值,我们有两个方案,一个就是自己写一个 lambda 表达式,另一个就是使用方法引用,直接引用一个已经写好了的满足条件的方法,比如这里的System.out.println方法就是需要一个参数的void方法,满足条件,当然我们也可以定制一个满足条件的方法然后用方法引用的方式来使用,如下:class TestReference{
public static void myPrint(Integer num){
System.out.println(num);
}
}
public class Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.forEach(TestReference::myPrint);
}
}
函数式接口,前面其实已经提到过了,如果一个接口里面只有一个方法,那么这就是一个函数式接口,对于函数式接口,我们可以通过 lambda 表达式或者方法引用来进行快速的实现,而不必新建一个 class 去继承或者写一个匿名内部类
默认方法,意思是说,我们在写一个接口时可以通过
default关键字为其中的方法提供默认的实现方案,使得实现类就算不覆写这个方法也没有关系:interface TestInterface{
default void test(){
System.out.println("here");
}
} class TestDefault implements TestInterface{
//没有覆写test方法也没有报错
} public class Test {
public static void main(String[] args) {
//here
new TestDefault().test();
}
}
Stream API,我们可以把一个集合转换为流,在这个流上做各种操作,比如查找、排序、过滤等等
主要有以下这些操作:

- 中间操作:指操作完成后还是返回一个流对象,可以拿着这个对象继续操作下去
- 结束操作:指操作完成后不再返回流对象,一切都结束了
- 无状态:指元素的处理不受之前元素的影响,可以挨个处理
- 有状态:指该操作只有拿到所有元素之后才能继续下去
- 非短路操作:指必须处理完所有元素才能得到最终结果
- 短路操作:指遇到某些符合条件的元素就可以得到最终结果
来个案例,现在给定一个 list,想要先求出每个元素的平方,然后排序,然后找出 10 和 100 之间的那些元素,然后去除重复元素,最后输出:
public class Test {
public static void main(String[] args) {
//准备我们的list
ArrayList<Integer> list = new ArrayList<>();
int[] ints = {4, 1, 6, 2, 8, 5, 15, 11, 9};
for (int i : ints) {
list.add(i);
}
//转换为流
Stream<Integer> stream = list.stream();
//第一步,求出每个元素的平方
stream.map((Integer origin) -> {
return origin * origin;
})
//第二步,排序
.sorted()
//第三步,找出10和100之间的那些值
.filter((Integer num) -> {
return num >= 10 && num <= 100;
})
//第四步,去重
.distinct()
//第五步,输出
.forEach(System.out::println);
}
}
从案例中可以发现,很多流操作是需要一个函数式接口作为参数的,因此一定要搭配前面的 lambda 表达式和方法引用来完成这些流操作,否则代码量是过大的
至于到底需要写什么样的 lambda 表达式(几个参数,返回值是什么),一定要在 IDEA 里点进去看,直接背是不现实的
新的 Date Time API,因为 java 中同时存在
java.util.Date和java.sql.Date两个时间类,很容易让人迷惑,而且这两个包里的内容也存在诸多问题,因此 java8 中新增了java.time这个包来把所有时间类的 API 一网打尽直接看个案例吧,演示部分 API 的使用:
public class Test {
public static void main(String[] args) { //获取当前的日期时间(年月日+时分秒)
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前的日期和时间: " + currentTime); //获取当前的日期(年月日)
LocalDate date1 = currentTime.toLocalDate();
System.out.println("date1: " + date1); //分别得到当前的月、日、秒
Month month = currentTime.getMonth();
int day = currentTime.getDayOfMonth();
int seconds = currentTime.getSecond();
System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds); //把当前的日期时间中的年替换为2012,日替换为10
LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
System.out.println("date2: " + date2); //显式的构造出一个日期
LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
System.out.println("date3: " + date3); //显式的构造出一个时间
LocalTime date4 = LocalTime.of(22, 15);
System.out.println("date4: " + date4); //解析字符串来得到一个时间
LocalTime date5 = LocalTime.parse("20:15:30");
System.out.println("date5: " + date5);
}
}
最后的输出如下:
当前的日期和时间: 2021-08-24T22:03:43.468015700
date1: 2021-08-24
月: AUGUST, 日: 24, 秒: 43
date2: 2012-08-10T22:03:43.468015700
date3: 2014-12-12
date4: 22:15
date5: 20:15:30
Optional 类,很好的解决了
NullPointerException的问题
学习过程中,部分内容有参考网上其它人的文章,如有侵权必删
常见面试题:java8有什么新特性?的更多相关文章
- java常见面试题及答案 1-10(基础篇)
java常见面试题及答案 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程.Java 源文件被 ...
- java常见面试题及答案
java常见面试题及答案 来源 https://blog.csdn.net/hsk256/article/details/49052293 来源 https://blog.csdn.net/hsk25 ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
- iOS常见面试题汇总
iOS常见面试题汇总 1. 什么是 ARC? (ARC 是为了解决什么问题而诞生的?) ARC 是 Automatic Reference Counting 的缩写, 即自动引用计数. 这是苹果在 i ...
- Java 常见面试题(一)
1)什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节码文件.Java被设 ...
- 【javascript常见面试题】常见前端面试题及答案
转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...
- Vue常见面试题汇总
Vue框架常见面试题 1.active-class是哪个组件的属性?嵌套路由怎么定义? 答:vue-router模块的router-link组件. 2.怎么定义vue-router的动态路由?怎么 ...
- 夯实Java基础系列16:一文读懂Java IO流和常见面试题
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- redis知识点及常见面试题
redis知识点及常见面试题 参考: https://zm8.sm-tc.cn/?src=l4uLj4zF0NCIiIjRnJGdk5CYjNGckJLQrIqNiZaJnpOWjIvQno2Llpy ...
随机推荐
- Redis学习——常用小功能
一.慢查询分析(查询日志:所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间,当超过预设阀值,就将这条命令的相关信息(例如:发生时间,耗时,命令的详细信息)记录下来,Redis也提供了类似的功 ...
- 解决 Github 打不开或打开很慢的问题
解决 Github 打不开或打开很慢的问题 方法一 一.确定 github 网站的 ip 打开网址:http://github.com.ipaddress.com/ 192.30.253.112 gi ...
- ODOO里视图开发案例---定义一个像tree、form一样的视图
odoo里视图模型MVC模式: 例子:在原来的视图上修改他: var CustomRenderer = KanbanRenderer.extend({ ....});var CustomRendere ...
- At 、Crontabl定时任务
之前笔者是在本地写的博客,然后用 windows 定时任务启动写的脚本上传到 Github 上,现在又遇到了 Linux 上的定时任务,项目还要用到 Quartz 定时任务框架 1. 一次性定时任务 ...
- jquery 获取url地址参数
1 var url = document.URL; 2 var a = url.split("="); 3 4 if(a[1]){ 5 return options.fn(this ...
- 免杀mimikatz
mimikatz源码 下载地址https://github.com/gentilkiwi/mimikatz/releases/tag/2.2.0-20210709 使用vs2019打开工程mimik ...
- Java的equsals和==
先上结论:在我们常用的类中equals被重写后,作用就是为了比较对象的内容,==是比较对象的内存地址.但并不能说所有的equals方法就是比较对象的内容. Java 中的==: 1.对于对象引用类型: ...
- Spring Cloud 专题之六:bus
书接上回: SpringCloud专题之一:Eureka Spring Cloud专题之二:OpenFeign Spring Cloud专题之三:Hystrix Spring Cloud 专题之四:Z ...
- SpringBoot系列——动态定时任务
前言 定时器是我们项目中经常会用到的,SpringBoot使用@Scheduled注解可以快速启用一个简单的定时器(详情请看我们之前的博客<SpringBoot系列--定时器>),然而这种 ...
- LAMP介绍以及Apache安装
一.LAMP架构介绍 1.1 LAMP概述 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态Web站点服务及其应用开发环境.LAMP是一个缩写词,具体包 ...