0

问题链接 1 链接 2 链接 3

从上面的链接中,我希望我遵循被接受的答案。但我仍然得到例外。我正在使用 Java 6。

代码 :

public class GenericComparator implements Comparator<User> {

private static final String TAG = "java.util.Comparator.GenericComparator";
EnumComparatorObjectType mType;

public GenericComparator(EnumComparatorObjectType paramType) {

    mType = paramType;
}

@Override
public int compare(User user1, User user2) {

    if (user1 == null && user2 == null)
        return 0;
    try {
        if (mType == EnumComparatorObjectType.ENUM_OBJECT_ADDRESS_BOOK_ENTRY) {
            String name1 = user1.getUsername();
            String name2 = user2.getUsername();
            return name1.compareToIgnoreCase(name2);
        } else if (mType == EnumComparatorObjectType.ENUM_OBJECT_PRESENCE) {
            EnumPresence p1 = user1.getState();
            EnumPresence p2 = user2.getState();
            return p1.compareTo(p2);
        }
    } catch (Exception e) {
        Logger.i(TAG, e.getMessage(), e);

    }
    return 0;
}

}

堆栈跟踪 :

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:2038) at java.util.Collections.sort(Collections.java:1891) at com.sample.app.adapters.BuddyListAdapter.filerContacts(BuddyListAdapter.java:144) at com.sample.app.adapters.BuddyListAdapter.notifyDataSetChanged(BuddyListAdapter.java:126) at com.sample.app.HomeActivity$2.onReceive(HomeActivity.java:325) at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:763) ... 9 more

4

1 回答 1

0

您已经处理了两个条目都是null的情况,但没有处理一个是null而另一个不是的情况。这个问题被你使用的事实隐藏了catch (Exception ...),它也捕获了NullPointerException,然后返回 0。这意味着任何比较的对象都null返回 0(意思null和一个对象相等),但非空条目是正常比较的。根据这个逻辑,你可以得到 a[1] == a[2],a[1] == a[3],但是 a[2] != a[3]。这显然是错误的,因为它不允许对对象进行正确排序。这就是异常消息“比较方法违反其一般合同”试图表达的意思。所以我建议不要Exception

我建议尝试以下方法:

if (user1 == null || user2 == null) {
    if (user1 == user2) {
        // both are null
        return 0;
    } else if (user1 == null) {
        return -1;
    }
    // user2 is null
    return 1;
}
if (mType == EnumComparatorObjectType.ENUM_OBJECT_ADDRESS_BOOK_ENTRY) {
    String name1 = user1.getUsername();
    String name2 = user2.getUsername();
    return name1.compareToIgnoreCase(name2);
} else if (mType == EnumComparatorObjectType.ENUM_OBJECT_PRESENCE) {
    EnumPresence p1 = user1.getState();
    EnumPresence p2 = user2.getState();
    return p1.compareTo(p2);
} else {
    throw IllegalArgumentException("Unsupported type: " + mType);
}

如果您首先要按状态然后按名称进行比较,则可以去掉mType,第二部分(检查 后null)将变为:

EnumPresence p1 = user1.getState();
EnumPresence p2 = user2.getState();
int comp = p1.compareTo(p2);
if (comp != 0) {
    return comp;
}
String name1 = user1.getUsername();
String name2 = user2.getUsername();
return name1.compareToIgnoreCase(name2);
于 2013-09-02T08:59:38.907 回答