简体   繁体   English

如何在Android中排序时避免IllegalArgumentException

[英]how to avoid IllegalArgumentException while sorting in android

ISSUE link 1 link 2 link 3 问题链接1 链接2 链接3

From the above links,i hope i'm following the answers which are accepted.But still im getting the exception. 从上面的链接,我希望我能遵循被接受的答案。 I'm using Java 6. 我正在使用Java 6。

code : 代码:

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

}

Stack trace : 堆栈跟踪 :

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

You have taken care of the case that both entries are null , but not the case that one is null and the other is not. 您已经考虑了两个条目均为null的情况,但没有注意一个条目为null且另一个条目都不为null的情况。 The problem was hidden by the fact that you used catch (Exception ...) , which also catches NullPointerException , and then return 0. That means any object compared to null returns 0 (meaning null and an object are equal), but non-null entries are compared normally. 您使用catch (Exception ...)也会捕获NullPointerException ,然后返回0,这一事实掩盖了问题。这意味着与null相比,任何对象都将返回0(意味着null和一个对象相等),但是非正常比较空条目。 According to this logic, you coult get a[1] == a[2], and a[1] == a[3], but a[2] != a[3]. 根据此逻辑,您将得到a [1] == a [2]和a [1] == a [3],但a [2]!= a [3]。 This is clearly wrong as it wouldn't allow objects to be sorted correctly. 这显然是错误的,因为它不允许正确地对对象进行排序。 This is what the exception message "Comparison method violates its general contract" is trying to say. 这就是异常消息“比较方法违反了它的一般约定”的意思。 So I suggest to not catch Exception . 因此,我建议不要捕获Exception

I suggest to try the following: 我建议尝试以下方法:

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

If you first want to compare by state and then by name, you could get rid of mType , and the second part (after checking for null ) would become: 如果首先 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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM