我正在尝试对我的自定义 NewsAdapter
进行排序通过Date
Articles_Map
的属性(property)对象,并且我注意到,在数据集较大的情况下,我的应用程序会崩溃并显示 java.lang.IllegalArgumentException: Comparison method violates its general contract!
错误。
我不确定该错误是否是由于int
而发生的溢出,或者是否确实与合约的传递性相关。特别是对于后者,我不知道如何解决它,因为据我所知,我已经处理了 3 种可能的结果(小于 0、0、大于 0)。
public class NewsAdapter extends ArrayAdapter<Articles_Map> {
Context mContext;
public NewsAdapter(Context c, int resource) {
super(c, resource);
this.mContext = c;
}
protected void doAdd(Articles_Map another) {
super.add(another);
}
public void addAll(List<Articles_Map> others) {
for (Articles_Map a : others) {
this.doAdd(a);
}
this.sort(byPublishedAtComparator);
}
private static final Comparator<Articles_Map> byPublishedAtComparator =
new Comparator<Articles_Map>() {
@Override
public int compare(Articles_Map o1, Articles_Map o2) {
// needs further testing in case of nulls
if (o1.publishedAt == null || o2.publishedAt == null) {
return 0;
}
return o1.publishedAt.compareTo(o2.publishedAt);
}
};
}
最佳答案
如果 publishedAt
为 null
,则您的 Comparator
违反了传递性要求。
假设您有三个 Articles_Map
实例:
- a - 值为
publishedAt
- b - 与
publishedAt
==null
- c -
publishedtAt
的值大于a
s 值
现在,如果您使用 a
和 b
或使用 b
和 c
调用比较器,比较器将返回两次调用均为 0
。
为了满足传递性规则,如果使用 a
和 c
调用比较器,则还必须返回 0
。但是,由于两个对象上的字段 publishedAt
都不是 null
,因此如果按描述准备,它将返回小于 0
的值。
要解决此问题,如果 o1.publishedAt
和 o2.publishedAt
中只有一个为 null,则比较器不得返回
.0
例如:
private static final Comparator<Articles_Map> byPublishedAtComparator =
new Comparator<Articles_Map>() {
@Override
public int compare(Articles_Map o1, Articles_Map o2) {
// needs further testing in case of nulls
if (o1.publishedAt == null) {
return (o2.publishedAt == null) ? 0 : -1;
} else if (o2.publishedAt == null) {
return 1;
}
return o1.publishedAt.compareTo(o2.publishedAt);
}
};
关于java - 为什么我的 CompareTo 会因一般契约(Contract)违规错误而崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40180280/