相信很多同行小伙伴会因为许多原因想跳槽,不论是干得不开心还是想跳槽涨薪,在如此内卷的行业,我们都面临着“面试造火箭,上班拧螺丝”的局面,鉴于当前形势博主呕心沥血整理的干货满满的造火箭的技巧来了,本博主花费2个月时间,整理归纳java全生态知识体系常见面试题!总字数高达百万! 干货满满,每天更新,关注我,不迷路,用强大的归纳总结,全新全细致的讲解来留住各位猿友的关注,希望能够帮助各位猿友在应付面试笔试上!当然如有归纳总结错误之处请各位指出修正!如有侵权请联系博主QQ1062141499!
目录
4 Math.round(15)等于多少? Math.round(- 15) 又等于多少
13 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
17 static class与non static class的区别
21 XML文档定义分为 Schema 和 DTD 两种形式
1 Java属于编译型还是解释型语言?
计算机不能直接理解高级语言,只能理解和运行机器语言。必须要把高级语言翻译成机器语言,计算机才能运行高级语言所编写的程序。
翻译的方式有两种,一个是编译,一个是解释。
用编译型语言写的程序执行之前,需要一个专门的编译过程,通过编译系统把高级语言翻译成机器语言,把源高级程序编译成为机器语言文件,以后直接运行而不需要再编译了,所以一般编译型语言的程序执行效率高。
解释型语言在运行的时候才解释成机器语言,每个语句都是执行时才翻译。每执行一次就要翻译一次,效率较低。
Java 是一种兼具编译和解释特性的语言,.java 文件会被编译成与平台无关的 .class 文件,但是 .class 字节码文件无法被计算机直接,仍然需要 JVM 进行翻译成机器语言。
所以严格意义上来说,Java 是一种解释型语言。
总结:
个人认为,java是解释型的语言,因为虽然java也需要编译,编译成.class文件,但是并不是机器可以识别的语言,而是字节码,最终还是需要 jvm的解释,才能在各个平台执行,这同时也是java跨平台的原因。所以可是说java即是编译型的,也是解释型,但是假如非要归类的话,从概念上的定义,恐怕java应该归到解释型的语言中。
编译型的语言包括:C、C++、Delphi、Pascal、Fortran
解释型的语言包括:Java、Basic、javascript、python
2 如何让计算机最高效的算出2乘以8?
2 <<3
位运算符 <<,是将一个数左移 n 位,相当于乘以了 2 的 n 次方
一个数乘以 8 只要将其左移 3 位即可
CPU 直接支持位运算,效率最高
补充:当这个数接近Java基本整数类型的最大值时,左移位运算可能出现溢出,得出负值。
3 javap的作用是什么?
javap 是 Java class文件分解器,可以反编译,也可以查看 java 编译器生成的字节码等。
javap 命令参数
javap -help
用法: javap <options> <classes>
其中, 可能的选项包括:
-help --help -? 输出此用法消息
-version 版本信息
-v -verbose 输出附加信息
-l 输出行号和本地变量表
-public 仅显示公共类和成员
-protected 显示受保护的/公共类和成员
-package 显示程序包/受保护的/公共类
和成员 (默认)
-p -private 显示所有类和成员
-c 对代码进行反汇编
-s 输出内部类型签名
-sysinfo 显示正在处理的类的
系统信息 (路径, 大小, 日期, MD5 散列)
-constants 显示静态最终常量
-classpath <path> 指定查找用户类文件的位置
-bootclasspath <path> 覆盖引导类文件的位置
测试类:
public class Testsynchronized {
public void sync() {
synchronized (this) {
System.out.println("sync");
}
}
}
使用命令进行反汇编 javap -c Testsynchronized
警告: 二进制文件Testsynchronized包含Lee.interview.Testsynchronized
Compiled from "Testsynchronized.java"
public class Lee.interview.Testsynchronized {
public Lee.interview.Testsynchronized();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public void sync();
Code:
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: getstatic #15 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #21 // String sync
9: invokevirtual #22 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: aload_1
13: monitorexit
14: goto 20
17: aload_1
18: monitorexit
19: athrow
20: return
Exception table:
from to target type
4 14 17 any
17 19 17 any
}
4 Math.round(15)等于多少? Math.round(- 15) 又等于多少
Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行取整。
5 静态与非静态成员变量区别?
生命周期不同:非静态成员变量随着对象的创建而存在;静态成员变量随着类的加载而存在
调用方式不同:非静态成员变量用 对象名.变量名 调用;静态成员变量用 类名.变量名,JDK1.7以后也能用对象名.变量名调用
别名不同:非静态成员变量也称为实例变量;静态变量称为类变量
数据存储位置不同:成员变量数据存储在堆内存的对象中,对象的特有数据;静态变量数据存储在方法区(共享数据区)的静态区,对象的共享数据
6 静态变量和实例变量的区别
静态变量:是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;
实例变量:必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。
7 File的常用方法都有哪些?
• Files. exists():检测文件路径是否存在。
• Files. createFile():创建文件。
• Files. createDirectory():创建文件夹。
• Files. delete():删除一个文件或目录。
• Files. copy():复制文件。
• Files. move():移动文件。
• Files. size():查看文件个数。
• Files. read():读取文件。
• Files. write():写入文件。
8 nio中的Files类常用方法有哪些?
- isExecutable:文件是否可以执行
- isSameFile:是否同一个文件或目录
- isReadable:是否可读
- isDirectory:是否为目录
- isHidden:是否隐藏
- isWritable:是否可写
- isRegularFile:是否为普通文件
- getPosixFilePermissions:获取POSIX文件权限,windows系统调用此方法会报错
- setPosixFilePermissions:设置POSIX文件权限
- getOwner:获取文件所属人
- setOwner:设置文件所属人
- createFile:创建文件
- newInputStream:打开新的输入流
- newOutputStream:打开新的输出流
- createDirectory:创建目录,当父目录不存在会报错
- createDirectories:创建目录,当父目录不存在会自动创建
- createTempFile:创建临时文件
- newBufferedReader:打开或创建一个带缓存的字符输入流
- probeContentType:探测文件的内容类型
- list:目录中的文件、文件夹列表
- find:查找文件
- size:文件字节数
- copy:文件复制
- lines:读出文件中的所有行
- move:移动文件位置
- exists:文件是否存在
- walk:遍历所有目录和文件
- write:向一个文件写入字节
- delete:删除文件
- getFileStore:返回文件存储区
- newByteChannel:打开或创建文件,返回一个字节通道来访问文件
- readAllLines:从一个文件读取所有行字符串
- setAttribute:设置文件属性的值
- getAttribute:获取文件属性的值
- newBufferedWriter:打开或创建一个带缓存的字符输出流
- readAllBytes:从一个文件中读取所有字节
- createTempDirectory:在特殊的目录中创建临时目录
- deleteIfExists:如果文件存在删除文件
- notExists:判断文件不存在
- getLastModifiedTime:获取文件最后修改时间属性
- setLastModifiedTime:更新文件最后修改时间属性
- newDirectoryStream:打开目录,返回可迭代该目录下的目录流
- walkFileTree:遍历文件树,可用来递归删除文件等操作
如测试获取文件所属人
public static void testGetOwner() throws IOException {
Path path_js = Paths.get("/Users/Lee/Desktop/index.js");
System.out.println(Files.getOwner(path_js));
}
9 为什么要使用克隆
克隆的对象可能包含一些已经修改过的属性,而 new 出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。
10 如何实现对象克隆
• 实现 Cloneable 接口并重写 Object 类中的 clone() 方法。
• 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
11 深拷贝和浅拷贝区别是什么
浅拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。
深拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。
public
static
void
testGetOwner() throws IOExc
12 如何跳出当前的多重嵌套循环
在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用)。
13 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。C++和 C#中可以通过传引用或传输出参数来改变传入的参数的值。说明:Java 中没有传引用实在是非常的不方便,这一点在 Java 8 中仍然没有得到改进,正是如此在 Java 编写的代码中才会出现大量的 Wrapper 类(将需要通过方法调用修改的引用置于一个 Wrapper 类中,再将 Wrapper 对象传入方法),这样的做法只会让代码变得臃肿,尤其是让从 C 和 C++转型为 Java 程序员的开发者无法容忍。
14 不通过构造方法能创建对象吗?
Java 创建对象的方式:
- 用 new 语句创建对象
- 运用反射,调用 java.lang.Class 或 java.lang.reflect.Constructor类的newInstance()方法
- 调用对象的 clone() 方法
- 运用反序列化手段,调用 java.io.ObjectInputStream 对象的 readObject() 方法
1、2 会调用构造函数
3、4 不会调用构造函数
15 静态方法内部能对非静态调用吗?
不能
- 静态方法只能访问静态成员
- 调用静态方法时可能对象并没有被初始化,此时非静态变量还未初始化
- 非静态方法的调用和非静态成员变量的访问要先创建对象
16 Object有哪些公用方法
Object是所有类的父类,任何类都默认继承Object
clone 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
equals 在Object中与==是一样的,子类一般需要重写该方法。
hashCode 该方法用于哈希查找,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
getClass final方法,获得运行时类型
wait 使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。 wait() 方法一直等待,直到获得锁或者被中断。 wait(long timeout) 设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生
1、其他线程调用了该对象的notify方法。
2、其他线程调用了该对象的notifyAll方法。
3、其他线程调用了interrupt中断该线程。
4、时间间隔到了。
5、此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。
notify 唤醒在该对象上等待的某个线程。
notifyAll 唤醒在该对象上等待的所有线程。
toString 转换成字符串,一般子类都有重写,否则打印内存地址。
17 static class与non static class的区别
static class(内部静态类)
1、用static修饰的是内部类,此时这个内部类变为静态内部类;对测试有用。
2、内部静态类不需要有指向外部类的引用。
3、静态类只能访问外部类的静态成员,不能访问外部类的非静态成员。
non static class(非静态内部类)
1、非静态内部类需要持有对外部类的引用。
2、非静态内部类能够访问外部类的静态和非静态成员。
3、一个非静态内部类不能脱离外部类实体被创建。
4、一个非静态内部类可以访问外部类的数据和方法。
package com.junli.java.innerClass;
/**
* 内部类测试
*/
public class InnerClassDemo {
public static void main(String[] args) {
//访问非静态内部类
Outer.Inner inner = new Outer().new Inner();
System.out.println(inner.name);
//访问静态内部类
Outer.StaticInner staticInner = new Outer.StaticInner();
System.out.println(staticInner.name);
//访问非静态内部类的非静态内部类
Outer.Inner.InnerInner innerInnerClass =
new Outer().new Inner().new InnerInner();
System.out.println(innerInnerClass.name);
}
}
class Outer {
class Inner {
String name = "Inner";
class InnerInner {
String name = "InnerInner";
}
}
static class StaticInner {
String name = "StaticInner";
}
}
18 什么是xml
xml是一种可扩展性标记语言,支持自定义标签(使用前必须预定义)使用DTD和XMLSchema标准化XML结构。
优点:用于配置文件,格式统一,符合标准;用于在互不兼容的系统间交互数据,共享数据方便;
缺点:xml文件格式复杂,数据传输占流量,服务端和客户端解析xml文件占用大量资源且不易维护
19 xml解析的两种基本方式:DOM和SAX的区别是?
DOM: document object model。
SAX: simple api for xml 。
DOM一次性把xml文件全部加载到内存中简历一个结构一摸一样的树, 效率低。 SAX解析器的优点是解析速度快,占用内存少,效率高。
DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。DOM,它是生成一个树,有了树以后你搜索、查找都可以做。
SAX,它是基于流的,就是解析器从头到尾解析一遍xml文件,解析完了以后你不过想再查找重新解析。 sax解析器核心是事件处理机制。例如解析器发现一个标记的开始标记时,将所发现的数据会封装为一个标记开始事件,并把这个报告给事件处理器。平时工作中,xml解析你是使用什么?JDOM、DOM4J
20 Java中有哪些解析XML的类库?有什么特点?
1. DOM(Document Object Model)
- 符合官方 W3C 标准
- 是以层次结构组织的节点
- 可以在层次结构中寻找特定信息
- 需要加载整个文档、构造层次结构
优点:可获取和操作 xml 任意部分的结构和数据
缺点:需加载整个 XML 文档,消耗资源大
2. SAX(Simple API for XML)
SAX 解析器基于事件的模型,解析 XML 文档时可以触发一系列事件,解析到期望的节点,可以激活一个回调方法,处理该节点上的数据
优点:
- 不需要全部加载完 XML 文档,可以在达到期望条件时停止解析
- 对内存的要求较低,能解析占用存储较大的文档
- 可以一边加载 XML,一边解析
- 解析 XML 效率和性能较高
缺点:
- 需要开发者负责节点的处理逻辑,文档越复杂程序就越复杂
- 按照 XML 内容单向解析,无法直接定位文档层次,很难同时访问同一个文档中的多处不同数据
3. JDOM(Java-based Document Object Model)
JDOM 自身不包含解析器,使用 SAX2 解析器来解析和验证输入XML文档
包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型、XML 文本文档
优点:API 简单,方便开发
缺点:灵活性较差;性能较差
4. DOM4J(Document Object Model for Java)
- dom4j 包含了超出 XML 文档表示的功能
- 支持 XML Schema
- 支持大文档或流化文档的基于事件的处理
- 可以选择按照 DOM 或 SAX 方式解析 XML 文档
优点:
- API丰富易用,较直观,方便开发
- 支持 XPath
- 性能较好
缺点:
- 接口较多,API 较为复杂
总结
- DOM4J 性能最佳
- JDOM 和 DOM 性能不佳,大文档易内存溢出,但可移植。小文档可考虑使用 DOM 和 JDOM
- XML 文档较大且不考虑移植性问题可用 DOM4J
- 无需解析全部 XML 文档,可用 SAX
- XML文档定义有几种形式?有何区别?
21 XML文档定义分为 Schema 和 DTD 两种形式
- Schema 是对XML文档结构的定义和描述,其主要的作用是用来约束XML文件,并验证XML文件有效性。
- DTD 的作用是定义XML的合法构建模块,它使用一系列的合法元素来定义文档结构。
区别:
- Schema 本身也是 XML 文档,DTD 定义跟 XML 无关
- Schema 文档结构性强,各元素之间的嵌套关系非常直观;DTD 文档的结构是"平铺型"的,如果定义复杂的XML文档,很难把握各元素之间的嵌套关系
- Schema 可以定义元素文本的具体类型; TD 只能指定元素含有文本
- Schema 支持元素节点顺序的描述;DTD 没有提供无序情况的描述
- Schema 可以很好满足命名空间;DTD 不可以
22 Java1.7与1.8,1.9,10 新特性
1.5
- 自动装箱与拆箱
- 枚举(常用来设计单例模式)
- 静态导入
- 可变参数
- 内省
1.6
- Web服务元数据
- 脚本语言支持
- JTable的排序和过滤
- 更简单,更强大的JAX-WS
- 轻量级Http Server
- 嵌入式数据库 Derby
1.7
- switch中可以使用字串了
- 运用List tempList = new ArrayList<>(); 即泛型实例化类型自动推断
- 语法上支持集合,而不一定是数组
- 新增一些取环境信息的工具方法
- Boolean类型反转,空指针安全,参与位运算
- 两个char间的equals
- 安全的加减乘除
- map集合支持并发请求,且可以写成 Map map = {name:"xxx",age:18};
1.8
- 允许在接口中有默认方法实现
- Lambda表达式
- 函数式接口
- 方法和构造函数引用
- Lambda的范围
- 内置函数式接口
- Streams
- Parallel Streams
- Map
- 时间日期API
- Annotations
1.9
- Jigsaw 项目;模块化源码
- 简化进程API
- 轻量级 JSON API
- 钱和货币的API
- 改善锁争用机制
- 代码分段缓存
- 智能Java编译, 第二阶段
- HTTP 2.0客户端
- Kulla计划: Java的REPL实现
10
- 本地变量类型推断
- 统一JDK仓库
- 垃圾回收器接口
- G1的并行Full GC
- 应用程序类数据共享
- ThreadLocal握手机制
23 JDK8中Stream接口的常用方法
Stream 接口中的方法分为中间操作和终端操作,具体如下。
中间操作:
- filter:过滤元素
- map:映射,将元素转换成其他形式或提取信息
- flatMap:扁平化流映射
- limit:截断流,使其元素不超过给定数量
- skip:跳过指定数量的元素
- sorted:排序
- distinct:去重
终端操作:
- anyMatch:检查流中是否有一个元素能匹配给定的谓词
- allMatch:检查谓词是否匹配所有元素
- noneMatch:检查是否没有任何元素与给定的谓词匹配
- findAny:返回当前流中的任意元素(用于并行的场景)
- findFirst:查找第一个元素
- collect:把流转换成其他形式,如集合 List、Map、Integer
- forEach:消费流中的每个元素并对其应用 Lambda,返回 void
- reduce:归约,如:求和、最大值、最小值
- count:返回流中元素的个数
24 JNI的使用
JNI是 Java Native Interface 的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。
25 什么是JAVA内部类?
25.1、概念
存在于Java类的内部的Java类。
25.2、分类
- 成员内部类
- 格式
class OuterClass {
class InnerClass {} //成员内部类
}
编译之后会生成两个class文件:OuterClass.class和OuterClass$InnerClass.class
- 方法内部类
- 格式
class OuterClass {
public void doSomething(){
class Inner{
}
}
}
编译之后会生成两个class文件:OuterClass.class和OuterClass$1InnerClass.class
只能在定义该内部类的方法内实例化
方法内部类对象不能使用该内部类所在方法的非final局部变量
当一个方法结束,其栈结构被删除,局部变量成为历史。但该方法结束后,在方法内创建的内部类对象可能仍然存在于堆中
- 匿名内部类
- a) 继承式匿名内部类格式
public class Fish {
/**
* 游泳方法
*/
public void swim() {
System.out.println("我在游泳!");
}
public static void main(String[] args) {
//创建鱼对象
Fish fish = new Fish() {
//重写swim方法
public void swim() {
System.out.println("我在游泳,突然发生海啸,我撤了!");
}
};
fish.swim();
}
}
编译后生成两个class文件:Fish.class和Fish$1.class
b) 接口式匿名内部类格式
interface IFish {
public void swim();
}
class TestIFish {
public static void main(String[] args) {
IFish fish = new IFish() {
@Override
public void swim() {
System.out.println("我是一条小丑鱼,我在游泳");
}
};
fish.swim();
}
}
编译后生成3个class文件:IFish.class、TestIFish.class和TestIFish$1.class
接口式的匿名内部类是实现了一个接口的匿名类,感觉上实例化了一个接口。
c) 参数式的匿名内部类
格式
public class TestCrucian {
public static void main(String[] args) {
Crucian c = new Crucian();
c.swim(new IFish() {
@Override
public void swim() {
System.out.println("鲫鱼在河水里游泳!");
}
});
}
}
/**
* 鲫鱼游泳
* @author Lee
* 2020年8月13日上午9:41:01
*/
class Crucian {
/**
* 鲫鱼的游泳方法
* @param fish
*/
void swim(IFish fish) {
fish.swim();
}
}
编译后生成3个class文件:Crucian.class、TestCrucian.class和TestCrucian$1.class
- 静态嵌套类
- 静态嵌套类,并没有对实例的共享关系,仅仅是代码块在外部类内部
- 静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它
- 静态嵌套类仅能访问外部类的静态成员和方法
- 在静态方法中定义的内部类也是静态嵌套类,这时候不能在类前面加static关键字
- 格式
25.4、特点
-
class OuterFish { /** * 静态嵌套类 * @author Lee * 2020年8月13日上午10:57:52 */ static class InnerFish { } } class TestStaticFish { public static void main(String[] args) { //创建静态内部类对象 OuterFish.InnerFish iFish = new OuterFish.InnerFish(); } }
25.3、内部类的作用
- 内部类提供了某种进入其继承的类或实现的接口的窗口
- 与外部类无关,独立继承其他类或实现接口
- 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号
- 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的
- 内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量
- 内部类提供了Java的"多重继承"的解决方案,弥补了Java类是单继承的不足
26 匿名内部类可以继承类或实现接口吗?为什么?
- 匿名内部类本质上是对父类方法的重写 或 接口的方法的实现
- 从语法角度看,匿名内部类创建处是无法使用关键字继承类 或 实现接口
原因:
- 匿名内部类没有名字,所以它没有构造函数。因为没有构造函数,所以它必须通过父类的构造函数来实例化。即匿名内部类完全把创建对象的任务交给了父类去完成。
- 匿名内部类里创建新的方法没有太大意义,新方法无法被调用。
- 匿名内部类一般是用来覆盖父类的方法。
- 匿名内部类没有名字,所以无法进行向下的强制类型转换,只能持有匿名内部类对象引用的变量类型的直接或间接父类。
27 内部类可以引用它的外部类的成员吗?有什么限制?
- 内部类对象可以访问创建它的外部类对象的成员,包括私有成员
- 访问外部类的局部变量,此时局部变量必须使用 final 修饰
28 java如何实现其他语言的高阶函数
JDK的特性Lambda表达式
什么是高阶函数
高阶函数是指接受另外一个函数作为参数,或返回一个函数的函数。什么样的参数是函数类型的参数?要看该参数是否是一个函数式接口,函数式接口只会有一个方法,会使用 @FunctionalInterface 这个注解来修饰。
高阶函数在 Java8 中很常见,如以下的例子:
Stream<Integer> numUp = Stream.of(1, 2, 5).map(num -> num += 1);
Stream<Integer> numbers = Stream.of(1, 2, -1, -5).filter(n -> n > 0);
如何判断高阶函数
Stream 的 anyMatch 是高阶函数吗?是的。因为它的参数接收的是另外一个函数:Predicate。
boolean greaterThanZero = Stream.of(-1, -2, 0, -5).anyMatch(num -> num > 0);
Stream 的 limit 是高阶函数吗?是的。因为它的返回值是一个Stream。
Stream<Integer> onlyTwoNumbers = Stream.of(-1, -2, 0, -5).limit(2);