Java中的三态布尔值

我不时地想念Java中SQL的三值BOOLEAN语义。 在SQL中,我们有:

  • TRUE
  • FALSE
  • UNKNOWN (也称为NULL

时不时地,我希望自己也能用Java表达这种UNKNOWNUNINITIALISED语义,而普通的truefalse还不够。

实现一个ResultSetIterator

例如,当为jOOλ实现ResultSetIterator时,一个为Java 8建模SQL流的简单库:

SQL.stream(stmt, Unchecked.function(r ->new SQLGoodies.Schema(r.getString("FIELD_1"),r.getBoolean("FIELD_2"))
))
.forEach(System.out::println);

为了实现Java 8 Stream ,我们需要构造一个Iterator ,然后可以将其传递给新的Spliterators.spliteratorUnknownSize()方法:

StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false
);

在Stack Overflow上可以看到另一个示例 。

在实现Iterator接口时,我们必须实现hasNext()next() 。 请注意,在Java 8中, remove()现在具有默认实现,因此我们不再需要实现它。

虽然在大多数情况下,对next()的调用之前仅是对hasNext()的调用,但是Iterator协定中对此没有要求。 完全可以这样写:

if (it.hasNext()) {// Some stuff// Double-check again to be sureif (it.hasNext() && it.hasNext()) {// Yes, we're paranoidif (it.hasNext())it.next();}
}

如何将Iterator调用转换为JDBC ResultSet上的支持调用? 我们需要调用ResultSet.next()

我们可以进行以下翻译:

  • Iterator.hasNext() == !ResultSet.isLast()
  • Iterator.next() == ResultSet.next()

但是那个翻译是:

  • 昂贵
  • 没有正确处理空的ResultSet
  • 并非在所有JDBC驱动程序中都实现(对于结果集类型为TYPE_FORWARD_ONLY的ResultSet,对isLast方法的支持是可选的)

因此,我们必须在内部维护一个标志,该标志告诉我们:

  • 如果我们已经调用了ResultSet.next()
  • 那个电话的结果是什么

除了创建第二个变量之外,为什么不使用三值的java.lang.Boolean 。 这是jOOλ的可能实现 :

class ResultSetIterator<T> implements Iterator<T> {final Supplier<? extends ResultSet>  supplier;final Function<ResultSet, T>         rowFunction;final Consumer<? super SQLException> translator;/*** Whether the underlying {@link ResultSet} has* a next row. This boolean has three states:* <ul>* <li>null:  it's not known whether there *            is a next row</li>* <li>true:  there is a next row, and it*            has been pre-fetched</li>* <li>false: there aren't any next rows</li>* </ul>*/Boolean hasNext;ResultSet rs;ResultSetIterator(Supplier<? extends ResultSet> supplier, Function<ResultSet, T> rowFunction, Consumer<? super SQLException> translator) {this.supplier = supplier;this.rowFunction = rowFunction;this.translator = translator;}private ResultSet rs() {return (rs == null) ? (rs = supplier.get()) :  rs;}@Overridepublic boolean hasNext() {try {if (hasNext == null) {hasNext = rs().next();}return hasNext;}catch (SQLException e) {translator.accept(e);throw new IllegalStateException(e);}}@Overridepublic T next() {try {if (hasNext == null) {rs().next();}return rowFunction.apply(rs());}catch (SQLException e) {translator.accept(e);throw new IllegalStateException(e);}finally {hasNext = null;}}
}

如您所见, hasNext()方法仅在其之前为null时才本地缓存hasNext三值布尔状态。 这意味着多次调用hasNext() 直到调用next() ,这将重置hasNext缓存状态。

如果需要, hasNext()next()前进ResultSet游标。

可读性?

你们中有些人可能会认为这不利于可读性。 他们将引入一个新变量,例如:

boolean hasNext;
boolean hasHasNextBeenCalled;

麻烦的是,您仍在实现三值布尔状态,但分配给两个变量,很难以一种比实际java.lang.Boolean解决方案更易读的方式来命名它们。 此外,两个boolean变量实际上有四个状态值,因此,发生错误的风险会略有增加。

每个规则都有其例外。 自从引入Option / Optional以来一直存在的null -is-bad历史准则,将null用于上述语义是一个很好的例外。

换句话说:哪种方法最好? 没有TRUEFALSE答案,只有UNKNOWN

小心一点

但是,正如我们在上一篇博客文章中所讨论的那样 ,如果可能的话,应该避免从API方法返回null 。 在这种情况下,显式使用null作为建模状态的一种方法很好,因为此模型封装在我们的ResultSetIterator 。 但是,请避免将此类状态泄漏到API外部。

翻译自: https://www.javacodegeeks.com/2014/05/three-state-booleans-in-java.html

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

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

相关文章

阻塞分析

