java - 为什么我的 CompareTo 会因一般契约(Contract)违规错误而崩溃?

标签 java android date compare comparator

我正在尝试对我的自定义 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);
                }
            };
}

最佳答案

如果 publishedAtnull,则您的 Comparator 违反了传递性要求。

假设您有三个 Articles_Map 实例:

  • a - 值为 publishedAt
  • b - 与 publishedAt == null
  • c - publishedtAt 的值大于 as 值

现在,如果您使用 ab 或使用 bc 调用比较器,比较器将返回两次调用均为 0

为了满足传递性规则,如果使用 ac 调用比较器,则还必须返回 0。但是,由于两个对象上的字段 publishedAt 都不是 null,因此如果按描述准备,它将返回小于 0 的值。

要解决此问题,如果 o1.publishedAto2.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/

相关文章:

java - 将 To_TimeStamp 函数转换为 java

java - 建议 bean 中的 Spring Integration "onSuccessExpression"语法

android - 在 SurfaceView 扩展中将视频拉伸(stretch)到全屏

java - Android静态与非静态问题

java - Android应用内计费如何实现

java - 在应用上下文中的 prop 标签中声明一个 Date 对象

python - Pandas - 使用 datetimeindex 对数据框进行排序

java - 如何使用 java 代码获取文本文件的最后 1 mb 数据?

java - Android:多列 ArrayList 到 Listview

java - Java 7 WatchService 对其他人来说很慢吗?