日期比较compareTo遇到的坑!!源码分析

compareTo经常用于比较日期的大小,其实java里面想要比较两个Date用此方法很方便,直接进行调用即可,我们根据返回的数值来判断是大于等于还是小于,这里我们进行实际代码格式分析compareTo(Date time1,Date time2) 其中return 1表示time1 > time2 ,return 0 表示time1 = time2 ,return -1 表示time1 < time2.很简单吧!!下面我们进行源码分析,毕竟没有任何一个开发者仅仅想知道知道这个结论!

 /**
     * Compares two Dates for ordering.
     *
     * @param   anotherDate   the <code>Date</code> to be compared.
     * @return  the value <code>0</code> if the argument Date is equal to
     *          this Date; a value less than <code>0</code> if this Date
     *          is before the Date argument; and a value greater than
     *      <code>0</code> if this Date is after the Date argument.
     * @since   1.2
     * @exception NullPointerException if <code>anotherDate</code> is null.
     */

    public int compareTo(Date anotherDate) {
        long thisTime = getMillisOf(this);   //this表示当前当前时间转化成毫秒数
        long anotherTime = getMillisOf(anotherDate);    //anotherDate此时间转化成毫秒数
        return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));   //比较运算返回简化形式
    }

这是jdk里面的源码,很简单,这里使用的是将Date转换成毫秒进行直接比较,其实这就相当于两个Long型的数值进行比较大小,然后进行返回-1 0 1 这就得到我们的返回结果,应征了上面的return
那如果我们传入的日期本身就是Date类型的呢?我们返回的结果又是怎样的呢?
我们首先把运行结果粘贴出来
这里写图片描述
百思不得其解!!!
自己写的测试用例,开始怀疑自己,本来数据库查询出来进行判断使用的1 0 -1 结果现在没有一个结果符合,开始查错, 最后总结对于String类型的日期比较,如果大于的话返回的是正整数,等于是0,小于的话就是负整数,而不仅仅局限于1,0和-1,下面讲解为什么。
我们看一下JDK源码,很多时间我们对运行结果不理解往往是因为对底层不熟悉,下面直接对源码进行分析

/**
     * Compares two strings lexicographically.
     * The comparison is based on the Unicode value of each character in
     * the strings. The character sequence represented by this
     * <code>String</code> object is compared lexicographically to the
     * character sequence represented by the argument string. The result is
     * a negative integer if this <code>String</code> object
     * lexicographically precedes the argument string. The result is a
     * positive integer if this <code>String</code> object lexicographically
     * follows the argument string. The result is zero if the strings
     * are equal; <code>compareTo</code> returns <code>0</code> exactly when
     * the {@link #equals(Object)} method would return <code>true</code>.
     * <p>
     * This is the definition of lexicographic ordering. If two strings are
     * different, then either they have different characters at some index
     * that is a valid index for both strings, or their lengths are different,
     * or both. If they have different characters at one or more index
     * positions, let <i>k</i> be the smallest such index; then the string
     * whose character at position <i>k</i> has the smaller value, as
     * determined by using the &lt; operator, lexicographically precedes the
     * other string. In this case, <code>compareTo</code> returns the
     * difference of the two character values at position <code>k</code> in
     * the two string -- that is, the value:
     * <blockquote><pre>
     * this.charAt(k)-anotherString.charAt(k)
     * </pre></blockquote>
     * If there is no index position at which they differ, then the shorter
     * string lexicographically precedes the longer string. In this case,
     * <code>compareTo</code> returns the difference of the lengths of the
     * strings -- that is, the value:
     * <blockquote><pre>
     * this.length()-anotherString.length()
     * </pre></blockquote>
     *
     * @param   anotherString   the <code>String</code> to be compared.
     * @return  the value <code>0</code> if the argument string is equal to
     *          this string; a value less than <code>0</code> if this string
     *          is lexicographically less than the string argument; and a
     *          value greater than <code>0</code> if this string is
     *          lexicographically greater than the string argument.
     */
    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);   //调用方法得到最小的字符串长度 lim
        char v1[] = value;                //转化成字符串数组进行存储
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {                 //进行遍历比较          
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;           //进行求差运算
            }
            k++;                           
        }
        return len1 - len2;                  //最后返回长度差
    }

由此可见,同一个方法,对于不同的数据类型在JDK源码中使用完全不同的解决思路,可见算法在我们开发过程中的重要性,所以衡量一个合格程序员的首要因素就应该是算法的能力!!!

以后争取每天都能出一些用来研究底层的代码和算法的实现,毕竟他们的好坏直接或者间接决定了你的高度!是码农还是程序设计师。这也就很好的解决了上面的运行结果,可见追根溯源还是底层实现的不同。
因为我这边是从数据库查询对数据进行过滤,所以我这里就不直接进行粘贴代码了,毕竟公司电脑码的代码所有知识产权都是公司,只有能力属于自己!!!

猜你喜欢

转载自blog.csdn.net/baidu_34168157/article/details/78816747