--阻塞 /*********************************************************************************************************************** 阻塞&#xff1a;其中一个事务阻塞&#xff0c;其它事务等待对方释放它们的锁,同时会导致死锁问题。 整理人&#xff1a;中国风(R…

科学计算机二进制算法,计算机是怎么理解二进制的?

计算机是怎么理解二进制的?计算机的发明最初纯粹是为了计算数字, 让一个机器能够通过输入不同的数字, 进行加减乘除等. 首先要约定好机器能处理的数是什么样的, 即输入是什么样的, 才能去制造计算机. 二进制只是一种尝试, 十进制也有科学家尝试过, 但由于复杂程度较二进制要高…

OpenCV人脸特效制作

https://blog.csdn.net/zxc024000/article/details/50456917 https://blog.csdn.net/huanghuangjin/article/details/81666134 DLibOpenCV 脸部跟踪张贴小物件(遮盖眼部或者眼睛变大) 所以首先需要人脸识别&#xff0c;然后再类似GAN之类的进行处理或生成 https://wysaid.org/9…

abp.event.on与abp.event.off使用

apb的全局事件 var eventName "app.createOrEditFieldModalSaved";var reloadPage function () { dt.ajax.reload();};abp.event.on(eventName, reloadPage); //弹窗关闭事件_modalManager.onClose(function () {//注销事件&#xff0c;要不然多次打开列表后&…

为JavaOne 2014做好准备!

保持那个想法&#xff01; 是的……我希望我能在Java One 2014上做演讲-但我现在只值得在梦里做到这一点&#xff01; 但是&#xff0c;没有什么阻止我遵循Java One并跟踪有关我最喜欢的主题的会话/对话。 我希望甲骨文能够像我们2013年版那样&#xff0c;像我们这样的凡人在网…

WPF 实现ScrollViewer的垂直偏移滚动跳转

问题&#xff1a;考虑屏幕大小&#xff0c;一般都是会在表单问卷的页面使用ScrollViewer。问卷中问题漏填漏选时&#xff0c;在提交时校验不过&#xff0c;需要滚动跳转至漏填漏选项。 页面如下&#xff1a; 每个选项使用StackPanel&#xff0c;并对复选框和单选的勾选事件进行…

13 个应该记住的最不寻常的搜索引擎

13 个应该记住的最不寻常的搜索引擎 如果你通过Digg或其他社会化媒体网站&#xff0c;向世界传播&#xff0c;我会非常感激&#xff0c;您对此文的随手评论会让此文展示在更多人面前。谢谢 你已经天天使用一些常见的搜索引擎&#xff0c;象 Google&#xff0c;Msn&#xff0c;Y…

限制 计算机中 某用户上网 win7,Win7旗舰版怎么限制孩子的上网时间?电脑限制孩子上网时间的方法...

Win7旗舰版怎么限制孩子的上网时间&#xff1f;我们在家里有孩子的时候非常害怕孩子沉迷与网络&#xff0c;不把心思放在学习上。所以会想方设法的限制孩子上网。那么我们怎么使用电脑的自带的功能限制孩子上网呢&#xff1f;下面小编就带着大家一起看一下吧&#xff01;设置管…

第八章(三)基于Listcheck适配器的访问控

denier适配器访问控制比较死板。Listchecker的适配器更加灵活。 定义handler: apiVersion: config.istio.io/v1alpha2 kind: listchecker metadata:name: chaos spec:overrides: ["v1","v3"] # 列表blacklist: true # 黑名单类型 定义t…

checkbox 最多选两项

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <title>久信臻氏</title></head><body><form action"index.php" method"post"> <div> &…

论图计算

自从机械计算开始以来&#xff0c;图形概念就已经存在&#xff0c;并且在纯数学领域已经存在了数十年。 由于数据库的黄金时代&#xff0c;图形在软件工程中变得越来越流行。 图形数据库提供了一种持久化和处理图形数据的方法。 但是&#xff0c;图形数据库并不是存储和分析图形…

注册了

第一天来 转载于:https://www.cnblogs.com/mayanshuang/archive/2008/07/26/1251934.html

html 拼接onmouseout,HTML onmouseout事件用法及代码示例

将鼠标指针移出元素或其子元素时&#xff0c;将发生HTML DOM onmouseout事件。用法:在HTML中&#xff1a;在JavaScript中&#xff1a;object.onmouseout function(){myScript};在JavaScript中&#xff0c;使用addEventListener()方法&#xff1a;object.addEventListener(&quo…

Windows PowerShell Cookbook

Windows PowerShell Cookbook转载于:https://www.cnblogs.com/gavinhughhu/archive/2009/12/29/1634652.html

7 selenium 模块

selenium 模块 一.简介 1.Python的一个第三方库&#xff0c;对外提供的接口可以操作浏览器&#xff0c;然后让浏览器完成自动化的操作。 2.自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器&#xff0c;完全…

vue-resource

安装npm install vue-resource引入import VueResource from vue-resource;Vue.use(VueResource);使用get方法this.$http.get("http://localhost/test.php").then( function (res) { // 处理成功的结果 console.log(res.body); },function (res) { // 处理失败的结果 …

针对新手的Java EE7和Maven项目-第3部分-定义ejb服务和jpa实体模块

从前面的部分恢复 第1部分 第2部分 我们在第三部分继续介绍&#xff0c;我们已经有一个父pom&#xff0c;并且已经为我们的war模块定义了pom。 在我们的原始设置中&#xff0c;我们定义了我们的应用程序将包含一个ejb jar形式的服务jar。 这是我们的Enterprise Java Bean&…

计算机本地网络如何共享,本地网络共享怎么实现

本地网络共享可以满足多台电脑同时联网&#xff0c;台式电脑实现网络共享可以使用路由器&#xff0c;笔记本电脑事项网络共享需要使用无线路由器或者无线网卡。那么本地网络共享又是如何实现的呢&#xff0c;下面为大家详细介绍一下。通过路由器实现本地网络共享&#xff1a;第…

淘宝购物车效果

淘宝购物车效果 今天给大家带来的是淘宝购物车效果&#xff0c;写的不怎么好&#xff0c;请大家多多指教。 效果&#xff1a; 1.点击全选前的选择框&#xff0c;选择所有的选择框。 2.点击商品的加号或者减号可以改变商品的数量值&#xff0c;并且改变商品的小计和他的积分&…

Git初始化配置以及配置github

1&#xff0c;配置用户名和邮箱&#xff08;这里是我github中配置的用户名和邮箱&#xff09;&#xff0c;执行下面命令后&#xff0c;在C:\Users\yaosq盘下会出现一个全局文件.gitconfig. git config --global user.name "这里换上你的用户名" git config --global…