[英]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.