2017-05-12 161 views
0

问题:你是如何处理这些用例的?LocalDate:缺少方法isEqualOrBefore isEqualOrAfter

  • 你使用静态辅助方法吗?
  • 你使用verbose equals后跟isAfter/isBefore吗?
  • 你使用否定相反的条件吗?
  • 你使用第三方库助手吗?

在日常业务中,我经常需要检查日期a < =日期b或日期a> =日期b。

互联网通常建议使用isBefore/isAfter方法的否定版本。

在实践中我发现,我

  • 几乎从来没有得到这些否定比较正确的第一次尝试(他们应该是直观和容易)。
  • 也很难读码

我想我的一部分仍然希望,我只是忽略了API中的相应方法(请!)当理解业务逻辑。

/** 
    * @return true if candidate >= reference </br> 
    *   or in other words: <code>candidate.equals(reference) || candidate.isAfter(reference)</code> </br> 
    *   or in other words: <code>!candidate.isBefore(reference) </br> 
    *   or in other words: <code>candidate.compareTo(reference) >= 0 
    */ 
    public static boolean isEqualOrAfter(LocalDate candidate, LocalDate reference) 
    { 
    return !candidate.isBefore(reference); 
    } 

    /** 
    * @return true if candidate <= reference </br> 
    *   or in other words: <code>candidate.equals(reference) || candidate.isBefore(reference)</code> </br> 
    *   or in other words: <code>!candidate.isAfter(reference) </br> 
    *   or in other words: <code>candidate.compareTo(reference) <= 0 
    */ 
    public static boolean isEqualOrBefore(LocalDate candidate, LocalDate reference) 
    { 
    return !candidate.isAfter(reference); 
    } 

编辑:由于由Andreas建议,我加入了版本compareTo方法,我希望我得到了他们的权利(未经测试)。

编辑2:例:

// Manager says: "Show me everything from 3 days ago or later" or "show me everything that's at most 3 days old" 
for(Item item : items) { 
    // negation idiom 
    if(!item.getDate().isBefore(LocalDate.now().minusDays(3))) { 
    // show 
    } 

    // compareTo idiom 
    if(item.getDate().compareTo(LocalDate.now().minusDays(3)) >= 0) { 
    // show 
    } 

    // desired 
    if(item.getDate().isEqualOrAfter(LocalDate.now().minusDays(3))) { 
    // show 
    } 
} 
+0

你不需要equals方法,前后都足够了。要使用equals()来测试相等性。 –

+0

@StimpsonCat @StimpsonCat @StimpsonCat在技术上你当然是对的,但这个问题的关键在于抱怨它根本不方便(而且对我和其他人来说非常容易出错) – Zalumon

+2

投票结束为“主要基于意见的”,因为对“你如何处理这些用例?”的回答完全是基于观点的。 ---但是,你忘记列出'compareTo()'。请注意,a.isAfter(b),a.isBefore(b)和a.isEqual(b)与a.compareTo(b)> 0完全相同,a.compareTo( b)<0'和'a.compareTo(b)== 0',所以你的'a.isEqualOrAfter(b)'和'a.isEqualOrBefore(b)'与'a.compareTo(b) )> = 0'和'a.compareTo(b)<= 0'。 – Andreas

回答

3

的compareTo是对于这些类型的(当然它们实现可比)是否一致? 记得联文档暗示“成语”:

(a.compareTo(b) <operator> 0), so 

for isEqualOrBefore: (a.compareTo(b) <= 0) 
for isEqualOrAfter: (a.compareTo(b) >= 0) 
+0

是的,我认为他们是,正如安德烈亚斯已经指出的那样。我将这些选项包含在我的问题代码中。然而,除了可读性问题之外,就我看来,只有问你自己这个方法是否一致才会使得这个方法不如isEqualOrAfter。 – Zalumon

+0

好的,直到发布后才看到更新。我经常得到compareTo错误 - ,直到我在类文件中读取该行为止! – nsandersen

+3

自从Java 1.0以来,它是'BigDecimal'中常见的成语。查看['BigDecimal.compareTo()']的javadoc(https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#compareTo-java.math.BigDecimal-):*该方法优先于六个布尔比较运算符('<', '==', '>','> =','!=','<=')中的每一个的单独方法。进行这些比较的建议习惯用法是:'(x.compareTo(y)''0)',其中是六个比较运算符之一* – Andreas

3

的方法你寻求的unnecesary。你就是这么做的:

isEqualOrBefore == !isAfter 
isEqualOrAfter == !isBefore 
+0

看到这正是我强烈反对的地方(以及为什么Andreas将这个问题标记为主要基于意见的原因)。我觉得这个建议的解决方案不方便,不太可读,并且很容易出错(以我的经验)。 – Zalumon

+0

另外我会争辩说,我寻求这些方法的事实使他们有必要。 – Zalumon

+1

没有必要的问题,他们没有必要。你可能认为它们方便可读,但我不同意你的看法。我所提出的只是对于不注意最重要的'!'的粗心大意或新手程序员而言“容易出错”。没有注意到这个错误只会发生一次。至于你的建议,我不喜欢它。像“isEqualOrBefore”这样的长方法名称的可读性要差得多,主要是因为它们由许多单词组成,并且一看不到它们。其次,如果我不得不,我会把它命名为isBeforeOrEqual,以区分2更好。 – Dariusz