Java 简化代码并避免instanceOf和null检查
我想简化代码(例如,通过使用选项)Java 简化代码并避免instanceOf和null检查,java,java-8,functional-programming,null,optional,Java,Java 8,Functional Programming,Null,Optional,我想简化代码(例如,通过使用选项) 值可以是:null,String,Date您可以使用java 8: return Optional.ofNullable(value).filter(v -> v instanceof Date || v instanceof String) .map(v -> v instanceof Date ? MyUtils.formatDate((Date)v, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS : v)
值可以是:
null
,String
,Date
您可以使用java 8:
return Optional.ofNullable(value).filter(v -> v instanceof Date || v instanceof String)
.map(v -> v instanceof Date ? MyUtils.formatDate((Date)v, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS : v)
.orElse(null);
我会用重载来处理它:
private String formatValue(String value) {
return value;
}
private String formatValue(Date value) {
return MyUtils.formatDate(value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}
…并修复通过它的任何代码null
如果您确实必须处理null
,则:
private String formatValue(String value) {
return value;
}
private String formatValue(Date value) {
return value == null ? null : MyUtils.formatDate(value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}
上面的工作提供了在编译时已知的传递类型,通常情况下就是这样。但是如果您必须处理编译时唯一已知的类型是
Object
的可能性,那么您也可以添加Object
版本:
private string formatValue(Object value) {
if (value instanceof Date) {
return this.formatValue((Date)value);
}
return value == null ? null : value.toString();
}
这开始让人感觉像是更多的代码,但它让正常路径(已知类型)直接进入适当的方法,并且只有在处理动态对象时,您才能提供这一点,因为您一直使用对象
或者您可以只使用对象
版本。它没有更少的检查,但对我来说似乎更简单、更清晰。对于日期或字符串中的日期,不能避免instanceOf。因为null不是日期:
if (value instanceof Date) {
value = MyUtils.formatDate((Date)value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}
return Optional.ofNullable(value).map(String.class::cast);
一个对象::toString
会更安全,但现在错误的值会引发fail fast强制转换异常。如果您确实想要一个功能版本的代码,您可以这样做(使用两个选项):
但这很难理解;因此,我个人会保留您的原始版本。此处缺少部分的实例,因此如果值
不是null,但不是预期格式的日期,则将触发异常,而不是返回到值。toString()
您是对的。我还假设,我们知道,Date
就是这种类型。纠正it@Andronicus.filter(v->v instanceof Date)
将错误地删除非日期的非空对象s@T.J.Crowder返回类型不是不正确吗?它包含更多的instanceofs?如果这确实是代码的逻辑,那么就没有更安全的方法了。您能告诉我们如何在代码中使用此函数吗?调用者:writeLog(“+formatValue(diff.getFieldName());//返回字符串writeLog(“blah:+formatValue(diff.getLeft());//返回日期或null@DerBenniAusA-要改进问题,请使用“编辑”链接,而不是在评论中发布代码。“returns Date or null”您的代码似乎也允许使用字符串,这就是我问这个问题的原因。我很好奇您要传递的值的声明类型(例如,在该示例中,getLeft
的返回类型)。您是否正在传入键入为String
和Date
的内容?或者你是在传递类型为Object
的东西吗?.getLeft()等来自apache tuple pairOverloading确实似乎是最好的方法,但由于问题要求使用可选,我建议将输入更改为optional
和optional
,然后返回!value.isPresent
@Dimitris-嗯,可选的东西只是一个“例如”,如果我读对了,这不是一个要求。我认为在这种特定情况下,Optional只会使问题复杂化,而不是简化。一个细节是,如果使用的变量是对象
,因为原始方法允许它,Object o=new Date()
不会返回预期值(假设您有formatValue(Object o))
当然可以在这里定义。@AxelH-确实,这就是原因。但我也应该编辑答案。公平地说,我只需使用@已弃用的私有字符串formatValue(Object)
使用instanceof
重定向到新方法。
if (value instanceof Date) {
value = MyUtils.formatDate((Date)value, Constant.DATE_FORMAT_YYYYMMDD_HHMMSS);
}
return Optional.ofNullable(value).map(String.class::cast);
private String formatValue(Object value) {
return Optional.ofNullable(value)
.map(v -> Optional.of(v)
.filter(d -> d instanceof Date)
.map(d -> MyUtils.formatDate((Date) d,
Constant.DATE_FORMAT_YYYYMMDD_HHMMSS))
.orElseGet(() -> v.toString()))
.orElse(null);
}