本文介绍了为什么我的compareTo崩溃与一般的合同违反错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过日期属性对我的自定义 NewsAdapter Articles_Map 对象,我注意到,在更大的数据集的情况下,我的应用程序崩溃与 java.lang.IllegalArgumentException:Compare方法违反了它的一般契约!错误。

I'm trying to sort my custom NewsAdapter by a Date property of the Articles_Map object, and I've noticed that in cases with bigger data sets my app crashes with a java.lang.IllegalArgumentException: Comparison method violates its general contract! error.

我不确定是否因为 int 溢出而发生错误,它的确与合同的传递性有关。特别是对于后者,我不知道如何解决它,因为据我所知我已经处理了3种可能的结果(小于0,0,大于0)。

I'm not sure if that error happens because of an int overflow, or if it is indeed related to the transitive property of the contract. And particularly for the latter, I don't know how to fix it, because as far as I understand I'm already handling the 3 possible outcomes (less than 0, 0, greater than 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 ,则比较器违反了传输性要求。

Your Comparator violates the transitivity requirement if publishedAt is null.

假设您有三个实例 Articles_Map


  • a - publishAt

  • b - publishedAt == null

  • c - 有一个值 publishedtAt a s

  • a - with a value for publishedAt
  • b - with publishedAt == null
  • c - with a value for publishedtAt that is greater than as value

$ c> a 和 b 或与 b c ,比较器会为两个调用返回 0

Now if you call your comparator with a and b or with b and c, the comparator returns 0 for both calls.

如果使用 a c 0 $ c>。但由于两个对象上的字段 publishedAt 不是 null ,它将返回小于

To satisfy the transitivity rule, your comparator must also return 0 if it is called with a and c. But since the field publishedAt is not null on both objects, it will return a value less than 0 if prepared like described.

为了解决这个问题,你的比较器不能返回 0 如果 o1.publishedAt o2.publishedAt 中只有一个是 null

To fix this, your comparator must not return 0 if only one of o1.publishedAt and o2.publishedAt is null.

例如:

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);
            }
        };

这篇关于为什么我的compareTo崩溃与一般的合同违反错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-15 01:19