compareTo()和Collections.sort()多列排序(升序)问题的解决方案

时间:2011-04-18 01:59:39

标签: java sorting collections compareto

我对Java的compareTo()和Collections.sort()行为感到困惑。

我应该使用compareTo()&amp ;;按升序对列进行排序。 Collections.sort()。

我的标准是(如果出现相同的数字,请排序下一个可用的列)。

(1)文件编号 (2)发布日期 (3)交易日期 (4)交易参考编号比较

这是实现Collection.sort()方法的代码(在调用方法中执行):

public int compareTo(CreditCardTransactionDetail t) {
   int comparison = 0;

   int documentNumberComparison = this.getDocumentNumber().compareTo(t.getDocumentNumber());
   if (documentNumberComparison != 0) {
       comparison = documentNumberComparison;
   } 
   else {
       int postingDateComparison = this.getTransactionPostingDate().compareTo(t.getTransactionPostingDate());
       if (postingDateComparison != 0) {
           comparison = postingDateComparison;
       } 
       else {
           int transactionDateComparison = this.getTransactionDate().compareTo(t.getTransactionDate());
           if (transactionDateComparison != 0) {
               comparison = transactionDateComparison;
           }
           else {
               int transactionRefNumberComparison = this.getTransactionReferenceNumber().compareTo(t.getTransactionReferenceNumber());
               LOG.info("\n\n\t\ttransactionRefNumberComparison = " + transactionRefNumberComparison + "\n\n");
               if (transactionRefNumberComparison != 0) {
                   comparison = transactionRefNumberComparison;
               }
           }
       }
    return comparison;
}

问题(S):

(1)我做对了吗?当比较= 0时,它返回-2。这是正确的行为,因为我一直认为它在-1,0,1之间。

(2)我应该使用比较器吗?

快乐的节目......

4 个答案:

答案 0 :(得分:4)

解决您的具体问题:

  1. 是的,看起来不错。结果不一定是-1,0或1.但是,您的代码可能稍微冗长一点,只要在没有使用comparison变量的情况下找到结果就返回。
  2. 如果您正在实施Comparable,则无需处理Comparator。当您需要比较不是Comparable或需要以不同方式进行比较的内容时,就可以了。
  3. GuavaComparisonChain课程使compareTo这样的方法非常容易:

    public int compareTo(CreditCardTransactionDetail o) {
      return ComparisonChain.start()
          .compare(getDocumentNumber(), o.getDocumentNumber())
          .compare(getTransactionPostingDate(), o.getTransactionPostingDate())
          .compare(getTransactionDate(), o.getTransactionDate())
          .compare(getTransactionReferenceNumber(), o.getTransactionReferenceNumber())
          .result();
    }
    

答案 1 :(得分:2)

回答(1):这是正确的。请参阅Comparator.compare(T,T)的javadoc:“一个负整数,零或正整数,因为第一个参数小于,等于或大于第二个。

或者使用Google Guava封装Comparator,以便更轻松,更强大地使用:

  //Write 4 Comparators for each comparable field
 Ordering ordering = Ordering.from(comparatorDocumentNumber)
    .compound(comparatorTransactionPostingDate)
    .compound(comparatorTransactionDate)
    .compound(comparatorTransactionReferenceNumber);
 Collections.sort(list, ordering);

它解耦每个比较器,很容易更改/添加/删除字段顺序。 编辑:看看ColinD的轻量级解决方案。

答案 2 :(得分:0)

你的比较足够合理。 compareTo可以返回-1,0,1以外的值。只是消极,0和正面。

你应该使用比较器。

答案 3 :(得分:0)

  1. 根据Comparable DocumentationcompareTo()

    Returns a negative integer, zero, or a positive integer as this object 
    is less than, equal to, or greater than the specified object.
    

    所以-2是一个有效的结果。

  2. 这是一个偏好的问题,真的。我个人更喜欢使用Comparator,但compareTo()也适用。在任何一种情况下,您的代码看起来都差不多。