当我在UI中搜索用户时,我试图按升序对用户进行排序。我用Insertion Sort开始了这个方法,我现在有类似的东西:
if (CollectionUtils.isNotEmpty(userList)) {
//Sort by ascending by display name
for (int i=1; i<userList.size(); i++){
User key = userList.get(i);
int j = i-1;
System.out.println("I: "+key.getFirstName());
System.out.println("J: "+userList.get(j).getFirstName());
while (j>-1 && isAscending(key.getFirstName(), userList.get(j).getFirstName())){
User temp = userList.get(j+1);
System.out.println("TEMP: "+temp.getFirstName());
userList.add(j+1, userList.get(j));
userList.add(j, temp);
j--;
}
userList.add(j+1, key);
}
for (final User user : userList) {
beanList.add(UserBean.getInstance(user));
}
}
假设我们有空值,我的isAscending方法会检查它,并且想法是名称为null的用户将被放置在列表的底部:
private boolean isAscending(String left, String right){
if(left.equals(right)) return false;
if(left == null && right == null) return false;
if((left == null && right != null) || left != null && right == null){
return false;
}
if(left.toLowerCase().compareTo(right.toLowerCase())>0){
return true;
}
return false;
}
通过这两种方法,我希望能够根据用户的名字按升序对用户进行排序。目前我正在进入无限循环,因为在第一次迭代之后,第一个索引处的用户被一遍又一遍地与他自己(也就是第一个索引处的用户)进行比较。
欢迎提出任何建议。感谢
答案 0 :(得分:0)
你的一个问题是你不断在列表中添加内容,但你永远不会删除任何东西。例如,您的内部循环是:
while (j>-1 && isAscending(key.getFirstName(), userList.get(j).getFirstName())){
User temp = userList.get(j+1);
System.out.println("TEMP: "+temp.getFirstName());
userList.add(j+1, userList.get(j));
userList.add(j, temp);
j--;
}
我们说该列表包含[3,2,1]
。所以第一次通过你:
temp = userList.get(1) // so temp = 2
userList.add(1, 3); // this makes the list contain [3,3,2,1]
userList.add(j, temp) // result: [2,3,3,2,1]
您想要交换位置j和j + 1的值。所以写:
temp = userList.get(j+1);
userList.set(j+1, userList.get(j));
userList.set(j, temp);
此外,您可能应该修复isAscending
方法。目前,您在潜在的空引用上调用equals
。此外,当您可以轻松拨打compareToIgnoreCase时,没有理由将toLowerCase
的参数调用compareTo
。更清洁的比较方法是:
private boolean isAscending(String left, String right){
// if either parameter is null, then not ascending
if(left == null || right == null) return false;
return (left.compareToIgnoreCase(right) > 0);
}
您可能会重新考虑代码中的空处理逻辑。对于您要进行比较的字段是否存在空值是否真的有意义?如果没有,那么你可能应该让比较方法抛出异常。
如果确实需要支持空值,则需要修改isAscending
方法,因为当前逻辑使任何非空值等于任何空值。因此,如果您的列表包含[3,null,1]
,那么对其进行排序将返回相同的顺序,因为调用isAscending(3, null)
将返回false,因此isAscending(null, 1)
也将返回false。如果要将空值排序到前面,您需要这样:
// both values are null, so not ascending
if (left == null && right == null) return false;
// left is null, but right is not
if (left == null) return true;
// right is null, but left is not
if (right == null) return false;
return (left.compareToIgnoreCase(right) > 0);