利用Idea重构功能及Java8语法特性——优化深层嵌套代码
利用Idea重构功能及Java8语法特性——优化深层嵌套代码
当遇到深层嵌套代码,如for,if,lambda表达式或内部类及这些代码的组合,这时我们可以通过Java 8的语法特性来进行优化。
下面的代码是一个嵌套循环的示例。
复制代码
public MappedField getMappedField(final String storedName) {
for (final MappedField mf : persistenceFields) { for (final String n : mf.getLoadNames()) { if (storedName.equals(n)) { return mf; } } } return null;
}
复制代码
重构1:
嵌套的for/if语句通畅可以通过Java 8中的stream来替代。
Optional found = persistenceFields.stream()
.flatMap(mappedField -> mappedField.getLoadNames().stream())
.filter(storedName::equals)
.findFirst();
上述重构代码会返回Optional,但笔者希望返回mappedField对象,再次改造后的代码如下。
复制代码
persistenceFields.stream()
.filter(mappedField -> {
for (String name : mappedField.getLoadNames()) { if (storedName.equals(name)) { return true; } } return false;
}
)
.findFirst()
复制代码
重构2: 进行更好的封装
重构1还存在一些问题,我们需要了解mappedField的结构,并通过循环遍历其所有name来找到匹配的name。根据迪米特法则(Law of Demeter ),及命令-不要去询问法则(Tell, Don’t Ask), 下面代码应该由MappedField对象来提供对应的方法来判断,而不是由调用者去了解MappedField结构后去写逻辑进行判断。
for (final MappedField mf : persistenceFields) {
if (mf.hasName(storedName)) { return mf; }
}
因此将上述代码提取为MappedField类中独立的方法,并命名为hasName。如果使用的IDE 是IDEA则可以通过refractor中的extract功能完成提取。
最后调用hasName方法来替代循环判断逻辑。
接着通过Idea的refractor 中的move功能将代码移动到目标类位置。
接着通过stream来重构hasName方法,hasName方法变更为下面的形式。
public Boolean hasName(String storedName) {
return getLoadNames().stream() .anyMatch(storedName::equals);
}
经过上述步骤最终重构后的代码为。
public MappedField getMappedField(final String storedName) {
return persistenceFields.stream() .filter(mf -> mf.hasName(storedName)) .findFirst() .orElse(null);
}
如需要返回Optional包装的对象则需要去掉orElse。
public Optional getMappedField(final String storedName) {
return persistenceFields.stream() .filter(mf -> mf.hasName(storedName)) .findFirst();
}
总结
这类代码特征通常为:
存在深层的循环或条件判断嵌套。
需要通过多个getter方法来访问对象内部数据。
重构方法:
考虑tell don’t ask原则,提供专用的方法供外部调用访问数据,而不是通过使用者经过多次访问去获取对象数据。并通过stream提供的操作来完成重构。
原文地址https://www.cnblogs.com/Java-no-1/p/11305245.html
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java内部类超详细总结(含代码示例)
Java内部类超详细总结(含代码示例)什么是内部类什么是内部类?顾名思义,就是将一个类的定义放在另一个类的内部。概念很清楚,感觉很简单,其实关键在于这个内部类放置的位置,可以是一个类的作用域范围、一个方法的或是一个代码块的作用域范围。所以理解了概念只是第一步,掌握细节才能彻底搞定Java的内部类特性。看例子,这是最普通的内部类: public class Product1 { class Design{ private String name = "P30 pro"; public String showName() { return name; } } class Content{ private int i; Content(int value){ i = value; } int value() {return i;} } public void show(int value) { Content c = new Content(value); Design d = new Design(); System.out.println(d.showName()); System.ou...
- 下一篇
MessagePack Java 0.6.X 快速开始指南 - 安装
0.6.x 版本的 MessagePack 已经过期被淘汰了。如果你现在开始使用 MessagePack 话,请不要使用这个版本。 我们再这里保留 0.6.x 版本的内容主要用于参考用途。 最新的MessagePack 版本请参考:https://github.com/msgpack/msgpack-java中的项目源代码。 MessagePack 中文文档请参考:http://docs.ossez.com/messagepack-docs/index.html MessagePack 测试和示例源代码:https://github.com/cwiki-us-demo/serialize-deserialize-demo-java 这个指南提供了使用msgpack-java 的快速指南。在开始的时候,我们将会介绍如何安装msgpack-java,然后将会运行如何使用msgpack 来对对象序列化/反序列化(serialize/deserizalize)对象。 安装 你可以使用下面 2 种方法来安装 msgpack-java —— 从 maven 下载或者直接构建 jar 包。 从 Ma...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS关闭SELinux安全模块
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2整合Redis,开启缓存,提高访问速度