Java8的新特性

1.Lambda表达式和函数式接口

Lambda的基础:函数式接口

Java 8与之前版本的区别:

  • Java 7及之前:接口中只能包含抽象方法,无法通过函数式接口简洁地表示Lambda表达式。
  • Java 8:通过@FunctionalInterface注解,明确表示接口为函数式接口,允许传递Lambda表达式作为参数。

函数式接口是只有一个抽象方法的接口。 这里的重点是"只有一个"和"抽象方法"。

  • 只有一个: 这意味着接口中不能有多个抽象方法。如果一个接口有多个抽象方法,那么Lambda表达式就无法确定它应该实现哪个方法了。
  • 抽象方法: 这意味着这个方法没有具体的实现(没有方法体)。接口中的默认方法(default methods)和静态方法(static methods)不属于抽象方法,它们都有具体的实现。

Java 8引入了一个特殊的注解:@FunctionalInterface。这个注解用于标记一个接口是函数式接口。虽然这个注解不是必需的(即使没有这个注解,只要接口满足函数式接口的定义,它仍然是函数式接口),但建议使用它。因为@FunctionalInterface注解有两个好处:

  • 明确性: 它可以清楚地表明这个接口是一个函数式接口,方便其他开发者理解。
  • 编译时检查:如果你在一个标记了@FunctionalInterface的接口中添加了多个抽象方法,编译器会报错,帮助你避免错误。

Lambda表达式

Java 8与之前版本的区别:

  • Java 7及之前:行为的传递通常依赖于匿名类,代码较为冗长。
  • Java 8:Lambda表达式简化了代码结构,避免了匿名类的冗余代码。

Lambda表达式提供了一种更加简洁,更加优雅的方式表示可传递的代码块

Lambda表达式本质上就是一个匿名函数。 它可以像普通函数一样接受参数、执行代码,并返回值。但与普通函数不同的是,Lambda表达式没有名称

Lambda表达式的语法

( parameter-list ) -> { expression-or-statements }

一个Lambda表达式由以下几个部分组成:

参数列表:() 中的parameter-list是以逗号分隔的参数。Java 11 后,还可以使用 var 关键字作为参数类型,有点 JavaScript 的味道 。Lambda表达式可以有零个或多个参数。参数的类型可以显式声明,也可以由编译器根据上下文推断。
箭头符号(->): 箭头符号将参数列表与Lambda表达式的主体分隔开。
函数体: {} 中的 expression-or-statements 为 Lambda 的主体。函数体包含Lambda表达式要执行的代码。它可以是一个表达式,也可以是一个代码块。

  • 如果函数体是一个表达式,Lambda表达式会隐式地返回这个表达式的值。
  • 如果函数体是一个代码块,则需要使用return语句来返回值(或者没有返回值,就像void方法一样)。

Lambda表达式与函数式接口的关系:Lambda表达式可以用在任何需要函数式接口的地方。因为Lambda表达式本质上就是函数式接口的一个实例。当你写下一个Lambda表达式时,你实际上是在创建一个实现了函数式接口的匿名对象。Lambda表达式的类型就是它所实现的函数式接口的类型。

2.Steam API

在Java中,Steam流是一种强大的数据处理工具,它允许我们对集合进行各种操作,如筛选、过滤、映射、分组等。这些操作可能是中间操作,返回一个Steam流,也可能是终端操作,返回一个结果。

Java 8与之前版本的区别:

  • Java 7及之前:集合操作通常是通过循环遍历来实现,代码繁琐,缺乏可读性。
  • Java 8:通过Stream API提供了更加简洁、功能强大的数据操作方法,可以通过链式调用实现复杂的操作。(filter方法)

Steam流的优势

Steam流的操作不会影响原始集合,也不会存储数据。这意味着我们可以在不改变原始数据的情况下对数据进行处理。在传统的集合操作中,我们通常需要将数据复制到另一个集合中,这可能会导致额外的内存开销。而Steam流则将集合中的元素逐个复制到一个流动的容器中进行操作,操作结束后,容器消失,不会产生额外的内存占用。
Steam流支持同步和并发执行。如果我们直接获取Steam流,得到的是同步执行的Steam流。如果我们调用parallelStream()方法,则得到一个可以并发执行的Steam流。这使得我们可以充分利用多核处理器的性能,加快数据处理速度。

