常见面试题: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 ...
随机推荐
- PAT乙级:1092 最好吃的月饼 (20分)
PAT乙级:1092 最好吃的月饼 (20分) 题干 月饼是久负盛名的中国传统糕点之一,自唐朝以来,已经发展出几百品种. 若想评比出一种"最好吃"的月饼,那势必在吃货界引发一场腥风 ...
- PGSQL存储过程学习
一.存储过程定义: 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参 ...
- odoo接口跨域问题
odoo Controller接口开发 POST请求的跨域问题解决方法 1.odoo Controller接口开发,前端在请求的时候会发生跨域问题,报错信息如下:Function declared a ...
- memcache(11211)未授权访问
1.安装Memcache服务端 sudo apt-get install memcached 2.启动服务 sudo memcached -d -m 128 -p 11211 -u root 3.ap ...
- js 倒计时退出
<p>您已提交成功!<span id='submit_second'></span></p> $("#submit_second") ...
- Hadoop 3.1.1 - 概述 - 集群安装
Hadoop 集群安装 目标 本文描述了如何从少数节点到包含上千节点的大规模集群上安装和配置 Hadoop 集群.如果只是为了尝试,你可以先从单台机器上安装开始(参阅单节点安装). 本文并不包含诸如安 ...
- 将几张图片合并为一张图片,返回byte数组
需求:通过url数组下载图片,再竖直合成一张新的图片,具体java代码如下 1 /** 2 * 竖直合并图片 3 * 4 * @param urls 5 * @return 6 */ 7 public ...
- 小程序中多个echarts折线图在同一个页面的使用
最近做小程序的业务中遇到一个页面要同时显示几个echarts图,刚开始遇到各种冲突,死数据可以,动态数据就报错的问题,折磨了一天,仔细看了官网和查在各种资料之后,终于解决了. 直接上代码: commi ...
- Java面向对象09——super
Super main package oop.demon01.demon05; public class Application { public static void main( ...
- A Telnet Client Using Expect
The following expect script achieves a simple telnet client: login -> send command -> exit. Th ...