在 Java 8 中使用 Optional 进行多次空检查

Pi5*_*i53 2 java datetime if-statement optional java-8

我想使用 Java 8 使用多个if和else语句来简化下面的代码。有没有办法使用一些 Java 8 功能来完全摆脱它们,例如Optional?我试图在这里找到一些东西,但找不到答案。

LocalDateTime beDate = someDate;
LocalDateTime aeDate = someDate;
LocalDateTime eDate;

if (beDate == null && aeDate == null) {
    eDate = null;
}
else if (beDate != null && aeDate == null) {
    eDate = beDate;
}
else if (beDate == null && aeDate != null) {
    eDate =  aeDate;
}
else if (beDate != null && aeDate != null && 
        (beDate.isEqual(aeDate) || beDate.isBefore(aeDate))) {
    eDate = beDate;
}
else {
    eDate = aeDate;
}
Run Code Online (Sandbox Code Playgroud)

chr*_*ke- 10

这里的逻辑很难理解。相反,更直接地表达你的意图:

private static final Comparator<ChronoLocalDateTime<?>> EARLIEST_PRESENT = 
    Comparator.nullsLast(Comparator.naturalOrder());

LocalDateTime eDate = BinaryOperator.minBy(EARLIEST_PRESENT).apply(beDate, aeDate);
Run Code Online (Sandbox Code Playgroud)

(请注意,元素的静态导入 fromComparator和BinaryOperator将使这更加清晰。)

  • @akuzminykh 人类的可理解性可能是代码中最重要的目标。我花了几乎一分钟的时间才弄清楚 OP 代码的用途。 (4认同)
  • 这是一个很好的答案,但有点太过分了。无论如何,这正是OP所要求的。 (2认同)
  • @OleV.V。我们拭目以待。我不认为自己会很快达到多个每日限额。 (2认同)
  • 或者`return BinaryOperator.minBy(EARLIEST_PRESENT).apply(beDate, aeDate);`虽然在这种情况下我更喜欢[单个表达式](/sf/answers/4252719971/)... (2认同)

Hol*_*ger 7

鉴于结果只是两种可能结果之一,您的条件是多余的:

if (beDate == null && aeDate == null) {
    eDate = null;
}
else if (beDate != null && aeDate == null) {
    eDate = beDate;
}
...
Run Code Online (Sandbox Code Playgroud)

在这里,无论是否eDate具有与beDate任何一种情况相同的内容null。这样if(aeDate == null) eDate = beDate;就足够了。在所有其他情况下,您正在分配aeDate,只有一个例外:

...
else if (beDate != null && aeDate != null && 
        (beDate.isEqual(aeDate) || beDate.isBefore(aeDate))) {
    eDate = beDate;
}
...
Run Code Online (Sandbox Code Playgroud)

我们可以简化beDate.isEqual(aeDate) || beDate.isBefore(aeDate)为aeDate.isAfter(beDate).

所以整个语句可以写成:

LocalDateTime eDate
    = aeDate == null || (beDate != null && aeDate.isAfter(beDate))? beDate: aeDate;
Run Code Online (Sandbox Code Playgroud)

的||是短路装置,该装置,右手侧是仅当左手侧评估,以评估false,所以,当左手侧是aeDate == null,它是隐含的右手侧aeDate != null,并且不需要重复进行。

SoeDate将获得beDatewhen aeDateis null(前两个if语句)或when both are not nulland aeDateis after beDate(另一个引用的if语句)的值,并获得aeDateotherwise的值。

运算符优先级使括号变得不必要,但为了清晰起见,保留它们也是有效的。