常见面试题: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 ...
随机推荐
- Spring RestTemplate 之put、delete请求
●PUT请求:在RestTemplate中,PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForEntity方法的参数基本一致,只是put方法没有返回值而已.举一个简单的例子, ...
- Linux从入门到进阶全集——【第十四集:Shell编程-export命令】
参考: https://www.cnblogs.com/guojun-junguo/p/9855356.html 功能说明:设置或显示环境变量. 语 法:export [-fnp][变量名称]=[变量 ...
- 一:Vue项目构建
第一步:需要安装nodeJS的环境,直接去官网下载https://nodejs.org/en/,下载下来按照提示一步步的安装.(vue.js是一个Js 框架.在node里面通过Npm 安装,是为了方便 ...
- python基础之os模块操作
# os模块 目录相关内置库import os# . 当前目录 .. 返回上一级目录# 1. os.path.abspath() --获取当前文件的绝对路径(不包含os模块.py) pwd# path ...
- Unittest方法 -- 测试断言
"""断言详解"""from unittest_1.it import *def add(a,b): return a - bclass B ...
- infomation_schema基本使用
一.infomation_schema库 把 information_schema 看作是一个数据库,确切说是信息数据库.其中保存着关于MySQL服务器所维护的所有其他数据库的信息.如数据库名,数据库 ...
- Python 接口之request ,headers格式不对
复制heardes格式,模拟请求报错 原因:粗心,headers带了空格
- Error: Could not find or load main class ***
jni 本地方法的总结 1,第一步,javah D:\wksp_study\designbook\target\classes> //clas文件所在目录执行 javah -cp D:\wksp ...
- Node.js躬行记(7)——定时任务的进化史
一.纯手工 公司主营的是直播业务,会很许多打榜活动,也就是按主播收到的礼物或收益进行排序,排在前面的会有相应奖励. 纯手工时代,每接到一个活动,就重新写一份,第一次写完.之后就是复制黏贴,再修改,每次 ...
- 定时任务quartz
pom引入 <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>qua ...