java实现可选形参_Java:可选的可选实现

java实现可选形参

java.util.Optional被实现为单个不可变的具体类,该类在内部处理两种情况。 一个有元素,一个没有元素。 让Optional作为一个接口并让两个不同的实现代替实现该接口不是更好的选择吗? 毕竟,这就是我们通常被教导要使用的一种面向对象的语言。

在本文中,我们将了解当前Optional实现的一些潜在参数。 我们还将学习为什么以不同的方式实现Streams,从而使Streams可以从文件甚至数据库表中获取。

真正的可选实现

真正的java.util.Optional::get实现如下所示:

 public T get() { if (value == null ) { throw new NoSuchElementException( "No value present" ); } return value; } 

可以看出,有两个代码路径。 一种是值是null(没有元素,并且不会引发异常),另一种是值是其他值(返回值)。

可选可选实现

让我们假装我们将回到时光机中,并被要求再次实现Optional 。 我认为我们中的许多人可能会提出一个初始解决方案,就像下面的解决方案(我将其命名为假设接口Option以便我们可以将其与“实际”接口进行区分)具有两个不同的实现(此处为EmptyOptionPresentOption ):

 public interface Option<T> { T get(); boolean isPresent(); public <U> Option<U> map(Function<? super T, ? extends U> mapper); static <T> Option<T> empty() { return (Option<T>) EmptyOption.EMPTY; } (Option<T>) EmptyOption.EMPTY; } <T> Option<T> of(T value) { static <T> Option<T> of(T value) { return new PresentOption<>(value); } PresentOption<>(value); } <T> Option<T> ofNullable(T value) { static <T> Option<T> ofNullable(T value) { return value == null ? empty() : of(value); ? empty() : of(value); }  }  final class EmptyOption<T> implements Option<T> { static final EmptyOption<?> EMPTY = new EmptyOption<>(); private EmptyOption() {} @Override public T get() { throw new NoSuchElementException(); } NoSuchElementException(); } @Override public boolean isPresent() { return false ; } ; } @Override public <U> Option<U> map(Function<? super T, ? extends U> mapper) { requireNonNull(mapper); return (Option<U>) EMPTY; }  }  final class PresentOption<T> implements Option<T> { private final T value; PresentOption(T value) { this .value = requireNonNull(value); } .value = requireNonNull(value); } @Override public T get() { return value; } value; } @Override public boolean isPresent() { return true ; } ; } @Override public <U> Option<U> map(Function<? super T, ? extends U> mapper) { requireNonNull(mapper); return Option.ofNullable(mapper.apply(value)); }  } 

为了简洁起见,仅示出了几种方法,但是原理保持不变:针对存在元素和不存在元素的情况的不同实现。 这给出了更清晰的代码,也使任何人都可以实现可选选项。

分析

我有信心在构思Optional时,JDK团队已对这种解决方案进行了评估,并且我认为不选择该解决方案是明智的决定。 Optional主要目的是“包装”返回值,以防止NPE和返回原始空值的其他缺点。 我还认为设计目标是使用Optional对性能的影响应该很小甚至可以忽略不计。

在下文中,我推测了一些论点,以选择以上所创造的当前的Optional实现。

剖面污染

JIT编译器按需编译Java字节码,以提高解释字节码的性能。

为了有效地做到这一点,JIT编译器能够收集每种已知方法的统计信息。 每个方法都可以具有一个MethodData对象,该对象包含有关如何使用该方法的度量标准,并且一旦JVM认为该方法足够“温暖”(即在某种意义上已被充分调用),便会创建该对象。

创建和维护MethodData过程称为“分析”。

当调用之间使用的方法大不相同时,就会发生“配置文件污染”,包括但不限于提供交替的非null / null元素并调用不同的多态方法(例如,参数是类型T泛型,并且被调用的方法调用T::equals )。 Java的基本功能是其动态调用方法的能力。 因此,当调用Option::get时, EmptyOption::get
最终调用PresentOption::get取决于调用时存在的实现。

一旦该方法被调用了10,000次,JIT编译器就会使用MethodData创建一个有效的已编译代码段,根据迄今为止收集的统计信息,该代码段将以最佳方式执行。

因此,如果元素始终存在(使用PresentOption ),并且牢记这一点编译代码,但随后突然出现EmptyOption ,则代码必须“退出”并采用慢得多的代码路径。

仅在最后一个类中使用Optional ,就不可能再有Optional方法的任何其他实现,因此,不会因不同的实现而造成配置文件污染。 JIT可以确定性地并合理地快速编译代码。

但是,等等,JVM不可能在启动时检查所有类并确定实际上只有两个实现类。
Option ,然后它可以解决整个问题? 好吧,不。 我们可以随时随意添加类,因此无法安全地枚举特定接口的所有可能实现。 至少要等到我们有了Java中真正的密封类时,才能进行。

