Java 9对可选的补充

哇,人们对Java 9的Stream API增添了 真正的兴趣。 想要更多? 让我们看一下……

可选的

可选::流

这不需要任何解释:

Stream<T> stream();

想到的第一个词是: 终于 ! 最后,我们可以轻松地从可选值流变为当前值流!

给定一个Optional findCustomer(String customerId)我们必须执行以下操作:

public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().map(this::findCustomer)// now we have a Stream<Optional<Customer>>.filter(Optional::isPresent).map(Optional::get);
}

或这个:

public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().map(this::findCustomer).flatMap(customer -> customer.isPresent()? Stream.of(customer.get()): Stream.empty());
}

我们当然可以将其推入实用程序方法中(我希望您这样做了),但是它仍然不是最佳方法。

现在,让Optional实际实现Stream会很有趣,但是

  1. 在设计Optional时似乎没有考虑过它,并且
  2. 该船已经航行,因为溪流是懒惰的,而Optional不是。

因此,剩下的唯一选择是添加一个返回零或一个元素流的方法。 这样,我们又有两个选择来实现期望的结果:

public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().map(this::findCustomer).flatMap(Optional::stream)
}public Stream<Customer> findCustomers(Collection<String> customerIds) {return customerIds.stream().flatMap(id -> findCustomer(id).stream());
}

很难说我喜欢哪个更好-都有优点和缺点-但这是另一篇文章的讨论。 两者看起来都比我们之前要做的要好。

现在,我们可以对Optional进行延迟操作。

很难说我喜欢哪个更好-都有优点和缺点-但这是另一篇文章的讨论。 两者看起来都比我们之前要做的要好。

现在,我们可以对Optional进行延迟操作。
另一个小细节:如果愿意,我们现在可以更轻松地从Optional上的急切操作转移到Stream上的惰性操作。

public List<Order> findOrdersForCustomer(String customerId) {return findCustomer(customerId)// 'List<Order> getOrders(Customer)' is expensive;// this is 'Optional::map', which is eager.map(this::getOrders).orElse(new ArrayList<>());
}public Stream<Order> findOrdersForCustomer(String customerId) {return findCustomer(customerId).stream()// this is 'Stream::map', which is lazy.map(this::getOrders)
}

我想我还没有用例,但是记住这一点很好。

Leo Leung在CC-BY 2.0下发布。

Leo Leung在CC-BY 2.0下发布。

可选::或

最后让我思考的另一个补充! 您多久使用一次Optional并想表达“使用此选项; 除非它是空的,否则在这种情况下我要使用另一个”? 很快我们就可以做到:

Optional<T> or(Supplier<Optional<T>> supplier);

假设我们需要一些客户数据,这些数据通常是从远程服务获得的。 但是因为访问它很昂贵并且非常聪明,所以我们有一个本地缓存。 实际上有两个,一个在内存上,一个在磁盘上。 (我可以看到你畏缩。放松,这只是一个例子。)

这是我们的本地API:

public interface Customers {Optional<Customer> findInMemory(String customerId);Optional<Customer> findOnDisk(String customerId);Optional<Customer> findRemotely(String customerId);}

在Java 8中将这些调用链接起来很麻烦(如果您不相信我,请尝试一下)。 但是使用Optional::or成为小菜一碟:

public Optional<Customer> findCustomer(String customerId) {return customers.findInMemory(customerId).or(() -> customers.findOnDisk(customerId)).or(() -> customers.findRemotely(customerId));
}

那不是很酷吗? 没有它,我们怎么生活? 勉强可以告诉你。 只是勉强。

可选的:: ifPresentOrElse

对于最后一个,我不太满意:

void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction);

您可以使用它来覆盖isPresent -if的两个分支:

public void logLogin(String customerId) {findCustomer(customerId).ifPresentOrElse(this::logLogin,() -> logUnknownLogin(customerId));
}

logLogin超载并且还带了一个客户,然后记录了其登录名。 同样, logUnknownLogin记录未知客户的ID。

现在,我为什么不喜欢它? 因为它迫使我同时执行这两项操作,并且使我无法再进行进一步的链接。 我本来会更愿意这样做:

Optional<T> ifPresent(Consumer<? super T> action);Optional<T> ifEmpty(Runnable action);

上面的情况看起来类似,但更好:

public void logLogin(String customerId) {findCustomer(customerId).ifPresent(this::logLogin).ifEmpty(() -> logUnknownLogin(customerId));
}

