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);
}