3.默认方法

Java 8允许在接口中定义默认方法,避免了接口修改时需要修改所有实现类的问题。默认方法具有默认实现,可以由接口实现类继承或重写。通过使用default关键字,可以在接口中定义具有默认实现非抽象的方法(扩展方法),而不破坏实现了该接口的类的代码。允许在已有的接口中添加新方法,而同时又保持了与旧版本代码的兼容性。类似于继承父类,重写父类的方法

Java 8与之前版本的区别:

  • Java 7及之前:接口无法包含实现,若需要添加新方法,必须修改实现类。
  • Java 8:接口可以包含默认实现的方法,接口的变更不会影响已有的实现类。

4.方法引用

方法引用是Lambda表达式的一种更加简洁的形式,可以直接引用已有的Java类或对象(实例)的方法或构造器。

第一种方法引用是构造器引用,它的语法是Class::new,或者更一般的Class< T >::new。请注意构造器没有参数。   

final Car car = Car.create( Car::new );final List< Car > cars = Arrays.asList( car ); 

第二种方法引用是静态方法引用,它的语法是Class::static_method。请注意这个方法接受一个Car类型的参数

  cars.forEach( Car::collide );

第三种方法引用是特定类的任意对象的方法引用,它的语法是Class::method。请注意,这个方法没有参数。

cars.forEach( Car::repair );

第四种方法引用是特定对象的方法引用,它的语法是instance::method。请注意,这个方法接受一个Car类型的参数 

final Car police = Car.create( Car::new );cars.forEach( police::follow );

5.重复注解

自从Java5引入了注解机制,这一特性就变得非常流行并且广为使用。然而,使用注解的一个限制是相同的注解在同一位置只能声明一次,不能声明多次。Java8打破了这条规则,引入了重复注解机制,这样相同的注解可以在同一地方声明多次。

重复注解机制本身必须用@Repeatable注解。事实上,这并不是语言层面上的改变,更多的是编译器的技巧,底层的原理保持不变。

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// 定义重复注解类型
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(Authors.class)
@interface Author {String name();
}// 定义容器注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Authors {Author[] value();
}// 使用重复注解
@Author(name = "John")
@Author(name = "Jane")
class Book {// 类的内容
}

@Repeatable 注解是 Java 8 引入的,它的作用是指定存储重复注解的容器注解。在上述代码中,@Author 注解被标记为可重复的,其容器注解是 @Authors。
@Retention(RetentionPolicy.RUNTIME) 表示注解在运行时可见,这样可以通过反射机制获取注解信息。
@Target(ElementType.TYPE) 表示注解可以应用于类、接口、枚举等类型上。

重复注解的实现

1.需要定义一个正常的注解类型,该注解将被重复使用。同时,还需要定义一个容器注解,容器注解用于存储重复注解的数组。

2.在需要的地方多次使用定义好的重复注解。

3.使用反射机制可以获取类上的重复注解信息。getAnnotationsByType 方法是 Java 8 为了方便获取重复注解而引入的,它可以直接返回指定类型的所有重复注解数组。

