常见面试题: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 ...
随机推荐
- 单细胞分析实录(19): 基于CellPhoneDB的细胞通讯分析及可视化 (下篇)
在上一篇帖子中,我介绍了CellPhoneDB的原理.实际操作,以及一些值得注意的地方.这一篇继续细胞通讯分析的可视化. 公众号后台回复20210723获取本次演示的测试数据,以及主要的可视化代码. ...
- PAT乙级:1087 有多少不同的值 (20分)
PAT乙级:1087 有多少不同的值 (20分) 当自然数 n 依次取 1.2.3.--.N 时,算式 ⌊n/2⌋+⌊n/3⌋+⌊n/5⌋ 有多少个不同的值?(注:⌊x⌋ 为取整函数,表示不超过 x ...
- 【Javaweb】Cookie和Session
会话技术 什么是会话 从浏览器访问服务器开始,到访问服务器结束,浏览器关闭为止的这段时间内容产生的多次请求和响应,合起来叫做浏览器和服务器之间的一次会话 会话管理作用 共享数据用的,并且是在不同请求间 ...
- Mysql 基础用法
#创建表 CREATE TABLE table_name (column_name int) CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` ...
- ts 学习笔记 - 进阶篇 1
目录 进阶 类型别名 字符串字面量类型 元祖 例子 越界的元素 枚举 手动赋值 常数项和计算所得项 常数枚举 外部枚举 进阶 类型别名 类型别名用来给一个类型起个新名字 type Name = str ...
- 构建前端第12篇之---在Vue中对组件,变量,函数的全局引入
张燕涛写于2020-01-16 星期two 本篇还是源于import和export的使用,昨天看es6入门 和MDN文档,大体上用法了解了,但今天看ElementUI源码的时候,看到 //src/in ...
- C/C++入门
C:面向过程-函数 C++:面向对象-类:向下兼容C 程序包含头文件+主函数 简单数据类型 long long型赋超过int型范围的初值,需要在初值后面加上LL,否则可能会编译错误 不要使用float ...
- 浅析php环境配置
PHP作为开源的服务器端脚本语言,在web应用方面非常广泛.如果你想下载某些开源应用,github上php开源软件选择往往比Java还多.最近,研究了linux下php的安装,主要有以下体会. PHP ...
- VS2019 +MySQL+EntityFramework 使用配置与坑点避免随记
一.安装运行环境 首先我们到mysql的官方网站上下载 mysql-installer-community-8.0.26.0 ,或者其他特定版本,通过它我们可以先将 mysql-for-visuals ...
- MapReduce框架-Join的使用
引言 首先先明白在关系型数据库中Join的用法. Join在MapReduce中的用法也是用于两个文件之间的连接. 使用MR程序解决两张表的join问题,有两种解决方案 à MR程序的join应用 1 ...