原料药污染

如果人们可以自由编写Optional自定义实现,那么与内置Optional相比,这些实现很可能会遭受设计缺陷/偏差。 同样,人们可能会让他们自己的类型实现Optional接口,这增加了JIT编译器/分析器的负担,因此将诱使人们使用非预期的复合类型(例如Foo implements Bar, Optional<Bazz>)

另外, Optional现在是Java不可或缺的一部分,因此,可以使它与JDK本身一起有效发展,包括内联类和其他即将推出的Java新功能。

可选与流

Optional相反, java.util.stream.Stream和专用版本(例如IntStream )确实是接口。 为什么Stream不像Optional那样具体地进行最后的上课?

好吧,Streams有一套完全不同的要求。 可以从Collection或数组中获取Stream但是有很多更强大的获取Stream 。 可以从文件,套接字,随机生成器甚至从数据库表中获取Stream 。 如果Stream被密封,将无法实现这些功能。

Speedment Stream是一个库的示例,该库允许从几乎任何数据库中获取标准Java流。 在此处阅读有关Speedment Stream的更多信息。

结论

Optional密封,有充分的理由。 Optional的内部实现不太清楚,但这是值得付出的代价,它具有更好的性能和更清晰的用户代码。

流是非密封接口,任何人都可以实现,并且可用于从各种来源(包括文件和数据库表)获取元素。 Speedment Stream ORM可用于从数据库表获取Streams。

在此处下载Speedment Stream。

翻译自: https://www.javacodegeeks.com/2019/08/java-optional-implementation-optional.html

java实现可选形参

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

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

相关文章

MySQL数据库的JSON数据类型详解

文章目录JSON 数据类型意义存储JSON串修改JSON串中指定字段的值查询 JSON 串中的数据查询 JSON 串中指定字段的值特殊语法精确查询嵌套精确查询模糊查询优化 JSON 查询处理 JSON 数据的常用函数JSON_CONTAINS_PATHJSON_PRETTY总结参考资料JSON 数据类型意义 其实&#xff0c;没…

高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)

【0】写在前面 0.1&#xff09;本代码旨在演示 从 ring0 转移到 ring3&#xff08;即&#xff0c;从高特权级 转移到 低特权级&#xff09;0.2&#xff09;本文 只对 与 门相关的 代码进行简要注释&#xff0c;言简意赅&#xff1b;0.3&#xff09;文末的个人总结是干货&#…

aws 删除ec2实例_如何在AWS中启动EC2实例

aws 删除ec2实例你好朋友&#xff0c; 在本教程中&#xff0c;我们将看到如何立即在AWS中旋转EC2实例。 您应该有权访问AWS控制台。如果您还没有AWS账户&#xff0c;则可以单击此处并在AWS上创建免费套餐。 如何在AWS中启动EC2实例 第1步 &#xff1a; 使用您的凭证登录到您…

python足球射门小游戏_足球射门游戏教案

足球射门游戏教案【篇一&#xff1a;足球射门游戏教案】足球游戏教案任课教师&#xff1a;张旭授课班级&#xff1a;初二(1)班第1次课上课时间&#xff1a;2008-12-1人数&#xff1a;50男(30)女(20)指导教师&#xff1a;彭老师1.运球接力1.足球运球类游戏{ 2.传球射门3.足球打靶…

jQuery 1.9版本之后函数toggle()的轮流执行事件监听器功能被舍弃掉了

文章目录实现隐藏与显示相互切换的效果可以恢复函数 toggle 轮流执行事件监听器的功能toggle()方法主要有两个功能&#xff0c;一是用于绑定两个或多个事件处理器函数&#xff0c;在元素被点击时轮流执行&#xff1b;二是切换元素的显隐状态&#xff0c;如果元素是可见的&#…

不同特权级间代码段的跳转{ 门 + 跳转(jmp + call) + 返回(ret) }

【0】写在前面 0.1&#xff09;我们讲 CPU的保护机制&#xff0c;它是可靠的多任务运行环境所必须的&#xff1b;0.2&#xff09; CPU保护机制&#xff1a;分为段级保护 页级保护&#xff1b; 0.2.1&#xff09;段级保护分为&#xff1a;段限长 limit 检查、段类型 type 检查…

精打细算油盐_Java:ChronicleMap第1部分,精打细算

精打细算油盐用数百万个对象填充HashMap会很快导致诸如内存使用效率低下&#xff0c;性能低下和垃圾回收等问题。 了解如何使用堆外CronicleMap &#xff0c;其中可以包含数十亿个对象&#xff0c;而对堆的影响很小或没有。 当我们要使用中小型数据集时&#xff0c;内置的Map实…