import java.lang.reflect.AnnotatedElement;public class Main {public static void main(String[] args) {// 获取 Book 类的 Class 对象Class<Book> bookClass = Book.class;// 获取类上的所有 @Author 注解Author[] authors = bookClass.getAnnotationsByType(Author.class);// 遍历注解数组并输出信息for (Author author : authors) {System.out.println("Author: " + author.name());}}
}

6.Optional类

Optional类主要是针对空指针异常的问题,Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

Optional optional = Optional.ofNullable(null);
System.out.println(optional.isPresent());
System.out.println(optional.orElse(0));//当值为空时给与初始值
System.out.println(optional.orElseGet(() -> new String[]{"a"}));

如果Optional类的实例为非空值的话,isPresent0返回true,否从返回false。

为了防止Optional为空值,orElseGet0方法通过回调函数来产生一个默认值。map()函数对当前Optional的值进行转化,然后返回一个新的Optional实例。orElse0方法和orElseGet0方法类似,但是orElse接受一个默认值而不是一个回调函数。

7.Date/Time API

在旧版的 Java 中,日期时间 API 存在诸多问题,比如:

        1.非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。

        2.设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。

        3.时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。在设计新版API时,十分注重与旧版API的兼容性:不允许有任何的改变(从java.util.Calendar中得到的深刻教训l)。

让我们用例子来看一下新版API主要类的使用方法。

  • Clock类:通过指定一个时区,然后就可以获取到当前的时刻,日期与时间。Clock可以替换System.currentTimeMillis0与TimeZone.getDefault0。
  • LocaleDate类:只持有ISO-8601格式且无时区信息的日期部分。
  • LocaleTime类:只持有ISO-8601格式且无时区信息的时间部分。
  • Duration类:在秒与纳秒级别上的一段时间。Duration使计算两个日期间的不同变的十分简单。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33557.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库管理-第302期 国产类RAC架构数据库网络连接方式(20250314)

数据库管理302期 2025-03-14 数据库管理-第302期 国产类RAC架构数据库网络连接方式&#xff08;20250314&#xff09;1 Oracle RAC2 DMDSC3 YAC4 KES RAC总结 数据库管理-第302期 国产类RAC架构数据库网络连接方式&#xff08;20250314&#xff09; 作者&#xff1a;胖头鱼的鱼…

Spring框架详解(IOC容器-上)

IOC&#xff08; Inversion of Control&#xff0c;控制反转&#xff09;和DI&#xff08;dependency injection&#xff09;是Spring框架的核心特性&#xff0c;也是Spring框架的基础。 Spring框架作为一个IOC容器&#xff0c;负责加载、创建和管理Spring Bean。 接下来介绍…

架构学习第八周--Kubernetes博客搭建

目录 一、整体架构 二、部署MySQL主从 三、部署Redis哨兵 四、部署WordPress 五、注意事项 一、整体架构 本项目为在一主三从的Kubernetes集群上部署WordPress博客。因为WordPress部分容器版本自行集成Apache和PHP服务&#xff0c;因此在Kubernetes上部署WordPress只需提供…

【品铂科技】在高精度定位行业内的口碑怎么样?

1. ‌技术实力与行业认可‌ 公司自主研发的ABELL无线实时定位系统在复杂环境中&#xff08;如工业、司法监狱等&#xff09;展现出厘米级&#xff08;5-10厘米&#xff09;高精度定位能力&#xff0c;客户反馈系统稳定性强、抗干扰能力突出&#xff0c;成为行业技术标杆‌。参…

长度最小的子数组-滑动窗口解法

本来觉得自己双指针学的还可以了&#xff0c;于是今天直接刷了一道滑动窗口题&#xff0c;没想到还是被坑绊倒了两次。这次我想记录在博客里&#xff0c;不仅可以防止我以后重蹈覆辙&#xff0c;兴许也还可以帮助到其他人。 题目来自力扣&#xff1a;209. 长度最小的子数组 - …

深入理解Linux网络随笔(七):容器网络虚拟化--Veth设备对

深入理解Linux网络随笔&#xff08;七&#xff09;&#xff1a;容器网络虚拟化 微服务架构中服务被拆分成多个独立的容器&#xff0c;docker网络虚拟化的核心技术为&#xff1a;Veth设备对、Network Namespace、Bridg。 Veth设备对 veth设备是一种 成对 出现的虚拟网络接口&…

深入理解 Maven BOM 及其继承特性

深入理解 Maven BOM 及其继承特性 一、什么是 Maven BOM&#xff1f; Maven BOM&#xff08;Bill Of Materials&#xff0c;物料清单&#xff09;是一种特殊的 Maven 项目&#xff0c;用于集中管理依赖项的版本信息。BOM 项目本身并不包含实际的代码或资源&#xff0c;而仅仅…

C语言(25)

一.数据在内存中的存储 1.整数在内存中的存储 整数在内存中以二进制的形式储存&#xff0c;分别为原码&#xff0c;补码&#xff0c;反码 有符号的整数&#xff0c;在上述三种形式都有符号位和数值位两个部分&#xff0c;符号位为0是正数&#xff0c;1是负数&#xff0c;最高…

一篇博客搞定时间复杂度

时间复杂度 1、什么是时间复杂度&#xff1f;2、推导大O的规则3、时间复杂度的计算3.1 基础题 13.2 基础题 23.3基础题 33.4进阶题 13.5进阶题 23.6 偏难题 13.7偏难题 2&#xff08;递归&#xff09; 前言&#xff1a; 算法在编写成可执行程序后&#xff0c;运行时要耗费时间和…

探索 Trossen AI:从 Aloha到智能机器人平台的进化之路

在人工智能与机器人技术快速发展的当下&#xff0c;科研硬件的性能与成本成为影响行业创新的重要因素。Trossen Robotic为在机器人领域二十余年的知名企业&#xff0c;近日推出的 Trossen AI 系列产品&#xff0c;为科研机构与开发者提供了高性能、高性价比的解决方案。 Trosse…

【Power Platform系列】如何在画布应用中调用工作流上传附件

在Power Apps画布应用中上传附件&#xff0c;比如到SharePoint文档库最典型的方式非常简单&#xff0c;插入一个编辑窗体&#xff0c;将窗体和背后的文档库绑定起来即可以快速实现。不过窗体内部的显示格式很难控制&#xff0c;如果要实现更为灵活的控制&#xff0c;就需要采用…

工作记录 2017-01-12

序号 工作 相关人员 1 协助BPO进行Billing的工作。 处理Amazing Charts的数据查询。 修改BillingJobPoster&#xff0c;处理CCDA 的自动导入&#xff0c;预计还需一天才能完成。 修改录入Code的界面&#xff08;code 移动到指定位置&#xff09;&#xff0c;预计明天更新。…

在centOS Linux系统搭建自动化构建工具Jenkins

前言 在工作中发现公司使用Jenkins实现自动化部署项目方案&#xff0c;于是闲着自己也捣鼓一下&#xff0c;网上查阅相关部署资料&#xff0c;顺便记录操作步骤&#xff0c;所以有了下面这篇的文章。 部署完之后&#xff0c;安装前端项目所需环境&#xff0c;比如node环境&am…

开箱即用的whisper-service服务

安装须知 Whisper官方网址 https://github.com/openai/whisper Whisper 镜像站 https://docker.aityp.com/r/docker.io/onerahmet 本次提供的环境镜像为&#xff1a;docker.io/onerahmet/openai-whisper-asr-webservice:v1.6.0-gpu 运行环境要求 服务器架构 服务器架构要…

SpringCloud带你走进微服务的世界

认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个…

【xv6操作系统】页表与写时拷贝解析及相关实验设计

【xv6操作系统】页表与写时拷贝解析及相关实验设计 页表页表概念xv6页表xv6 TLB实验1&#xff1a;加速系统调用实验2&#xff1a;打印三级页表实验3&#xff1a;检测已访问的页表 写时拷贝写时拷贝实验实现 页表 页表概念 deepseek说&#xff1a; 页表&#xff08;Page Table…

如何处理PHP中的编码问题

如何处理PHP中的编码问题 在PHP开发过程中&#xff0c;编码问题是一个常见且棘手的问题。无论是处理用户输入、数据库交互&#xff0c;还是与外部API通信&#xff0c;编码问题都可能导致数据乱码、解析错误甚至安全漏洞。本文将深入探讨PHP中的编码问题&#xff0c;并提供一些…

人工智能之数学基础:线性变换的象空间和零空间

本文重点 前面的课程中,我们学习了线性变换,由此而引申出线性变换的象空间和零空间,这两个空间在机器学习领域会被经常用到,本文对此进行学习。 直观理解 总的来说象空间就是经过线性变换得到的空间,零空间就是经过线性变换是零的元素构成的空间。 从几何角度来看,象空…

方案精读:IBM方法论-IT规划方法论

该文档聚焦 IT 规划方法论&#xff0c;适合企业高层管理者、IT 部门负责人、业务部门主管以及参与企业信息化建设的相关人员阅读。 &#xff08;本解读资料已包含在绑定资源内&#xff09; 主要内容围绕 IT 规划展开&#xff1a;首先明确 IT 规划需基于企业核心战略&#xff0…

日志监控工具openobserve使用案例

引言 分享一个日志监控工具&#xff0c;openobserve&#xff08;简称 o2&#xff09;&#xff0c;它是一个云原生可观察性平台&#xff0c;专为日志、指标、跟踪、分析 而构建&#xff0c;旨在以 PB 级规模运行。与 Elasticsearch 不同&#xff0c;OpenObserve 不需要了解和调整…