今天在一份祖传代码,看到其中对 map 调用了 3 次,十分想 polish 掉它,脱敏后如下:
boolean oneBoolean = true;
Map<String, String> fMap = oneDTO.getFeatureMap();
if (fMap != null && fMap.containsKey("oneKey") && StringUtils.isNumeric(fMap.get("oneKey"))) {
Long options = Long.valueOf(fMap.get("oneKey"));
if (options != null && ((options>>>48) & 1) == 1) {
// 第48位为1,表示"一种特殊的含义"
needSplit = false;
}
}
想到以前看过的 Optional 的用法,突然想练练手(一般不可能 Push 改掉,代码变更在企业永远要经过回归测试才能上线,而回归测试意味着成本。“能跑的代码,不能改”)
正确地用 Java8,这种场景需要用反逻辑
boolean oneBoolean1 = ! Optional.ofNullable(oneDTO.getFeatureMap()).map(map -> map.get("oneKey"))
.filter(StringUtils::isNumeric).map(Long::parseLong).filter(options -> ((options >>> 48) & 1) == 1).isPresent();
如果有个人想把反逻辑放进filter里转正逻辑,而没有经过思考,就会错
boolean oneBoolean2_error = Optional.ofNullable(oneDTO.getFeatureMap()).map(map -> map.get("oneKey"))
.filter(StringUtils::isNumeric).map(Long::parseLong).filter(options -> ((options >>> 48) & 1) != 1).isPresent();
异常 CASE:中间链里出现 null 时,导致最终结果 : oneBoolean=true, oneBoolean1=true, oneBoolean2_error=false;
oneBoolean2
修正错误后
boolean oneBoolean3 = Optional.ofNullable(fulfillWareDTO.getFeatureMap()).map(map -> map.get("oneKey"))
.filter(StringUtils::isNumeric).map(Long::parseLong).map(options -> ((options >>> 48) & 1) != 1).orElse(true);
使用 Java8 中的 Optional、函数式编程等各种特性,编码的花样多了,对编码者的要求也高了。
如果不是特别熟练,建议还是只停留在使用传统的编码方式,比如使用上述祖传代码的"卫语句"形式,不要想着用"花里胡哨"的东西,除非你很熟练。
意义:养成一种习惯,在看到祖传代码的时候,思考它,想着改进它,尽管你不能去 push 覆盖掉。但是你自己写的时候,就不会写出这样的代码了。
所以本文的真正标题其实应该是《如何对待你的祖传代码》(标题党 [doge][doge][doge]
)
那么回过头来,开头的祖传代码中用了 3 次 map 的操作,在生产链路上,3 次 和 1 次成本差距虽然很微毫,但是思考 3 次优化到 1 次写法的过程十分有益:
boolean oneBoolean4 = true;
Map<String, String> fMap2 = fulfillWareDTO.getFeatureMap();
if (fMap2 != null) {
String oneValue = fMap2.get("oneKey");
if (StringUtils.isNumeric(oneValue) && ((Long.parseLong(oneValue) >>> 48) & 1) == 1) {
needSplit = false;
}
}
用 Optional 熟练之后可以这样写(我个人认为的,铁子们有更好的想法可以提出讨论)
boolean oneBoolean5 = true;
if (Optional.ofNullable(oneDTO.getFeatureMap()).map(map -> map.get("oneKey")).filter(StringUtils::isNumeric)
.map(Long::parseLong).map(options -> ((options >>> 48) & 1) == 1).orElse(false)) {
oneBoolean5 = false;
}
…
对使用 Optional 的一些建议:
.get()
,而是使用 .orElse()
或者 .orElseGet()
.get()
就会发现为 null 时会报异常,使用 Optional 本身是为了避免不断地卫语句判 null 或者 try-catch 驱动好的,感谢你看到这里,对文章有错误的地方欢迎指出,谢谢。
如果觉得本文写得不错,不妨点赞、评论、收藏、分享,你的三连是对我最大的支持!
我的 Github:zhangt2333’s Github
我的 CSDN:zhangt2333’s CSDN
我的 博客园:zhangt2333’s cnblog
我的 小书房:https://zhangt.top/
本文作者:zhangt2333
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议 。转载请注明出处!