使用插入排序用户排序

时间:2018-01-29 18:56:09

标签: java spring sorting

当我在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;
    }

通过这两种方法,我希望能够根据用户的名字按升序对用户进行排序。目前我正在进入无限循环,因为在第一次迭代之后,第一个索引处的用户被一遍又一遍地与他自己(也就是第一个索引处的用户)进行比较。

欢迎提出任何建议。感谢

1 个答案:

答案 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);