首先,我发现它更具可读性。 其次,它允许我只拥有ifEmpty分支(如果我愿意的话)(而不会因空lambda而使我的代码混乱)。 最后,它允许我进一步链接这些呼叫。 要继续上面的示例:

public Optional<Customer> findCustomer(String customerId) {return customers.findInMemory(customerId).ifEmpty(() -> logCustomerNotInMemory(customerId)).or(() -> customers.findOnDisk(customerId)).ifEmpty(() -> logCustomerNotOnDisk(customerId)).or(() -> customers.findRemotely(customerId)).ifEmpty(() -> logCustomerNotOnRemote(customerId)).ifPresent(ignored -> logFoundCustomer(customerId));
}

剩下的问题如下:将返回类型添加到方法(在这种情况下为Optional::ifPresent )是否是不兼容的更改? 不太明显,但我目前懒得去调查。 你知道吗?

反射

把它们加起来:

  • 使用Optional::stream将Optional映射到Stream
  • 使用Optional::or将空的Optional替换为返回另一个Optional的调用结果。
  • 使用Optional::ifPresentOrElse可以同时执行isPresent-if两个分支。

很酷!

你怎么看? 我敢肯定那里有人仍然会错过他最喜欢的手术。 告诉我怎么回事儿!

翻译自: https://www.javacodegeeks.com/2016/06/java-9-additions-optional.html

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

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

相关文章

Matlab功率谱估计

(2012-03-16 12:22:15) 随机信号处理 * 随机变量分布特征量 均值mean 协方差矩阵cov 相关系数矩阵corrcoef [R, P] corrcoef(X)&#xff0c;P值用于检验相关性&#xff0c;越小越相关&#xff0c;0.05以下为显著相关。 * 相关函数估计 相关函数估计xcorr [c,lags] xcorr(…

OO第三次博客作业——规格

OO第三次博客作业——规格 一、调研结果&#xff1a; 规格的历史&#xff1a; 引自博文链接&#xff1a;http://blog.sina.com.cn/s/blog_473d5bba010001x9.html 传统科学的特点是发现世界&#xff0c;而软件的特点是构造世界。软件的最底层就是0&#xff0c;1&#xff0c;两个…

EndNote使用技巧之一--参考文献的导入

2012-11-20 11:54:15| 分类&#xff1a; 学术相关 | 标签&#xff1a; |字号大中小 订阅 一、怎样给课题组的其他人员共享我的library? 打开要共享的libirary→点击file→send to→compressed lirary→在 Send to Compressed Library 窗口确认储存路径与文件名&#xf…

5.29

查看linux系统中空闲内存/物理内存使用/剩余内存 free -m top命令 是Linux下常用的性能 分析工具 ps -eL |wc -l 查看进程数 ulimit -a 查看资源限制 echo DDS_ROOT 查看DDS设置的环境变量 tcpdump -i eth0 src 192.168.2.204 查看源IP204的eth0网卡的数据包接收情况 用vi进入…

primefaces_PrimeFaces在GlassFish 3.1.2.2上推动大气

primefacesPrimeFaces 3.4在三天前发布。 除了通常令人敬畏的新组件和更新组件外&#xff0c;它还包括新的PrimeFaces Push框架。 基于Atmosphere&#xff0c;这为您的应用程序提供了简单的推送机制。 这是在最新的GlassFish 3.1.2.2上配置和运行它的方法。 准备工作 像往常一…

相关的意义

第四章 相关系数 [内容导读]   本章的内容在课程中具有承上启下的重要作用。一方面&#xff0c;相关系数是反映与描述一组数据的概括性特征量数&#xff0c;只不过这里的数据是二元变量的观测数据。另一方面&#xff0c;对相关系数内容的理解与掌握&#xff0c;是建立在散点…

oo第三次作业

一、规格历史 最初的程序设计是直接面向机器的&#xff0c;代码编写困难、可读性差&#xff0c;当时对于软件开发的需求并不多。随着对于程序规模的需求&#xff0c;出现了面向过程的设计思想&#xff0c;开发者开始忽略底层实现&#xff0c;进行程序设计。对于面向过程设计思想…

帮助推动Java EE向前发展

如果您还记得我写的题为《 Java EE 8&#xff1a;当前状态是什么》的文章 &#xff0c;很明显&#xff0c;在过去的几个月中&#xff0c;Java EE的发展肯定已经放缓。 肯定有一些Java EE下的JSR具有比其他JSR更多的活动&#xff0c;但是自JavaOne 2015以来&#xff0c;整个Java…

35

1 转载于:https://www.cnblogs.com/venicid/p/9116284.html