日志服务器搭建及配置_[ELK入门到实践笔记] 一、通过rsyslog搭建集中日志服务器...

ELK 是elastic公司提供的一套完整的日志收集以及展示的解决方案&#xff0c;这是我在ELK学习和实践过程写下的笔记&#xff0c;整理成了一个ELK入门到实践的系列文章&#xff0c;分享出来与大家共勉。本文为该系列文章的第一篇&#xff0c;通过rsyslog搭建集中日志服务器&#…

JavaScript(JS)调用事件监听器(事件处理函数/事件处理程序/事件监听函数)时如何传递参数

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>事件的演示代码</title></head> <body> <input id"bt" type"button" value"test"> <scrip…

x86 的 TSS 任务切换机制

转自&#xff1a;http://blog.chinaunix.net/uid-587665-id-2732907.html 【0】写在前面segment descriptors 构建保护模式下的最基本、最根本的执行环境。system descriptors 则构建保护模式下的核心组件&#xff1a;&#xff11;、TSS descriptor 提供硬件级的进程切换机制&a…

spring安全性_具有PreAuthorize的Spring方法安全性

spring安全性朋友不允许朋友写用户身份验证。 厌倦了管理自己的用户&#xff1f; 立即尝试Okta的API和Java SDK。 数分钟之内即可在任何应用程序中对用户进行身份验证&#xff0c;管理和保护。 本教程将探讨使用Spring Security在Spring Boot中配置身份验证和授权的两种方法。…

animiz动画制作软件_AN动画制作软件

AN基础介绍我们先了解一些基本概念&#xff0c;才能帮助我们更好的进行下面一系列的操作。1.图层。图层就像是含有文字或图形等元素的胶片&#xff0c;一张张按顺序叠放在一起&#xff0c;组合起来形成页面的最终效果。图层可以将页面上的元素精确定位。图层中可以加入文本、图…

关于一致/非一致代码段与TSS 关系的个人看法

【0】概念定义 0.1&#xff09;一致代码段: 简单理解&#xff0c;就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接调用访问的代码&#xff0c; 但是特权级高的程序不允许访问特权级低的数据. 通常这些共享代码&#xff0c;是”不访问”受保护的资源和某些类型异…

python预处理标准化_tensorflow预处理:数据标准化的几种方法

tensorflow预处理&#xff1a;数据标准化的几种方法发布时间&#xff1a;2018-08-09 19:39,浏览次数&#xff1a;1774, 标签&#xff1a;tensorflow数据归一化问题是数据挖掘中特征向量表达时的重要问题&#xff0c;当不同的特征成列在一起的时候&#xff0c;由于特征本身表达方…

三思笔记_使用反射前先三思

三思笔记介绍 有时&#xff0c;作为开发人员&#xff0c;您可能会遇到无法使用new运算符实例化对象的情况&#xff0c;因为其类名称存储在配置XML中的某个位置&#xff0c;或者您需要调用一个名称指定为注释属性的方法。 在这种情况下&#xff0c;您总会有一个答案&#xff1a;…

分页机制总结

【0】写在前面&#xff08;分页机制&#xff09; 0.0&#xff09; source code from orange’s implemention of a os and text description from Zhaojiong’s perfect analysis of Linux kernel and for complete code ,please visit https://github.com/pacosonTang/Orange…

python程序填空题参照代码模板、完善代码_python二级考试操作题11.pdf

综合应用题参照代码模板完善代码&#xff0c;实现下述功能。文件ngchina.html 保持了网页源代码&#xff0c;请将该页面中图片的URL 提取出来,并输出所有图像的URL。习题讲解#P301#读取HTML 文件内容def getHTMLlines(htmlpath):f open(htmlpath,"r",encoding utf-…

Struts2学习笔记

文章目录Struts2 的核心开发包Struts2 配置文件Struts2 域对象Struts2 编程流程Action 组件使用通配符配置 ActionAction 中如何访问 Session通过 ActionContext 对象访问 Session 对象&#xff08;不推荐&#xff09;通过实现 SessionAware 接口访问 sessionAction 如何访问 r…

如何从文件系统中读取文件内容

【0】写在前面 0.0&#xff09; text description from orange’s implemention of a os &#xff0c;文末总结系个人臆测出的干货 【1】intro to FAT12&#xff08;file allocation table 12&#xff09;文件系统格式&#xff08;from Baidu Baike&#xff09; &#xff08;…

java微服务,微在哪_Java:ChronicleMap第3部分,快速微服务

java微服务,微在哪标准Java Maps需要在启动时进行初始化。 了解如何利用可从文件初始化的ChronicleMaps并显着减少微服务启动时间&#xff0c;以及如何在JVM之间共享Maps。 内置的Map实现&#xff08;例如HashMap和ConcurrentHashMap速度很快&#xff0c;但是必须先使用映射进…