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

发布于 2024-11-02 12:54:54 字数 1550 浏览 0 评论 0原文

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

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

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

(1) 文件编号 (2) 发布日期 (三)交易日期 (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;
}

问题:

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

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

快乐编程...

Am somewhat confused with Java's compareTo() and Collections.sort() behavior.

I am supposed to sort a column in ascending order using compareTo() & Collections.sort().

My criteria is (if the same number occurs than please sort the next available column).

(1) Document Number
(2) Posting Date
(3) Transaction Date
(4) Transaction Reference Number Comparison

Here's the code (which is executed in a calling method) that implements the Collection.sort() method:

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

Question(s):

(1) Am I doing the right thing? When a comparison = 0, it returns as -2. Is this correct behavior because I always thought it to be between -1,0,1.

(2) Should I be using the comparator?

Happy programming...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小红帽 2024-11-09 12:54:54

回答您的具体问题:

  1. 是的,看起来不错。结果不一定是 -1、0 或 1。不过,您的代码可能稍微不那么冗长,只要找到结果就返回,根本不使用 comparison 变量。
  2. 如果您正在实现Comparable,则无需处理Comparator。它适用于当您需要比较不可比较的内容或需要以不同方式进行比较时。

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

To address your specific questions:

  1. Yes, that looks fine. The result does not have to be -1, 0 or 1. Your code could be slightly less verbose, though, and just return as soon as it finds a result without using the comparison variable at all.
  2. If you're implementing Comparable, no need to deal with a Comparator. It's for when you need to compare something that isn't Comparable or need to compare in a different way.

Guava's ComparisonChain class makes a compareTo method like this incredibly easy:

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();
}
真心难拥有 2024-11-09 12:54:54

(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 的更轻的解决方案。

Answer for (1): It's correct. see javadoc of Comparator.compare(T, T): "a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second."

Or use Google Guava which encapsulates Comparator for easier and powerful usage:

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

It decouples each Comparator, it's easy to change/ add/ remove fields order.
EDIT: see ColinD's lighter solution.

沩ん囻菔务 2024-11-09 12:54:54

你的compareTo是足够合理的。 CompareTo 可以返回 -1,0,1 以外的值。只有负数、0 和正数。

您应该使用比较器。

Your compareTo is reasonable enough. compareTo can return values other than -1,0,1. Just negative, 0 and positive.

You should be using a comparator.

梦归所梦 2024-11-09 12:54:54
  1. 根据比较文档, compareTo():

    返回负整数、零或正整数作为此对象 
    小于、等于或大于指定对象。
    

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

  2. 这确实是一个偏好问题。就我个人而言,我更喜欢使用 Comparator,但 compareTo() 也能正常工作。无论哪种情况,您的代码看起来都几乎相同。

  1. According to the Comparable Documentation, compareTo():

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

    So -2 is a valid result.

  2. That's a matter of preference, really. Personally I prefer using a Comparator, but compareTo() works just as well. In either case, your code would look pretty much the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文