精华内容
下载资源
问答
  • jdk新特性
    千次阅读
    2022-02-10 15:08:24

    JDK各个版本的新特性

    ************ 如有侵权请提示删除 ***************


    JDK1.19 新特性

    开发中。。。

    JDK1.18 新特性

    开发中。。。

    JDK1.17 新特性

    2021-09-14
    LTS (Long Term Support) 版本

    • 306: 恢复始终严格的浮点语义:使浮点运算始终保持严格,而不是同时具有严格的浮点语义 ( strictfp) 和细微不同的默认浮点语义。这将恢复语言和 VM 的原始浮点语义,与 Java SE 1.2 中引入严格和默认浮点模式之前的语义相匹配。
    • 356: 增强的伪随机数生成器:为伪随机数生成器 (PRNG) 提供新的接口类型和实现,包括可跳转 PRNG 和另一类可拆分 PRNG 算法 (LXM)。
    • 382: 新的 macOS 渲染管道:使用 Apple Metal API 为 macOS 实现 Java 2D 内部渲染管道,以替代使用已弃用的 Apple OpenGL API 的现有管道。
    • 391: macOS/AArch64 端口:将 JDK 移植到 macOS/AArch64。
    • 398: 弃用 Applet API 以进行删除:弃用 Applet API 以进行删除。这基本上是无关紧要的,因为所有网络浏览器供应商要么已取消对 Java 浏览器插件的支持,要么已宣布计划这样做。
    • 403: 强烈封装 JDK 内部:强烈封装 JDK 的所有内部元素,除了 关键的内部 API,例如sun.misc.Unsafe. 将不再可能通过单个命令行选项放松对内部元素的强封装,这在 JDK 9 到 JDK 16 中是可能的。
    • 406: 开关的模式匹配(预览版):通过表达式和语句的模式匹配switch 以及对模式语言的扩展来增强 Java 编程语言。扩展模式匹配以switch允许针对多个模式测试表达式,每个模式都有特定的操作,以便可以简洁安全地表达复杂的面向数据的查询。
    • 407: 删除 RMI 激活:删除远程方法调用 (RMI) 激活机制,同时保留 RMI 的其余部分。
    • 409: 密封类:使用密封的类和接口增强 Java 编程语言 。密封的类和接口限制了哪些其他类或接口可以扩展或实现它们。
    • 410: 删除实验性 AOT 和 JIT 编译器:删除实验性的基于 Java 的提前 (AOT) 和即时 (JIT) 编译器。该编译器自推出以来很少使用,维护它所需的工作量很大。保留实验性的 Java 级 JVM 编译器接口 (JVMCI),以便开发人员可以继续使用外部构建的编译器版本进行 JIT 编译。
    • 411: 弃用安全管理器以进行删除:弃用安全管理器以便在将来的版本中删除。安全管理器可追溯到 Java 1.0。多年来,它一直不是保护客户端 Java 代码的主要方法,也很少用于保护服务器端代码。为了推动 Java 向前发展,我们打算弃用安全管理器,以便与旧版 Applet API ( JEP 398 ) 一起移除。
    • 412: 外部函数和内存 API(孵化器):引入一个 API,Java 程序可以通过该 API 与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存(即不受 JVM 管理的内存),API 使 Java 程序能够调用本机库并处理本机数据,而不会出现脆弱性和危险。 JNI。
    • 414: Vector API(第二个孵化器):引入一个 API 来表达向量计算,该计算可以在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于等效标量计算的性能。
    • 415: 特定于上下文的反序列化过滤器:允许应用程序通过 JVM 范围的过滤器工厂配置特定于上下文和动态选择的反序列化过滤器,该过滤器工厂被调用来为每个单独的反序列化操作选择一个过滤器。

    JDK 17

    JDK1.16 新特性

    2021-03-16

    • 338: 矢量 API(孵化器):提供孵化器模块的初始迭代, jdk.incubator.vector以表达向量计算,这些计算在运行时可靠地编译为支持的 CPU 架构上的最佳向量硬件指令,从而实现优于等效标量计算的性能。
    • 347: 启用 C++14 语言功能:允许在 JDK C++ 源代码中使用 C++14 语言功能,并就哪些功能可以在 HotSpot 代码中使用提供具体指导。
    • 357: 从 Mercurial 迁移到 Git:在GitHub上托管OpenJDK 社区的 Git 存储库。与JEP 357(从 Mercurial 迁移到 Git)一致,这会将所有单存储库 OpenJDK 项目迁移到 GitHub,包括JDK 功能版本和版本 11 及更高版本的JDK 更新版本。
    • 369: 迁移到 GitHub
    • 376: ZGC:并发线程堆栈处理:将 ZGC 线程堆栈处理从安全点移至并发阶段。
    • 380: Unix 域套接字通道:将 Unix-domain ( AF_UNIX) 套接字支持添加到包中的套接字通道和服务器套接字通道API java.nio.channels。扩展继承的通道机制以支持 Unix 域套接字通道和服务器套接字通道。
    • 386: 高山 Linux 端口:将 JDK 移植到 Alpine Linux,以及其他使用 musl 作为主要 C 库的 Linux 发行版,在 x64 和 AArch64 架构上,
    • 387: 弹性元空间:更及时地将未使用的 HotSpot 类元数据(即元空间)内存返回给操作系统,减少元空间占用,并简化元空间代码以降低维护成本。
    • 388: Windows/AArch64 端口:将 JDK 移植到 Windows/AArch64。
    • 389: 外部链接器 API(孵化器):引入一个 API,该 API 提供对本机代码的静态类型纯 Java 访问。此 API 与 Foreign-Memory API ( JEP 393 ) 一起,将大大简化绑定到本机库的其他容易出错的过程。
    • 390: 基于值的类的警告:将原始包装类指定为基于值的,并弃用它们的构造函数以进行删除,从而提示新的弃用警告。提供有关在 Java 平台中任何基于值的类的实例上不正确尝试同步的警告。
    • 392: 打包工具:提供jpackage工具,用于打包自包含的 Java 应用程序。
    • 393: Foreign-Memory Access API(第三孵化器):引入 API 以允许 Java 程序安全有效地访问 Java 堆之外的外部内存。
    • 394: instanceof 的模式匹配:通过 运算符的模式匹配增强 Java 编程语言instanceof。 模式匹配 允许程序中的通用逻辑,即从对象中条件提取组件,可以更简洁和安全地表达。
    • 395: 记录:使用记录增强 Java 编程语言,记录是充当不可变数据的透明载体的类。记录可以被认为是名义元组。
    • 396: 默认情况下对 JDK 内部进行强封装:默认情况下强烈封装 JDK 的所有内部元素,除了关键的内部 API,例如sun.misc.Unsafe. 允许最终用户选择自 JDK 9 以来一直默认的宽松强封装。
    • 397: 密封课程(第二次预览):使用密封的类和接口增强 Java 编程语言 。密封的类和接口限制了哪些其他类或接口可以扩展或实现它们。

    JDK 16

    JDK1.15 新特性

    2020-09-15

    • 339: 爱德华兹曲线数字签名算法 (EdDSA):如RFC 8032所述,使用 Edwards-Curve 数字签名算法 (EdDSA) 实施加密签名。
    • 360: 密封类(预览版):使用密封的类和接口增强 Java 编程语言。密封的类和接口限制了哪些其他类或接口可以扩展或实现它们。
    • 371: 隐藏类:引入隐藏类,即不能被其他类的字节码直接使用的类。隐藏类旨在供在运行时生成类并通过反射间接使用它们的框架使用。隐藏类可以定义为访问控制嵌套的成员,并且可以独立于其他类卸载。
    • 372: 移除 Nashorn JavaScript 引擎
    • 373: 重新实现旧版 DatagramSocket API:用易于维护和调试的更简单、更现代的实现替换java.net.DatagramSocket和API的底层实现。java.net.MulticastSocket新的实现将很容易适应虚拟线程,目前正在Project Loom中进行探索。这是JEP 353的后续,它已经重新实现了旧的 Socket API。
    • 374: 禁用和弃用偏向锁定
    • 375: instanceof 的模式匹配(第二次预览):通过运算符的模式匹配增强 Java 编程语言instanceof。模式匹配允许程序中的通用逻辑,即从对象中条件提取组件,可以更简洁和安全地表达。这是 JDK 15 中的预览语言功能。
    • 377: ZGC:可扩展的低延迟垃圾收集器:将 Z 垃圾收集器从实验功能更改为产品功能。
    • 378: 文本块
    • 379: Shenandoah:一个低暂停时间的垃圾收集器:将 Shenandoah 垃圾收集器从实验功能更改为产品功能。
    • 381: 删除 Solaris 和 SPARC 端口:删除源代码并构建对 Solaris/SPARC、Solaris/x64 和 Linux/SPARC 端口的支持。这些端口在 JDK 14 中已被弃用以删除,并明确打算在未来的版本中删除它们。
    • 383: Foreign-Memory Access API(第二个孵化器):引入 API 以允许 Java 程序安全有效地访问 Java 堆之外的外部内存。
    • 384: 记录(第二次预览);使用记录增强 Java 编程语言,记录是充当不可变数据的透明载体的类。记录可以被认为是名义元组。
    • 385: 弃用 RMI 激活以进行删除:弃用RMI 激活 机制以供将来删除。RMI 激活是 RMI 的一个过时部分,自 Java 8 以来一直是可选的。RMI 的任何其他部分都不会被弃用。

    JDK 15

    JDK1.14 新特性

    2020-03-17

    • 305 Pattern Matching for instanceof (Preview) instanceof 的模式匹配(预览):通过 运算符的模式匹配增强 Java 编程语言instanceof 。模式匹配 允许程序中的通用逻辑,即从对象中条件提取组件,可以更简洁和安全地表达。这是 JDK 14 中的预览语言功能。
    • 343 Packaging Tool (Incubator) 打包工具(孵化):创建用于打包自包含 Java 应用程序的工具。
    • 345 NUMA-Aware Memory Allocation for G1 G1 的NUMA 内存分配优化:通过实施 NUMA 感知内存分配来提高大型机器上的 G1 性能。
    • 349 JFR Event Streaming JFR事件流:公开 JDK Flight Recorder 数据以进行持续监控。
    • 352 Non-Volatile Mapped Byte Buffers 非原子性的字节缓冲区映射:添加新的 JDK 特定文件映射模式,以便FileChannelAPI 可用于创建MappedByteBuffer引用非易失性内存的实例。
    • 358 Helpful NullPointerExceptions 非常有帮助的空指针异常:NullPointerException通过精确描述哪个变量是 来提高 JVM 生成的 s 的可用性null。
    • 359 Records (Preview) Records(预览):使用记录增强 Java 编程语言。记录为声明类提供了一种紧凑的语法,这些类是浅层不可变数据的透明持有者。这是 JDK 14 中的预览语言功能。
    • 361 Switch Expressions (Standard) Switch 表达式(标准):扩展switch,因此它可以用作语句或表达式,并且两种形式都可以使用传统case … :标签(有失效)或新case … ->标签(没有失效),还有一个新的语句用于从 a 中产生一个值switch表达。这些更改将简化日常编码,并为在switch. 这是JDK 12和JDK 13中的预览语言功能。
    • 362 Deprecate the Solaris and SPARC Ports 弃用 Solaris 和S PARC 端口:弃用 Solaris/SPARC、Solaris/x64 和 Linux/SPARC 端口,以便在未来的版本中删除它们。
    • 363 Remove the Concurrent Mark Sweep (CMS) Garbage Collector 移除 CMS(Concurrent Mark Sweep)垃圾收集器:删除并发标记清除 (CMS) 垃圾收集器。
    • 364 ZGC on macOS macOS 系统上的 ZGC:将 ZGC 垃圾收集器移植到 macOS。
    • 365 ZGC on Windows Windows 系统上的 ZGC:将 ZGC 垃圾收集器移植到 Windows。
    • 366 Deprecate the ParallelScavenge + SerialOld GC Combination 弃用 ParallelScavenge + SerialOld GC 组合:弃用 Parallel Scavenge 和 Serial Old 垃圾回收算法的组合。
    • 367 Remove the Pack200 Tools and API 移除Pack200 Tools和API
    • 368 Text Blocks (Second Preview) 文本块(第二个预览版)
    • 370 Foreign-Memory Access API (Incubator) 外部存储器API(孵化)

    JDK 14

    JDK1.13新特性

    2019-09-17

    新特性:

    • 350 Dynamic CDS Archives 对appCDS进行性了扩展,允许在Java应用执行结束时动态归档类。归档类包括包括默认的基础层CDS(class data-sharing) 存档中不存在的所有已加载的应用程序类和类库。通过此仿瓷提高了AppCDS的可用性;
    • 351 ZGC: Uncommit Unused Memory 对ZGC进行了增强,在以前的版本中,java GC之后并不会将系统内存释放给OS,因为每次释放都意味着重新调整jvm的内存大小,存在一定的消耗;随着软件的发展,我们发现在很多时候内存是比较昂贵的资源,所以将不用的内存释放回去给OS是非常有必要的;此功能在默认情况下已开始,但可以通过-xx:-zuncommit参数禁用;注意:如果最新内存参数设置比最大内存参数大,那么此功能将隐式禁用。
    • 353 Reimplement the Legacy Socket API 在这个版本中,将使用新的实现来代替java.net.socket和java.net.serversocket API的底层实现。新版本中旧的API还未删除,可以通过配置系统属性"jdk.net.useplansocketimpl"来使用他们。但默认实现是最新版本的。
    • 354 Switch Expressions (Preview) 扩展开关,以便它可以用作语句或表达式,并且两种形式都可以使用传统的情况…:标签(带有贯穿线)或新案例…->标签(没有掉进去),还有一个新的语句,用于从开关表达式中产生值。这些变化将简化日常编码,并为在交换机中使用模式匹配做好准备。这是jdk 13中的一个预览语言特性。
    • 355 Text Blocks (Preview) 向Java语言添加文本块。文本块是一个多行字符串文本,它避免了大多数转义序列的需要,自动以可预测的方式格式化字符串,并在需要时让开发人员控制格式。这是jdk 13中的一个预览语言特性。

    此外,JDK8的截止时间为2019年1月份,到期后,Oracle将不再提供补丁及其它的更新服务。官网称可能会更久,JDK9的截止时间是2018年3月,JDK10的截止版本是2018年9月。(详细请前往:http://www.oracle.com/technetwork/java/javase/eol-135779.html?ssSourceSiteId=otncn),JDK 9和 JDK 10都是一个短期版本,故稳定长期的版本可能是JAVA 11(LTS - Long Term Support)版本。

    JDK 13

    JDK1.12 新特性

    翻译后的新特性有:

    - 189: Shenandoah: A Low-Pause-Time Garbage Collector (Experimental) :新增一个名为 Shenandoah 的垃圾回收器,它通过在 Java 线程运行的同时进行疏散 (evacuation) 工作来减少停顿时间。

    • 230: Microbenchmark Suite:新增一套微基准测试,使开发者能够基于现有的 Java Microbenchmark Harness(JMH)轻松测试 JDK 的性能,并创建新的基准测试。
    • 325: Switch Expressions (Preview) :切换表达式(预览),对 switch 语句进行扩展,使其可以用作语句或表达式,简化日常代码。
    • 334: JVM Constants API :JVM 常量 API,引入一个 API 来对关键类文件 (key class-file) 和运行时工件的名义描述(nominal descriptions)进行建模,特别是那些可从常量池加载的常量。
    • 340: One AArch64 Port, Not Two :删除与 arm64 端口相关的所有源码,保留 32 位 ARM 移植和 64 位 aarch64 移植。
    • 341: Default CDS Archives :默认生成类数据共享(CDS)存档。
    • 344: Abortable Mixed Collections for G1 :当 G1 垃圾回收器的回收超过暂停目标,则能中止垃圾回收过程.
    • 346: Promptly Return Unused Committed Memory from G1 :立即从 G1 返回未使用的已提交内存,改进 G1 垃圾回收器,以便在空闲时自动将 Java 堆内存返回给操作系统。

    JDK 12

    JDK1.11 新特性

    2018-09-25

    LTS (Long Term Support) 版本

    翻译后的新特性有:

    • 181:Nest-Based基于嵌套的访问控制
    • 309:动态类文件常量
    • 315:改进 Aarch64 内在函数intrinsic
    • 318:无操作垃圾收集器
    • 320:消除Java EE和CORBA模块
    • 321:HTTP客户端(标准)
    • 323:局部变量的语法λ参数
    • 324:Curve25519和Curve448关键协议
    • 327:Unicode 10
    • 328:飞行记录器
    • 329:ChaCha20和Poly1305加密算法
    • 330:发射一列纵队源代码程序
    • 331:低开销堆分析
    • 332:传输层安全性(Transport Layer Security,TLS)1.3
    • 333:动作:一个可伸缩的低延迟垃圾收集器 (实验)
    • 335:反对Nashorn JavaScript引擎
    • 336:反对Pack200工具和API

    JDK 11

    JDK1.10 新特性

    2018-03-21

    根据官网的公开资料,共有12个重要特性,如下:

    • JEP286,var 局部变量类型推断。
    • JEP296,将原来用 Mercurial 管理的众多 JDK 仓库代码,合并到一个仓库中,简化开发和管理过程。
    • JEP304,统一的垃圾回收接口。
    • JEP307,G1 垃圾回收器的并行完整垃圾回收,实现并行性来改善最坏情况下的延迟。
    • JEP310,应用程序类数据 (AppCDS) 共享,通过跨进程共享通用类元数据来减少内存占用空间,和减少启动时间。
    • JEP312,ThreadLocal 握手交互。在不进入到全局 JVM 安全点 (Safepoint) 的情况下,对线程执行回调。优化可以只停止单个线程,而不是停全部线程或一个都不停。
    • JEP313,移除 JDK 中附带的 javah 工具。可以使用 javac -h 代替。
    • JEP314,使用附加的 Unicode 语言标记扩展。
    • JEP317,能将堆内存占用分配给用户指定的备用内存设备。
    • JEP317,使用 Graal 基于 Java 的编译器,可以预先把 Java 代码编译成本地代码来提升效能。
    • JEP318,在 OpenJDK 中提供一组默认的根证书颁发机构证书。开源目前 Oracle 提供的的 Java SE 的根证书,这样 OpenJDK 对开发人员使用起来更方便。
    • JEP322,基于时间定义的发布版本,即上述提到的发布周期。版本号为$FEATURE.$INTERIM.$UPDATE.$PATCH,分j别是大版本,中间版本,升级包和补丁版本。

    JDK 10

    JDK1.9 新特性

    • 模块系统:模块是一个包的容器,Java 9 最大的变化之一是引入了模块系统(Jigsaw 项目)。
    • REPL (JShell):交互式编程环境。
    • HTTP 2 客户端:HTTP/2标准是HTTP协议的最新版本,新的 HTTPClient API 支持 WebSocket 和 HTTP2 流以及服务器推送特性。
    • 改进的 Javadoc:Javadoc 现在支持在 API 文档中的进行搜索。另外,Javadoc 的输出现在符合兼容 HTML5 标准。
    • 多版本兼容 JAR 包:多版本兼容 JAR 功能能让你创建仅在特定版本的 Java 环境中运行库程序时选择使用的 class 版本。
    • 集合工厂方法:List,Set 和 Map 接口中,新的静态工厂方法可以创建这些集合的不可变实例。
    • 私有接口方法:在接口中使用private私有方法。我们可以使用 private 访问修饰符在接口中编写私有方法。
    • 进程 API: 改进的 API 来控制和管理操作系统进程。引进 java.lang.ProcessHandle 及其嵌套接口 Info 来让开发者逃离时常因为要获取一个本地进程的 PID 而不得不使用本地代码的窘境。
    • 改进的 Stream API:改进的 Stream API 添加了一些便利的方法,使流处理更容易,并使用收集器编写复杂的查询。
    • 改进 try-with-resources:如果你已经有一个资源是 final 或等效于 final 变量,您可以在 try-with-resources 语句中使用该变量,而无需在 try-with-resources 语句中声明一个新变量。
    • 改进的弃用注解 @Deprecated:注解 @Deprecated 可以标记 Java API 状态,可以表示被标记的 API 将会被移除,或者已经破坏。
    • 改进钻石操作符(Diamond Operator) :匿名类可以使用钻石操作符(Diamond Operator)。
    • 改进 Optional 类:java.util.Optional 添加了很多新的有用方法,Optional 可以直接转为 stream。
    • 多分辨率图像 API:定义多分辨率图像API,开发者可以很容易的操作和展示不同分辨率的图像了。
    • 改进的 CompletableFuture API : CompletableFuture 类的异步机制可以在 ProcessHandle.onExit 方法退出时执行操作。
    • 轻量级的 JSON API:内置了一个轻量级的JSON API
    • 响应式流(Reactive Streams) API: Java 9中引入了新的响应式流 API 来支持 Java 9 中的响应式编程。
      JDK 9
      详细参考:http://www.runoob.com/java/java9-new-features.html

    JDK1.8 新特性

    2014-03-18
    LTS (Long Term Support) 版本

    • Lambda 表达式 − Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。

    • 方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。

    • 默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。

    • 新工具 − 新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。

    • Stream API −新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。

    • Date Time API − 加强对日期与时间的处理。

    • Optional 类 − Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。

    • Nashorn, JavaScript 引擎 − Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。

    https://www.runoob.com/java/java8-new-features.html
    Java8新特性

    JDK1.7 新特性

    2011-07-28 Dolphin(海豚)

    LTS (Long Term Support) 版本

    • switch语句块中允许以字符串作为分支条件;
    • 在创建泛型对象时应用类型推断;
    • 在一个语句块中捕获多种异常;
    • 支持动态语言;
    • 支持try-with-resources(在一个语句块中捕获多种异常);
    • 引入Java NIO.2开发包;
    • 数值类型可以用二进制字符串表示,并且可以在字符串表示中添加下划线;
    • 钻石型语法(在创建泛型对象时应用类型推断);
    • null值得自动处理;

    JDK1.6 新特性

    2006-12-11 Mustang(野马)

    • 支持脚本语言;
    • JDBC 4.0API;
    • Java Compiler API;
    • 可插拔注解;
    • 增加对Native PKI(Public Key Infrastructure), Java GSS(Generic Security Service),Kerberos和LDAP(Lightweight Directory Access Protocol)支持;
    • 继承Web Services;

    JDK1.5 新特性

    2004-09-30 Tiger(老虎)

    • 泛型;
    • 增强循环,可以使用迭代方式;
    • 自动装箱与自动拆箱;
    • 类型安全的枚举;
    • 可变参数;
    • 静态引入;
    • 元数据(注解);
    • Instrumentation;

    JDK Version 1.4

    2004-02-06 Merlin(隼)

    • XML处理;
    • Java打印服务;
    • Logging API;
    • Java Web Start;
    • JDBC 3.0 API;
    • 断言;
    • Preferences API;
    • 链式异常处理;
    • 支持IPV6;
    • 支持正则表达式;
    • 引入Imgae I/O API.

    JDK Version 1.3

    2000-05-08 Kestrel(红隼)

    • Java Sound API;
    • jar文件索引;
    • 对Java的各个方面都做了大量优化和增强;

    JDK Version 1.2

    1998-12-08 Playground(操场)

    • 集合框架;
    • JIT(Just In Time)编译器;
    • 对打包的Java文件进行数字签名;
    • JFC(Java Foundation Classes), 包括Swing 1.0, 拖放和Java2D类库;
    • Java插件;
    • JDBC中引入可滚动结果集,BLOB,CLOB,批量更新和用户自定义类型;
    • Applet中添加声音支持.

    JDK Version 1.1

    1997-02-19

    • JDBC(Java DataBase Connectivity);
    • 支持内部类;
    • RMI(Remote Method Invocation) ;
    • 反射;
    • Java Bean;

    JDK Version 1.0

    1996-01-23 Oak(橡树)

    • 初代版本,伟大的一个里程碑,但是是纯解释运行,使用外挂JIT,性能比较差,运行速度慢。

    Java Platform, Standard Edition Documentation - Releases

    JDK从入门到高阶,面试必备之JDK8-14系统课程-全面【黑马程序员】_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

    更多相关内容
  • 本课程专门针对JDK8-15新特性进行一一讲解,每个新特性都进行案例演示,通俗易懂易学习。 讲解方式: 课程讲解通俗易懂,课程重点剖析模块化系统、交互式编程。 课程内容: 课程讲解通俗易懂,课程重点剖析模块化...
  • jdk新特性

    2019-05-25 02:33:55
    java新特性.rar,java新特性.doc
  • 借鉴前人经验,在经过不断实践之后,将Strean流部分方法整理成适合于自身需要的文档,供大家借鉴分享。
  • JDK新特性笔记1

    2022-08-03 11:59:47
    JDK新特性笔记1
  • jdk1.8-9新特性视屏
  • 十八、JDK新特性.md

    2021-09-04 15:37:22
    十八、JDK新特性
  • 超全面javaweb教程第7天-_17_jdk新特性的总结
  • Tutorial_JDKProperty JDK 新特性
  • [JAVA教程] 张老师JDK8实战视频教程 51集JDK8专业标准学习课程 全新JDK新特性与实战教学
  • JAVA_JDK新特性查看

    2016-04-01 18:05:41
    java jdk 新特性查看:

    java jdk 新特性查看:
    1,javase下载界面:http://www.oracle.com/technetwork/java/javase/downloads/index.html
    2,点击 Learn more
    3,点击 Release Notes for JDK 8 and JDK 8 Update Releases.
    4,第三步加载完,直接滑动到最后你会看到:What’s New in JDK 8
    5,点击该项,你可以看到当前jdk版本的新特性。
    6,然后点击任意一项新特性链接
    docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html
    在这里你会看到jdk历史版本的新特性

    图例:
    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里写图片描述

    展开全文
  • JDK1.8新特性

    千次阅读 2021-09-23 21:30:11
    JDK1.8新特性 总的来说,JDK在以下方面具有新特性: 速度更快 – 红黑树 代码更少 – Lambda 强大的Stream API – Stream 便于并行 – Parallel 最大化减少空指针异常 – Optional 1、HashMap中的红黑树 HashMap...

    JDK1.8新特性


    总的来说,JDK在以下方面具有新特性:

    1. 速度更快 – 红黑树
    2. 代码更少 – Lambda
    3. 强大的Stream API – Stream
    4. 便于并行 – Parallel
    5. 最大化减少空指针异常 – Optional

    1、HashMap中的红黑树

    HashMap中链长度大于8时采取红黑树的结构存储。

    红黑树,除了添加,效率高于链表结构。


    2、ConcurrentHashMap

    Jdk1.7时隔壁级别CocnurrentLevel(锁分段机制)默认为16。

    JDK1.8采取了CAS算法

    Jdk1.8没有永久区,取而代之的是MetaSpace元空间,用的是物理内存。


    3、Lambda表达式

    1、Lambda表达式的基础语法:Java8引入了一个新的操作符“->”,该操作符成为箭头操作符或者Lambda操作符,箭头操作符将Lambda表达式拆分成两部分

    左侧:Lambda表达式的参数列表
    右侧:Lambda表达式中所需执行的功能,即Lambda体。

    语法格式一:无参数,无返回值

    Runnable r2 = () -> System.out.println("hello lambda");
            r2.run();
    

    语法格式二:有一个参数,并且无返回值
    (x) -> System.out.print(x);

    语法格式三:若只有一个参数,小括号可以省略不写
    x -> System.out.print(x);

    语法格式四:有两个以上的参数,有返回值,并且Lambda体中有多条语句

            Comparator<Integer> c1 = (x, y) -> {
                System.out.print(Integer.compare(x, y)+"函数式接口");
                return Integer.compare(x, y);
            }  ;
            c1.compare(1, 2);
    

    语法格式五:若Lambda体中只有一条语句,return和大括号都可以省略不写

    Comparator<Integer> c1 = (x,y) -> Integer.compare(x,y);
    

    语法格式六:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器可以通过上下文进行类型推断出数据类型,既“类型推断”。
    (Integer x,Integer y) -> Integre.compare(x,y);

    总结:
    左右遇一括号省,左侧推断类型省, 能省则省。


    2、Lambda表达式的函数式接口


    一些基本的使用示例

    List<Employee> list = Arrays.asList(
                new Employee("张三", "上海", 5000, 22),
                new Employee("李四", "北京", 4000, 23),
                new Employee("c五", "日本", 6000, 50),
                new Employee("b七", "香港", 7000, 50),
                new Employee("赵六", "纽约", 1000, 8)
        );
    
        /**
         *需求1:lambda表达式的使用:
         * 调用COllections.sort方法,通过定制排序比较两个Employee(先按年龄比较,年龄相同按姓名比),使用
         * Lambda作为参数传递。
         */
        @Test
        public void test1(){
            Collections.sort(list,(x,y)->{
                if(x.getAge()!=y.getAge())
                    return Integer.compare(x.getAge(),y.getAge());
                else
                    return x.getName().compareTo(y.getName());
    
            });
    
            for (Employee employee : list) {
                System.out.println(employee);
            }
        }
    
        /**
         * 需求2:
         * 1.声明函数式接口,接口中声明抽象方法,public String getvalue(String str();
         * 2.声明类TestLambda,类中编写方法使用接口作为参数,讲一个字符串转换成大写,并作为方法的返回值。
         */
        @Test
        public void test2(){
            String str = getvalue("hello world", x -> x.toUpperCase());
            System.out.print(str);
    
        }
        public String getvalue(String str,MyFunction1 my){
            return my.getValue(str);
        }
    
        @FunctionalInterface
        public interface MyFunction1{
            public String getValue(String str);
        }
    
    
        /**
         * 需求3:
         * 1.声明一个带两个泛型的函数式接口,泛型类型是<T,R>,T为参数,R为返回值。
         * 2.接口中声明对应抽象方法
         * 3.在TestLambda类中声明方法,使用接口作为参数,计算两个long型参数的和
         * 4.在计算两个long型参数的乘积
         */
        @Test
        public void test3(){
            Long r = getR(25l,30l, (t1,t2) -> t1 * t2);
            System.out.print(r);
    
            Long r1 = getR(25l, 23l, (t1, t2) -> t1 + t2);
            System.out.print(r1);
    
        }
        public <T,R> R getR(T t1,T t2,MyFUnction2<T,R> mf){
            return mf.method(t1,t2);
        }
    
        public interface MyFUnction2<T,R>{
            public R method(T t1,T t2);
        }
    

    Java8中的四大核心函数式接口

    /*
    Consumer<T> :消费型接口
        void accept(T t);
    
    Supplier<T> :供给型接口
        T get();
    
    Function<T,R> :函数型接口
        R apply(T t);
    
    Predicate<T> :断言型接口
        boolean test(T t);
    */
    

    Lambda表达式的
    一、方法引用
    若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”(可以理解为方法引用是Lambda表达式的另外一种表现形式)

    主要语法:

    对象::实例方法名

    类::静态方法名

    类::实例方法名

    注意:
    ①Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型一致。
    ②若Lambda参数列表中的第一参数是实例方法的调用者,而第二个参数是实例方法的参数时,可以使用ClassName::method进行调用。


    二、构造器引用

    格式:

    ClassName::new

    注意:需要引用的构造器的参数列表要与函数式接口中抽象方法的参数列表保持一致。

    三、数组引用

    格式:

    Type[]::new


    4、Stream流

    一系列流水线式的中间操作。

    流是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

    注意:
    ①Stream自己不会存储元素。
    ②Stream不会改变源对象。相反,会返回持有新结果的新Stream。
    ③Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。


    操作的三个步骤:
    1、创建一个流Stream
    2、中间操作
    3、终止操作


    创建:

    @Test
        public void test1(){
            //1. 可以通过Collections系列集合提供的stream()或parallelStream()
            List<String> list = new ArrayList<>();
            Stream<String> stream = list.stream();
    
            //2. 通过Arrays中的静态方法stream()获取数组流
            Employee[] emps = new Employee[10];
            Stream<Employee> stream1 = Arrays.stream(emps);
    
            //3. 通过Stream类中的静态方法of()
            Stream<String> stream3 = Stream.of("", "", "");
    
            //4. 创建无限流
            //迭代
            Stream.iterate(0,x -> x+2).limit(10).forEach(System.out::println);
    
            //生成
            Stream<Double> generate = Stream.generate(() -> Math.random());
            generate.limit(5).forEach(System.out::println);
        }
    

    中间操作:API

    多个中间操作可以连接起来形成一个流水线,除非流水想上出发终止操作。否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,成为“惰性求值”。

    筛选和切片

       /**
        * 筛选和切片
        *
        * filter -- 接受Lambda,从流中排除某些元素
        * limit -- 截断流,使其元素不超过某个给定数量
        * skip -- 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit互补。
        * distinct -- 去重,通过hashcode和equals去重。
        */
    
       List<Employee> list = Arrays.asList(
               new Employee("张三", "上海", 5000, 22),
               new Employee("李四", "北京", 4000, 23),
               new Employee("c五", "日本", 6000, 50),
               new Employee("b七", "香港", 7000, 50),
               new Employee("赵六", "纽约", 1000, 8)
       );
    
       @Test
       public void test1(){
           Stream<Employee> stream = list.stream();//创建流
    
           stream
                   .filter(e -> e.getAge()>25)//过滤符合条件的流元素
                   .limit(5)//只取5个
                   .skip(4)//跳过4个
                   .distinct()//去重,需重写hashcode和equals方法
                   .forEach(System.out::println);//终止操作,获取流
    
       }
    

    映射
    接受Lambda,将元素转换成其他形式或提取信息,接受一个函数作为参数, 该函数会被应用到每个元素上,并将其映射成一个新的元素。

    public class StreamTest3 {
        //中间操作
    
        /**
         * 映射
         * map -- 接受Lambda,将元素转换成其他形式或提取信息,接受一个函数作为参数,
         * 该函数会被应用到每个元素上,并将其映射成一个新的元素。
         *
         * flatmap -- 接受一个函数做为参数,将流中的每个值都转换成另一个流,然后将所有流连接成一个流,
         */
    
        List<Employee> emps = Arrays.asList(
                new Employee("张三", "上海", 5000, 22),
                new Employee("李四", "北京", 4000, 23),
                new Employee("c五", "日本", 6000, 50),
                new Employee("b七", "香港", 7000, 50),
                new Employee("赵六", "纽约", 1000, 8)
        );
        @Test
        public void test2(){
            emps
                    .stream()//创建流
                    .map(employee -> employee.getName())//中间操作:映射
                    .forEach(System.out::println);//终止流
    
    
        }
    
        @Test
        public void test3(){
            List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
            Stream<Stream<Character>> streamStream = list
                    .stream()
                    .map(StreamTest3::getCharacter);//流中还是流
    
    
            streamStream
                    .forEach(sm->sm
                            .forEach(System.out::println));
    
    
            System.out.println("-------------------------------------");
    
            list.stream()
                    .flatMap(StreamTest3::getCharacter)//大流中直接包含的是流元素,相当于add和addAll的区别。
                    .forEach(System.out::println);
        }
        public static Stream<Character> getCharacter(String str){
            List<Character> list = new ArrayList<>();
            for (char c : str.toCharArray()) {
                list.add(c);
            }
            return list.stream();
        }
    }
    

    public class StreamTest4 {
        //中间操作
        /**
         * 排序
         *
         * sorted -- 自然排序(Comparable)
         * sorted(Comparator com) -- 定制排序(Comparator)
         */
    
        @Test
        public void test1(){
            List<String> list =
                    Arrays.asList("ddd", "ccc", "ggg", "bbb", "aaa");
    
            list.stream()
                    .sorted()//自然排序
                    .forEach(System.out::println);
    
            System.out.println("------------------------------");
    
            emps.stream()
                    .sorted((e1,e2) -> {//定制排序
                        if(e1.getSalary() == e2.getSalary())
                            return e1.getName().compareTo(e2.getName());
                        else
                            return e1.getSalary() - e2.getSalary();
                    }).forEach(System.out::println);
    
        }
    
    
    
    
    
    
    
    
        List<Employee> emps = Arrays.asList(
                new Employee("张三", "上海", 5000, 22),
                new Employee("李四", "北京", 4000, 23),
                new Employee("c五", "日本", 6000, 50),
                new Employee("b七", "香港", 6000, 50),
                new Employee("赵六", "纽约", 1000, 8)
        );
    
    }
    

    Stream的终止操作
    - allMatch – 检查是否匹配所有元素
    - anyMatch – 检查是否至少匹配一个元素
    - noneMatch – 检查是否没有匹配所有元素
    - findFirst – 返回第一个元素
    - count – 返回流中元素的总个数
    - max – 返回流中最大值
    - min – 返回流中最小值


      @Test
      public void test1(){
          boolean b = emps.stream()
                  .allMatch(emp -> emp.getStatus().equals(Status.FREE));
          System.out.println(b);
    
          boolean b1 = emps.stream().
                  anyMatch(emp -> emp.getStatus().equals(Status.BUSY));
          System.out.println(b1);
    
          boolean b2 = emps.stream()
                  .noneMatch(emp -> emp.getSalary() > 16000);
          System.out.println(b2);
    
          Optional<Employee> any = emps.parallelStream()//并行流
                  .findAny();
          System.out.println(any.get());
    
    
      }
    
      List<Employee> emps = Arrays.asList(
              new Employee("张三",9000.00,25,Status.FREE),
              new Employee("李四",16000.00,22,Status.BUSY),
              new Employee("王五",15000.00,22,Status.FREE),
              new Employee("赵六",12000.00,23,Status.VOCATION),
              new Employee("孙七",8000.00,26,Status.FREE),
              new Employee("唐八",19000.00,24,Status.BUSY)
      );
    
    

    终止操作:归约reduce

    map和reduce的连接通常称为map-reduce模式,因google用它进行网络搜索而出名

    /**
     * 终止操作:
     *
     * 归约
     * reduce(T identity, BinaryOperator) / reduce(BinaryOperator)
     *  -- 可以将流中的元素反复结合起来,得到一个值
     */
    @Test
    public void test1(){
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
    
        Optional<Double> reduce1 = emps.stream()
                .map(Employee::getSalary)//现将salsry映射出来
                .reduce(Double::sum);//进行归约求和
        System.out.println(reduce1.get());
    }
    
    

    终止操作:收集Collect(很强大)
    将流转换成其他格式,接受一个Collector接口的实现,用于给Stream中元素做汇总的操作。

    Collector接口中方法的实现决定了如何对流进行收集操作(如收集到List、Set、Map)中,Collectors实用类提供了很多静态方法,可以方便的创建常用收集器实例,具体方法见API

    /**
     * 收集
     * collect
     * -- 将流转换成其他的形式,接收一个Collector接口的实现,可以通过Collectors的实用类操作
     */
    @Test
    public void test2(){
        //收集姓名到列表
        List<String> collect = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
        System.out.println("-------------------------");
    
        //收集姓名到set
        Set<String> collect1 = emps.stream().map(Employee::getName)
                .collect(Collectors.toSet());
        collect1.forEach(System.out::println);
        System.out.println("--------------------------");
    
        //收集姓名到指定的数据结构
        LinkedHashSet<String> collect2 = emps.stream().map(Employee::getName)
                .collect(Collectors.toCollection(LinkedHashSet::new));
        collect2.forEach(System.out::println);
    }
    @Test
    public void test3(){
        //总数
        Long collect = emps.stream()
                .collect(Collectors.counting());
        System.out.println(collect);
        System.out.println("---------------------------------");
    
        //平均
        Double collect1 = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(collect1);
        System.out.println("-------------------------------");
    
        //总和
        Double collect2 = emps.stream().collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(collect2);
        System.out.println("-----------------------");
    
        //最大值
        Optional<Employee> collect3 = emps.stream().collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(collect3);
        System.out.println("-----------------------");
    }
    
    //分组
    @Test
    public void test4(){
        //单级分组
        Map<Status, List<Employee>> collect = emps.stream().collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(collect);
        System.out.println("----------------------");
    
        //多级分组
        Map<Status, Map<String, List<Employee>>> collect1 = emps.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
            if (e.getAge() < 20)
                return "少年";
            else if (e.getAge() < 30)
                return "青年";
            else
                return "中年";
        })));
        System.out.println(collect1);
        System.out.println("----------------------");
    
        //分区--满足条件一个区,不满足另一个区
        Map<Boolean, List<Employee>> collect2 = emps.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 8000));
        System.out.println(collect2);
        System.out.println("-----------------------");
    
        //收集各种统计数据
        DoubleSummaryStatistics collect3 = emps.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(collect3+"-----------平均薪水"+collect3.getAverage());
    
        //连接字符串
        String collect4 = emps.stream().map(Employee::getName).collect(Collectors.joining(",", "-----", "-----"));
        System.out.println(collect4);
    
    }
    

    一些练习:

    @Test
    public void test1(){
        /**
         * 需求1:
         *给定一个数字,如何返回一个有每个数的平方构成的列表?
         * 给定【1,2,3,4,5】,返回【1,4,9,16,25】
         */
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        List<Integer> collect = list.stream().map(integer -> integer * integer).collect((Collectors.toList()));
        System.out.println(collect);
    
        /**
         * 需求2:
         * 用reduce和map数一数流中的元素个数
         */
        Optional<Integer> reduce = list.stream()
                .map(e -> 1)//巧妙之处
                .reduce(Integer::sum);
        System.out.println(reduce);
    }
    
    

    5、并行流

    Fork/Join框架:
    在必要的情况下,将一个大任务进行必要的拆分Fork成若干个小任务,再将小任务的运算结果进行Join汇总。

    Fork/Join框架和传统线程池的区别:
    采用“工作窃取”模式(Working-stealing),即当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。

    相对于一般的线程池实现,fork/join框架的优势体现在对其中包含的任务的处理方式上,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态,而在fork/join框架实现中,如果某个子问题由于等待另外一个子问题的完成而无法继续运行,那么处理该子问题的线程会主动寻找其他尚未运行的子问题来执行,这种方式减少了线程等待的时间,提高了性能。

    并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
    Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API 可以声明性地通过parallel() 与sequential() 在并行流与顺序流之间进行切换。

    /**
     * 方式1:
     * 自己实现的ForkJoin
     */
    @Test
    public void test1(){
        Instant start = Instant.now();
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinCalculate(0, 100000000L);
    
        Long sum = pool.invoke(task);
        Instant end = Instant.now();
    
        System.out.println(Duration.between(start,end).toMillis());
    }
    public class ForkJoinCalculate extends RecursiveTask<Long> {
    
        private long start;
        private long end;
    
        private static final long THRESHHOLD = 10000;
    
        public ForkJoinCalculate(long start, long end) {
            this.start = start;
            this.end = end;
        }
    
        @Override
        protected Long compute() {
            long length = end - start;
    
            if(length <= THRESHHOLD){
                long sum = 0;
                for (long i = start; i <= end; i++) {
                    sum += i;
                }
                return sum;
            }else{
                long middle = (start + end) / 2;
    
                ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
                left.fork();
    
                ForkJoinCalculate right = new ForkJoinCalculate(middle + 1, end);
                right.fork();
    
                return left.join()+right.join();
            }
        }
    }
    
    
    /**
     * 方式2:
     * 直接使用for循环
     */
    @Test
    public void test2(){
        Instant start = Instant.now();
    
        Long sum = 0L;
        for (int i = 0; i <= 100000000L; i++) {
            sum += i;
        }
    
    
        Instant end = Instant.now();
        System.out.println(Duration.between(start,end).toMillis());
    
    }
    
    /**
     * 方式3:
     * JDK8的并行流实现。
     */
    @Test
    public void test3(){
        Instant start = Instant.now();
    
        long sum = LongStream.rangeClosed(0, 1000000000L)
                .parallel()//并行流
                //.sequential()//串行流
                .reduce(0, Long::sum);
    
        Instant end = Instant.now();
    
        System.out.println(Duration.between(start,end).toMillis());
    }
    //并行流将会充分使用多核的优势,多线程并行执行,基数越大,效果越明显。其底层还是Fork/Join框架。只不过SUN公司优化的更好,比自己实现更高效
    

    6、Optional类

    Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用null 表示一个值不存在,现在Optional 可以更好的表达这个概念。并且可以避免空指针异常。

    常用方法:
    - Optional.of(T t) : 创建一个Optional 实例
    - Optional.empty() : 创建一个空的Optional 实例
    - Optional.ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例
    - isPresent() : 判断是否包含值
    - orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
    - orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值
    - map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
    - flatMap(Function mapper):与map 类似,要求返回值必须是Optional


    public class OptinalTest1 {
        /**
         * 常用方法:
         Optional.of(T t) : 创建一个Optional 实例
         Optional.empty() : 创建一个空的Optional 实例
         Optional.ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例
         isPresent() : 判断是否包含值
         orElse(T t) : 如果调用对象包含值,返回该值,否则返回t
         orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值
         map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
         flatMap(Function mapper):与map 类似,要求返回值必须是Optional
         */
    
        //flatMap
        @Test
        public void test6(){
    //        Optional<Employee> op = Optional.ofNullable(new Employee("jim","shanghai",9000));
            Optional<Employee> op = Optional.ofNullable(null);
            //flatMap,返回的必须是Optional容器,进一步避免空指针异常
            Optional<Integer> optional = op.flatMap(e -> Optional.of(e.getSalary()));
            System.out.println(optional.orElse(10000));
        }
    
        //map
        @Test
        public void test5(){
    //        Optional<Employee> op = Optional.ofNullable(new Employee("jim","shanghai",9000));
            Optional<Employee> op = Optional.ofNullable(null);
    
    
            //有值返回map的操作,没值返回Optional.empty()
            Optional<Integer> salary = op.map(Employee::getSalary);
            System.out.println(salary.get());//如果传入为空,此时会报错
    
        }
    
        //ORelse
        //orElseGet
        @Test
        public void test4(){
            Optional<Object> op = Optional.ofNullable(null);
            if(op.isPresent()){
                System.out.println(op.get());
            }else{
                op.orElse(new Employee());//如果没值,传入默认的值
    
                Object o = op.orElseGet(Employee::new);//函数式接口,可以写更多
                System.out.println(o);
            }
        }
    
        //ofnullable
        @Test
        public void test3(){
            Optional<Object> op = Optional.ofNullable(null);
            if(op.isPresent())
                System.out.println(op.get());//仍然会报错,NoSUchELEMEnt.exception
            else
                System.out.println("No Value");
        }
    
        //empty
        @Test
        public void test2(){
            Optional<Object> op = Optional.empty();
            System.out.println(op.get());//也会报错,NoSuchElement.Exception
        }
    
        //of 构建
        @Test
        public void test1(){
            Optional<Employee> op = Optional.of(new Employee());
            Employee employee = op.get();
            System.out.println(employee);
    
            //Optional<Object> op2 = Optional.of(null);//直接传null会发生空指针异常
    //        Object o = op2.get();
    //        System.out.println(o);
        }
    }
    
    展开全文
  • JDK8核心新特性

    2021-06-20 20:02:08
    JDK8已经发行有几年了,在该版本中推出了不少新特性,其中比较有代表的新特性有:Lambda表达式,Stream流,方法引用。在网上也有很多关于这些新特性的介绍,但个人觉得网上的很多文字对新特性的介绍是不够全面的,...
  • JDK1.8新特性知识详解

    千次阅读 2022-03-23 11:36:47
    jdk 1.8 新特性知识详解

    jdk1.8新特性汇总如下图jdk1.8特性图汇总

    核心/常用知识点

    函数式编程(Lambda表达式)

    特点

    它不是一种具体的技术,是一种方法论,使用对应提供的函数进行编程,而不是去关心内部的实现。

    使用格式

    1·方法没有参数:()->{ }
    2·方法有参数:(参数,参数)->{ }
    3·如果现在只有一行语句返回:(参数,参数)->语句

    内置函数接口

    在这里插入图片描述

    Consumer 函数式接口(消费型)

    • 作用
      接受单个输入参数并且不返回结果的操作,与大多数其他功能接口不同, Consumer预期通过副作用进行操作。
    • 源码
      下面展示一些 内联代码片
    /**
     * 接受单个输入参数并且不返回结果的操作。
     * 与大多数其他功能接口不同, Consumer预期通过副作用进行操作。
     *
     * @since 1.8
     */
    @FunctionalInterface
    public interface Consumer<T> {
    
        /**
         * 对给定的参数执行此操作。
         *
         * @param t the input argument
         */
        void accept(T t);
    
        /**
         * 返回一个组合的Consumer ,依次执行此操作,然后执行after操作。 
         * 如果执行任一操作会抛出异常,它将被转发到组合操作的调用者。 
         * 如果执行此操作会引发异常,则不会执行after操作。
         *
         * @param 此操作后执行的操作
         * @return 一个组成的 Consumer ,依次执行 after操作
         * @throws NullPointerException - if after is null
         */
        default Consumer<T> andThen(Consumer<? super T> after) {
            Objects.requireNonNull(after);
            return (T t) -> { accept(t); after.accept(t); };
        }
    
    • 示例代码
      /**
       * 获取一个新的字符串
       * @param name
       * @param consumer
       */
      public static void getNewStr(String name,Consumer<String> consumer){
          consumer.accept(name);
      }
      
      public static void main(String[] args) {
         String name = "张三";
         getNewStr(name,(x)-> System.out.println(x+"去吃饭了..."));
         //输出结果为:张三去吃饭了...
      }
      
      从上述示例可以看出,这个函数相当于预先给你一些默认的操作,如果只要传入相对应的参数进去就能自动帮你实现功能。

    Function 函数(转换型)

    • 作用
      Function接口 接受一个输入参数T,返回一个结果R。
    • 源码
      下面展示一些 内联代码片
    @FunctionalInterface
    public interface Function<T, R> {
        // 接受输入参数,对输入执行所需操作后  返回一个结果。
        R apply(T t);
    
        // 返回一个 先执行before函数对象apply方法,再执行当前函数对象apply方法的 函数对象。
        default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
           Objects.requireNonNull(before);
           return (V v) -> apply(before.apply(v));
        }
    
        // 返回一个 先执行当前函数对象apply方法, 再执行after函数对象apply方法的 函数对象。
        default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
            Objects.requireNonNull(after);
            return (T t) -> after.apply(apply(t));
        }   
    
        // 返回一个执行了apply()方法之后只会返回输入参数的函数对象。
        static <T> Function<T, T> identity() {
            return t -> t;
        } 
    }
    
    • 示例代码
     /**
         * 获取一个新的价格
         * @param price
         * @param function
         * @return
         */
        static Double getNewPrice(Float price, Function<Float,Double> function){
            return function.apply(price);
        }
    
        public static void main(String[] args) {
            Double newPrice = getNewPrice(20.36F, (x) -> (double) x + 30);
            System.out.println(newPrice);
            //输出结果为:50.36000061035156
        }
    
    • 总结
      从上面示例可以看出,function 提供的是一个转换型的功能,数据类型转换。
    • andThen 使用
      – 示例代码
     /**
         * 从参数可知,function 第一次已经将float转换成double了,第二次将double转换成float
         * 本示例是告诉用法,不要以为是没事转换来转换去
         * @param price
         * @param function
         * @param function2
         * @return
         */
        static Float getNewPrice(Float price, Function<Float,Double> function,Function<Double,Float> function2){
            return function.andThen(function2).apply(price);
        }
    
        public static void main(String[] args) {
            Float newPrice = getNewPrice(20.36F, (x) -> (double) x + 30,(x)->(float)(x + 20) );
            System.out.println(newPrice);
    
        }
    

    Supplier 函数(供给型)

    • 作用
      获取一个结果
    • 源码
    @FunctionalInterface
    public interface Supplier<T> {
    
        /**
         * Gets a result.
         *
         * @return a result
         */
        T get();
    }
    
    • 示例代码
    public static String getNewStr(Supplier<String> supplier){
            return supplier.get();
        }
    
        public static void main(String[] args) {
            String name = "张三";
            String newStr = getNewStr(()->name+"去吃饭了...");
            System.out.println(newStr);
            //输出结果为:张三去吃饭了...
        }
    
    • 总结
      supplier供给型明显和consumer消费型不相同,虽然输出结果都是一样,使用起来也不一样,supplier是有返回结果的,consumer 是没有返回结果的

    Predicate 断言式 函数(判断型)

    • 作用
    • 源码
    	/**
         * 执行返回结果
         */
        boolean test(T t);
    
        /**
     	 * 多条件同时满足
         */
        default Predicate<T> and(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) && other.test(t);
        }
    
        /**
    	 * 执行结果的反转值
    	 * true变成 false ,false 变成true
         */
        default Predicate<T> negate() {
            return (t) -> !test(t);
        }
    
        /**
         * 两个条件或者
         */
        default Predicate<T> or(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) || other.test(t);
        }
    
        /**
    	 * 是否是同一对象
         */
        static <T> Predicate<T> isEqual(Object targetRef) {
            return (null == targetRef)
                    ? Objects::isNull
                    : object -> targetRef.equals(object);
        }
    
    • 示例代码
    /**
         * 获取断言信息
         * @param value
         * @param predicate
         * @return
         */
        public static Boolean getPredicate(Integer value, Predicate<Integer> predicate){
            return predicate.test(value);
        }
    
        public static void main(String[] args) {
            Integer math = 20 ;
            Boolean predicate = getPredicate(math, (x) -> x >= 30);
            System.out.println(predicate);
        }
    
    • 总结
      用于校验条件是否满足情况。

    Comparator排序

    • 示例代码
        public static void main(String[] args) {
            List<Student> studentList = Arrays.asList(new Student("张三", 7, 90.00),
                    new Student("李四", 6, 80.05),
                    new Student("王五", 3, 100.00));
            //多线程并发情况下能保证线程安全
            Collections.synchronizedList(studentList)
            //按成绩进行倒叙排列
            Collections.sort(studentList,Comparator.comparing(Student::getGrade).reversed());
            //遍历新的集合顺序
            studentList.forEach(student->{
                System.out.println(student.toString());
            });
            //输出结果为:
           		//王五年龄是 :3, 分数是:100.0分
    			//张三年龄是 :7, 分数是:90.0分
    			//李四年龄是 :6, 分数是:80.05分
        }
    
        @Data
        @AllArgsConstructor
        public static class Student{
            private String name;
            private Integer age;
            private Double grade;
    
            @Override
            public String toString() {
                return  name + "年龄是 :" + age + ", 分数是:" + grade + '分';
            }
        }
    

    易于并发编程 parallel()

    比如在一堆数字中寻找最小值

    当这堆数字很大的时候,我们需要去实现多线程去比较的话,需要考虑多线程,线程池以及拆分数据,实现快排等,但是当我们使用JDK8函数式编程的时候可以直接使用一个方法开启 并行 .parallel()

    int min = IntStream.of(nums).parallel().min().getAsInt();
    

    比较下函数式编程和命令式编程

    • 函数式编程
    int min = IntStream.of(nums).parallel().min().getAsInt();
    
    • 命令式编程
    	int minNum = Integer.MAX_VALUE;
        for (int num : nums) {
            if (num < minNum) {
                minNum = num;
            }
        }
    

    通过上述函数式编程优势很明显,不需要处理内部是怎么实现的,只需要得到一个结果就行了。

    Option类

    作用

    Optional 可以省去非空判断,因为内部已经实现了,避免了空指针异常。

    常用方法

    方法描述
    of把指定的值封装为Optional对象,如果指定的值为null,则抛出NullPointerException
    empty创建一个空的Optional对象
    ofNullable把指定的值封装为Optional对象,如果指定的值为null,则创建一个空的Optional对象
    get如果创建的Optional中有值存在,则返回此值,否则抛出NoSuchElementException
    orElse如果创建的Optional中有值存在,则返回此值,否则返回一个默认值
    orElseGet如果创建的Optional中有值存在,则返回此值,否则返回一个由Supplier接口生成的值
    orElseThrow如果创建的Optional中有值存在,则返回此值,否则抛出一个由指定的Supplier接口生成的异常
    filter如果创建的Optional中的值满足filter中的条件,则返回包含该值的Optional对象,否则返回一个空的Optional对象
    map如果创建的Optional中的值存在,对该值执行提供的Function函数调用
    flagMap如果创建的Optional中的值存在,就对该值执行提供的Function函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象
    isPresent如果创建的Optional中的值存在,返回true,否则返回false
    ifPresent如果创建的Optional中的值存在,则执行该方法的调用,否则什么也不做

    默认方法(@FunctionalInterface )

    默认方法的作用

    这个新特性其实是很重要的,它的作用就是在接口上可以定义方法的实现 作为默认方法,这样
    Java就可以扩展很多底层接口 比如List接口 ,对其添加了很多default默认方法,这时候List的接口的实现类也不用去修改了。

    特点

    • 一个类实现多个接口,因此可以采用实现多个接口的方式实现多重继承的目的。
    • 接口中成员的修饰符都是public或者default,不能使用private和protected修饰。
    • 接口可以默认方法与静态方法,有方法体的实现。但abstract修饰的抽象方法没有方法体。
    • 标识接口
      Java语言中,有些接口内部没有声明任何方法,也就是实现这些接口不需要重写任何方法,这些没有任何方法声明的接口叫做标识接口。比如clonable和Serializable接口等,表示实现它的类属于一个特定的类型。

    示例代码

    @FunctionalInterface
    interface Interface1 {
      int doubleNumber(int i);
    
      default void someMethod(){
        System.out.println("Interface1 default Method ");
     }
    }
    

    多重实现的默认方法冲突

    @FunctionalInterface  
    interface Interface1 {
      int doubleNumber(int i);
      void someMethod();
    }
    

    类型注解(ElementType)

    含义:在各种程序元素(定义类、定义接口、定义方法、定义成员变量…)

    ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中。
    ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中(eg:声明语句、泛型和强制转换语句中的类型)。

    重复注解

    含义

    标注在类,方法等上面的注解可以重复出现,之前是不允许

    添加了新的getAnnotationsByType()

    getAnnotationsByType(),可以返回某个类型的重复注解,例如Filterable.class.getAnnoation(Filters.class)将返回两个Filter实例,输出到控制台的内容如下所示:

    filter1
    filter2
    

    LocalDateTime

    类型推断

    其他知识

    JRE 精简

    Permgen删除

    StampedLock

    JavaFx2.0

    其他

    展开全文
  • JDK8 新特性学习.rar

    2020-01-19 16:31:28
    如果你不会JDK1.8的新特性,这部资料绝对物超所值,里面有JDK1.8新特性的入门文档,还有自己整理的性能对比等给同事学习分享笔记,看完学习稍微实践一下,就可以完成入门到上手了,纯干货,5分不贵哈。
  • JDK8十大新特性

    千次阅读 2022-05-16 21:33:18
    JDK十大新特性
  • jdk各个版本的新特性

    2021-12-28 11:41:20
    jdk5-jdk10各个版本的新特性 JDK1.5新特性: 1.自动装箱与拆箱: 2.枚举 3.静态导入,如:import staticjava.lang.System.out 4.可变参数(Varargs) 5.内省(Introspector),主要用于操作JavaBean中的属性,...
  • 视频教程地址:http://www.gulixueyuan.com/course/56
  • JDK新特性.rar

    2012-07-26 11:44:17
    jdk1.5以上版本中新增加的特性描述,带有代码例子让你很清晰的明白jdk的 常量 、枚举、 for each、反射等各种特性,相信需要的你,一定满足。
  • jdk新特性研究精髓

    2012-08-02 15:48:05
    jdk研究,本文档对jdk新特性进行了归纳和总结,都是个人研究的结果,想和大家分享一下。
  • 很重要jdk 1.5 newfeatures jdk新特性 面试必备 我们必须记住。开发必备。学习jdk必备
  • JDK15新特性系列课程

    2021-06-30 20:51:59
     熟练JDK15新特性,适应的java开发需求。 课程简介:  1.Hidden Classes 2.EdDSA 数字签名算法 3.的垃圾回收器ZGC 4.Text Blocks 标准化 5.密封类适合人群:   有一定的java基础,想快速从事java和大数据...
  • JDK新特性

    千次阅读 2017-10-01 10:35:51
    Java/JDK 8 新特性1.8对于1.7做了哪些优化/改进 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,的 JavaScript 引擎,的日期 ...
  • jdk1.8新特性

    2018-03-13 11:30:56
    JDK1.8新特性简介剖析,仅做参考,希望大家相互学习 作为Comparator 和Runnable早期的证明,在JDK中已经定义的接口恰巧作为函数接口而与lambdas表达式兼容。同样方式可以在你自己的代码中定义任何函数接口或第三方...
  • jdk8新特性

    2017-11-22 09:26:00
    jdk8新特性,百度云盘。jdk8新特性,百度云盘。jdk8新特性,百度云盘。
  • JDK5,JDK8新特性.ppt .ppt

    2022-01-03 12:20:05
    参考使用,欢迎下载
  • #JDK8新特性#JDK8新特性

    2022-06-10 11:57:40
    JDK8新特性
  • JDK1.8 的 8 个新特性

    千次阅读 2022-02-22 16:01:39
    jdk1.8 的一些新特性简化了代码的写法,减少了部分开发量。主要如下: Lambda 表达式 接口中的默认方法和静态方法 函数式接口 方法引用和构造器调用 局部变量限制 Stream API 新时间日期API 二、default 关键字 在...
  • jdk1.8版本的新特性

    千次阅读 2021-11-12 20:09:50
    的底层代码时,看见接口中有方法的实现,在查阅资料后发现在jdk1.8版本增加了很多新特性,其中就有接口中发法的实现。废话不多说关于jdk1.8的新特性如下: Lambda表达式:Lambda允许把函数作为一个方法的参数(函数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 277,974
精华内容 111,189
关键字:

jdk新特性