glassfish默认密码_在MySQL上使用含盐密码的GlassFish JDBC安全性

glassfish默认密码我在该博客上最成功的文章之一是有关在GlassFish上使用基于表单的身份验证设置JDBC安全领域的文章 。 对这篇文章的一些评论使我意识到&#xff0c;要真正使它安全&#xff0c;应该做的还很多。 开箱即用的安全性 图片&#xff1a; TheKenChan &#xff08; …

Endnote生成的中英文混排参考文献中“等”与“et al”的处理

已有 12791 次阅读 2010-3-27 00:50 |个人分类:学习|系统分类:科研笔记|关键词:Endnote,参考文献,等,et al from: http://blog.sciencenet.cn/home.php?modspace&uid485&doblog&id306545 相信有很多科研工作者在管理参考文献、写论文时选用了Endnote作为首选参考…

【洛谷】P4643 【模板】动态dp

题解 在冬令营上听到冬眠的东西&#xff0c;现在都是板子了猫锟真的是好毒瘤啊(雾) (立个flag&#xff0c;我去thusc之前要把WC2018T1乱搞过去 &#xff09; 好的&#xff0c;我们可以参考猫锟的动态动态dp的课件&#xff0c;然后你发现你什么都看不懂&#xff08;菜啊 但是我们…

让 CentOS 启动时不启动桌面服务

[日期&#xff1a;2012-11-03] 来源&#xff1a;Linux社区 作者&#xff1a;kandyer [字体&#xff1a;大 中 小] 修改/etc/inittab文件&#xff0c;将 id:5:initdefault: 改为 id:3:initdefault: Linux 系统任何时候都运行在一个指定的运行级上&#xff0c;并且不同的运…

bzoj2721樱花——质因数分解

题目&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id2721 可以知道 x 和 y 一定都大于 n! &#xff0c;不妨把 y 表示为 n!t &#xff1b; 那么 1/x 1/y 1/x 1/(n!t) 1/n! &#xff1b; 整理一下&#xff0c;最终变成&#xff1a;x (n!)/t 1 &#xff1b…

带有WildFly Swarm的远程JMS

我再次在博客上谈论WildFly群&#xff1f; 简短的版本是&#xff1a;我需要对远程JMS访问进行测试&#xff0c;并且拒绝设置复杂的功能&#xff08;如完整的应用程序服务器&#xff09;。 这个想法是要有一个简单的WildFly Swarm应用程序&#xff0c;该应用程序配置了队列和主题…

CentOS,重启的常用命令

重启命令 Linux中常用的关机和重新启动命令有shutdown、halt、reboot以及init&#xff0c;它们都可以达到关机和重新启动的目的&#xff0c;但是每个命令的内部工作过程是不同的&#xff0c;下面将逐一进行介绍。 1. shutdown shutdown命令用于安全关闭Linux系统。有些用户会…

nosql怎么使用_使用NoSQL实施实体服务–第5部分:使用云提高自治性

nosql怎么使用在之前的文章中&#xff0c;我讨论了如何通过结合使用Java Web Services &#xff0c; Java EE和CouchDB NoSQL数据库为产品构建SOA“实体”服务。 在本系列的最后一篇文章中&#xff0c;我将利用我已经创建的一些技术资产&#xff0c;并使用一些流行的SOA模式实现…

串口MSComm控件五种不同校验方式对数据收发的影响

(2008-09-10 14:50:00) http://blog.sina.com.cn/s/blog_470eccc60100arq7.html串口MSComm控件有五种校验方式&#xff0c;分别是无校验&#xff08;None&#xff09;&#xff0c;奇校验&#xff08;Odd&#xff09;&#xff0c;偶校验&#xff08;Even&#xff09;&#xff0c…

利刃 MVVMLight 3:双向数据绑定

利刃 MVVMLight 3&#xff1a;双向数据绑定 原文:利刃 MVVMLight 3&#xff1a;双向数据绑定上篇我们已经了解了MVVM的框架结构和运行原理。这里我们来看一下伟大的双向数据绑定。说到双向绑定&#xff0c;大家比较熟悉的应该就是AngularJS了&#xff0c;几乎所有的AngularJS 系…

使用Java扫描DynamoDB项目

在之前的文章中&#xff0c;我们介绍了如何查询DynamoDB数据库 查询DynamoDB第1部分 查询DynamoDB第2部分 。 除了发出查询之外&#xff0c;DynamoDB还提供扫描功能。 扫描所做的是获取您在DynamoDB表上可能拥有的所有项目。 因此&#xff0c;扫描不需要任何基于我们的分区键…