IllegalArgumentException:比较方法违反了一般合同

时间:2016-02-19 10:16:08

标签: java sorting collections

对不起,还有其中一个问题,但我根本不明白这里发生了什么,或者我哪里出错了。

概述:我的contains包含多个 HashSet<Integer> set = new HashSet<>(); for(int n : a) { set.add(n); } for (int n : b) { set.add(n); } - Objects.Those有ArrayListMovie。我希望按以下条件对其进行排序,优先级如下:

  • date
  • startingTime

但是这样做时,我收到以下错误:

date

我得到了什么: 我在JavaFX项目中也有同样的事情,但我使用startingTime而不是java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeHi(TimSort.java:864) at java.util.TimSort.mergeAt(TimSort.java:481) at java.util.TimSort.mergeForceCollapse(TimSort.java:422) at java.util.TimSort.sort(TimSort.java:219) at java.util.TimSort.sort(TimSort.java:169) at java.util.Arrays.sort(Arrays.java:2010) at java.util.Collections.sort(Collections.java:1883) at org.pbdevelopement.cineapp.MainActivity.sortByStartingTime(MainActivity.java:208) 进行排序。我需要转换为ArrayList.sort(),因为显然Android还不支持Collections.sort()方法。

这是启动排序并定义Collections.sort()

的方法
ArrayList.sort()

正如您所看到的,我比较了电影中的两个Comperator,如果它们相等,我会继续比较开始时间。 以下是private ArrayList<Movie> sortByStartingTime(ArrayList<Movie> list) { Collections.sort(list, new Comparator<Movie>() { //This line is MainActivity.java: 208 ;) @Override public int compare(Movie o1, Movie o2) { int comparison = o1.getDate().compareTo(o2.getDate()); if (comparison == 0) { return o1.getStartingTime().compareTo(o2.getStartingTime()); } return comparison; } }); return list; } date类中的两种compare()方法(我应该承认它们是自编的):

DateKeeper

返回TimeKeeperpublic int compareTo(DateKeeper toCompare) { Calendar startDate = getAsCalendar(); Calendar endDate = toCompare.getAsCalendar(); long diff = endDate.getTimeInMillis() - startDate.getTimeInMillis();//in Milli seconds return (int) (diff / (1000 * 60 * 60 * 24)); } -1,因为我想将此方法用于两个日期之间的差异。我已经阅读了0方法,发现这应该不是问题。

1

compare只返回所谓的public int compareTo(TimeKeeper toCompare) { int toReturn = Integer.compare(this.getValue(), toCompare.getValue()); return toReturn; }

我不明白这是如何违反方法合同的。据我所知,getValue()是传递的(或者不是?)反身的,对称的。那么为什么我收到此错误消息?

1 个答案:

答案 0 :(得分:2)

你的问题是你在减去后的一天中除以毫秒数。这可能导致两个节目可能相隔24小时,但在不同的日子显示为同一天。 尝试:

public int compareTo(DateKeeper toCompare) {
    Calendar startDate = getAsCalendar();
    Calendar endDate = toCompare.getAsCalendar();
    long diff = (endDate.getTimeInMillis()/ (1000 * 60 * 60 * 24)) - (startDate.getTimeInMillis()/ (1000 * 60 * 60 * 24));//in Milli seconds
    return (int) diff;
}

或将两个日历对象的时间设置为午夜