【问题标题】:Collection sorting in basis of two parameters simultaneously同时基于两个参数的集合排序
【发布时间】:2011-04-08 08:05:18
【问题描述】:

我有一个有两个日期字段的类说:

class TestData {
    Date activation;
    Date timeStamp;
}

我想根据activation 日期对上述类的列表进行排序,如果它们相等,则根据timestamp 即 max(activation) 和 max(timeStamp)。

我尝试的代码如下,它只获取 max(activation)

public class CollectionSort {

    public static void main(String[] args) {
        List<TestData> testList = new ArrayList<TestData>();

        Collections.sort(testList, new Comparator<TestData>() {

            @Override
            public int compare(TestData t1, TestData t2) {
                int result = 0;
                if (t1.getActivation().before(t2.getActivation())) {
                        result = 1;
                }
                return result;
            }
        });
        System.out.println("First object is " + testList.get(0));
    }
}

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 请注意,如果您的Comparator 实现永远不能返回负整数(通常是-1),那么它几乎肯定是错误的!因为如果compare(a, b) 返回一个正数int,那么compare(b, a) 必须返回一个负数!
  • 您不需要在比较方法中强制转换为 TestData 或 instanceof 测试。由于泛型 (Java 5) 转换是在幕后自动为您完成的,因此方法参数已经是 TestData 类型。

标签: java sorting collections


【解决方案1】:

这样就可以了!

        Collections.sort(yourList, new Comparator<TestData>() {    
            public int compare(TestData o1, TestData o2) {
                int date1Diff = o1.getActivation().compareTo(o2.getActivation());
                return date1Diff == 0 ? 
                        o1.geTimestamp().compareTo(o2.getTimestamp()) :
                        date1Diff;
            }               
        });

【讨论】:

    【解决方案2】:

    以下是使用普通 Java 的方法:

     public int compare(TestData o1, TestData o2) {
        int result = o1.getActivation().compareTo(o2.getActivation()));
        if(result==0) result = o1.getTimeStamp().compareTo(o2.getTimeStamp());
        return result;
     }
    

    或者使用Guava(使用ComparisonChain):

    public int compare(TestData o1, TestData o2) {
        return ComparisonChain.start()
          .compare(o1.getActivation(), o2.getActivation())
          .compare(o1.getTimeStamp(), o2.getTimeStamp())
          .result();
     }
    

    或者使用Commons / Lang(使用CompareToBuilder):

    public int compare(TestData o1, TestData o2) {
        return new CompareToBuilder()
          .append(o1.getActivation(), o2.getActivation())
          .append(o1.getTimeStamp(), o2.getTimeStamp())
          .toComparison();
     }
    

    (所有三个版本都是等效的,但纯 Java 版本是最冗长的版本,因此最容易出错。所有三个解决方案都假设 o1.getActivation()o1.getTimestamp() 都实现了 Comparable)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-21
      • 2019-06-12
      • 2013-03-27
      • 2015-04-27
      • 1970-01-01
      • 2017-03-29
      • 2023-01-22
      • 1970-01-01
      相关资源
      最近更新 更多