当前位置: 首页 > 知识库问答 >
问题:

android中排序时如何避免IllegalArgumentException

莫典
2023-03-14

问题链接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:比较方法违反了它的一般约定!在java.util.TimPort.mergeHi(TimPort.java:864)和java.util.TimPort.regeAt(TimSort.java:481),在java.til.TimPort.mergeForceCollapse(TimSort.java:242)和java.util.Tim sort.sort(TimSport.java:219),在java.util.TimSort.sort(TimSort.cava:169)和java.util.Arrays.sort(Arrays.java:2038),在java.util.Collections.sort(Collections.java:1891),com.sample.app.adapters.BuddyListAdapter.filer联系人(BuddyListAdapter.java:144)位于com.sample.app.apps.adapters.BuddyListAdapter.notifyDataSetChanged(Buddy ListAdapter.java:126),位于com.smple.app.HomeActivity$2.onReceive(HomeAction.java:325),位于android.app.LoaddApk$ReceiverDispatcher$Args.run(LoadedApk.java:763)…9更多信息

共有1个答案

梁丘成和
2023-03-14

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

我建议尝试以下方法:

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);
 类似资料:
  • 本文向大家介绍Spark处理数据排序问题如何避免OOM,包括了Spark处理数据排序问题如何避免OOM的使用技巧和注意事项,需要的朋友参考一下 错误思想 举个列子,当我们想要比较 一个 类型为 RDD[(Long, (String, Int))] 的RDD,让它先按Long分组,然后按int的值进行倒序排序,最容易想到的思维就是先分组,然后把Iterable 转换为 list,然后sortby,但

  • Hadoop MapReduce的默认行为是在分区内对schffle键进行排序,但不是跨分区(它是使键跨部分排序的总排序) 我想问如何使用Spark RDD实现同样的事情(分区内排序,但不跨分区排序) < li>RDD的< code>sortByKey方法是进行总排序 < li>RDD的< code > repartitionandsorttwithinpartitions 在分区内进行排序,而不

  • 问题内容: 我有3个基于Acivity的应用程序,它的工作流程是 和。当onResume事件触发时,需要调用MainActivity。无需参加其他两项活动。 onResume事件触发时有什么方法可以调用? 谢谢 问题答案: 您可以在AndroidManifest.xml文件中为MainActivity 设置属性。请参阅此处以查找原因和更多详细信息。我认为这是满足您需求的最便捷方法。 编辑: 我刚刚

  • 问题内容: 我有一个,我需要能够对列进行重新排序。但是,我希望第一列不能重新排序。我使用以下命令来启用重新排序: 现在可以对列进行重新排序,包括不需要的第一列。有什么方法可以锁定第一列? 我已经看到一些使用两个表的解决方案,其中第一列在单独的表中,但是也许有更好/更简单的方法。 问题答案: 我认为您需要重写中的方法。在类有一个方法,你应该能够看到,以确定它是否是你的固定列,然后你应该能够取消事件。

  • 问题内容: 我正在尝试通过从客户端向服务器发送密钥和随机数来认证用户。 我的代码未向我显示客户端的响应。执行下面的代码时,我得到了一个空指针异常。 问题答案: 解决大多数问题的固定步骤: 阅读堆栈跟踪以确定哪一行代码引发NPE 在该行代码处设置一个断点 使用调试器,在遇到断点时,确定该行中的对象引用是 弄清楚为什么引用该文件(到目前为止,这是唯一实际的困难部分) 解决根本原因(也可能很困难)

  • 问题内容: 我有两个简单的Java代码。第一个将恒定功率定义为power = a.pow(b); 第二个将恒定功率定义为power = BigInteger.ONE.shiftLeft(b) 在命令行中设置内存标志- Xmx1024m,第一个代码可以正常工作,但是第二个代码却出现错误:java.lang.OutOfMemoryError:Java堆空间 我的问题:我应该在第二个代码中更改什么以避免