【问题标题】:java collection sort issuejava集合排序问题
【发布时间】:2013-07-31 08:11:14
【问题描述】:

我使用简单的比较器并得到异常并且不知道该怎么做

我是这样称呼的:

try {
   Collections.sort(this.closePositions, new PositionComperator());
}
catch(Exception e) {
   e.printStackTrace();
}

这是比较器:

  public class PositionComperator implements Comparator<DataResponse> {

    @Override
    public int compare( DataResponse pos1, DataResponse pos2) {

        if (pos1.openTime >= pos2.openTime) {
            return 1;
        } 
        else {
            return -1;
        }// returning 0 would merge keys

    }

   }

这是个例外:

java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(Unknown Source)
at java.util.TimSort.mergeAt(Unknown Source)
at java.util.TimSort.mergeCollapse(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.TimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at GTTask.RefreshIdentityHistory.call(RefreshIdentityHistory.java:59)
at GTTask.RefreshIdentityHistory.call(RefreshIdentityHistory.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

【问题讨论】:

  • sort 不能导致元素合并。不过,如果你使用 Set,那就另当别论了。
  • 能否提供PositionComperator的代码

标签: java collections compare


【解决方案1】:

如果xy两个值有相同的openTime,那么compare(x, y)compare(y, x)都会返回1,这违反了compare的约定:

实施者必须确保所有xysgn(compare(x, y)) == -sgn(compare(y, x))

你还没有确保这一点。

您需要考虑当openTime 值相同时您希望发生什么 - 要么返回 0,要么具有一些一致的概念,即哪个值应该在另一个之前。例如,您是否可以进行一些辅助比较?

【讨论】:

  • @user502967:不,这正是我给出的原因:如果两个值相等,那么在比较它们时你会得到 1。查看compare的合同。
【解决方案2】:

您收到此错误的原因是当它对两个项目进行排序时,它们改变了顺序。您还应该包括相等的情况。

最好这样做:

return po1.openTime - pos2.opentime;

或者做

if (pos1.openTime > pos2.openTime) {
    return 1;
} 
else if (pos1.openTime < pos2.openTime) {
    return -1;
} else {
    return 0;
}

【讨论】:

  • “返回0”会导致什么?
  • 这意味着它们是相等的,它们不会被排序。查看比较方法的 java 文档。
【解决方案3】:

你可以使用treeSet。它是为你排序的。并且有比较方法。例如

TreeSet<Double> sortedSet = new TreeSet<Double>(); 

例如比较一下

TreeSet<Double> set = new TreeSet<Rock>(new Comparator<Double>()
public int compare(Double a, Double b){
                return a.value - b.value;
            }
        }

【讨论】:

猜你喜欢
  • 2018-01-02
  • 1970-01-01
  • 2014-10-22
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
相关资源
最近更新 更多