按自定义顺序对Arraylist进行排序

时间:2018-06-28 05:20:35

标签: java sorting

感谢您抽出宝贵的时间:)

我有一段代码使用compareToIgnoreCase对Arraylist进行排序。

Collections.sort(als,new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            //I want to alter this part
            int dif=o1.compareToIgnoreCase(o2); 
            return dif;
        }


    });

但是我想通过以下方式对arraylist进行排序:

输入:(按任何顺序)

sherin
Sherin
SHERIN
bubBle
buBble
BUBBLE
heart
hEart
hEArt

输出:

BUBBLE
buBble
bubBle
hEArt
hEart
heart
SHERIN
Sherin
sherin

您能帮我吗? 在此先感谢:)

2 个答案:

答案 0 :(得分:7)

您的第一次尝试还不错,但是如果不区分大小写的值相似,则需要添加另一个比较:

Stream.of("sherin", "Sherin", "SHERIN", "bubBle", "buBble", "BUBBLE", "heart", "hEart", "hEArt")
    .sorted((s1, s2) -> {
        int tmp = s1.compareToIgnoreCase(s2); 
        return tmp == 0 ? 
            s1.compareTo(s2) //Compare equivalent values based on the case (upper case first)
            : tmp;
    }).forEach(System.out::println);

Stream.sorted提供的比较器与您的实现相同,但使用的是lambda表示法。

结果:

BUBBLE
buBble
bubBle
hEArt
hEart
heart
SHERIN
Sherin
sherin

编辑:感谢Joop Eggen使用比较器装饰器的建议:

Comparator
    .comparing(Function.identity(), String::compareToIgnoreCase)
    .thenComparing(Function.identity(), String::compareTo);

使用起来更干净,并得到相同的结果:

Stream.of("sherin", "Sherin", "SHERIN", "bubBle", "buBble", "BUBBLE", "heart", "hEart", "hEArt").sorted(
        Comparator
            .comparing(Function.identity(), String::compareToIgnoreCase)
            .thenComparing(Function.identity(), String::compareTo)
    ).forEach(System.out::println);

我用这种表示法可以做的越短越好:

Comparator.comparing((String s) ->.toLowerCase()).thenComparing(Function.identity())

答案 1 :(得分:2)

    public int compare(String s1, String s2) {
        int n1 = s1.length();
        int n2 = s2.length();
        int min = Math.min(n1, n2);
        for (int i = 0; i < min; i++) {
            char c1 = s1.charAt(i);
            char c2 = s2.charAt(i);
            char u1 = Character.toUpperCase(c1);
            char u2 = Character.toUpperCase(c2);
            char l1 = Character.toLowerCase(c1);
            char l2 = Character.toLowerCase(c2);

            if (u1 != u2) {
                return u1 - u2;
            } else {
                if (l1 != l2) {
                    return l1 - l2;
                } else if (c1 != c2) {
                    return c1 - c2;
                }
            }
        }
        return n1 - n2;
    }