如何在数字之前用字母对字母数字字符串进行排序(升序)

How to sort Alphanumeric String with letters before numbers (ascending order)

我有一个 ArrayList 的字符串,顺序如下:

Collections.sort(alTest);

1G0EE147546
1G1EE147576
1G3EE147547
1G4EE147577
1G6EE147548
1G6EE147574
1G7EE147578
1G8EE147545
1G9EE147575
1GXEE147579

注意最后一条记录1GXEE147579,当"X"出现在“9”1G9EE147575.

我需要按此方式对列表进行排序:

1GXEE147579
1G0EE147546
1G1EE147576
1G3EE147547
1G4EE147577
1G6EE147548
1G6EE147574
1G7EE147578
1G8EE147545
1G9EE147575

用"X" of 1GXEE147579在数字“0”、“1”等前 1G0 EE147546

谢谢

您可以编写自己的比较器来根据您的要求调整排序条件:

    private static final Comparator<String> comparator = new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            //here comes the comparing process
            return 0;
        }
    };

比较器 returns 三个值之一:

  • -1 当o1对象应该按顺序放在 o2之前
  • 1 当o1对象应该按顺序放在 o2之后
  • 0 当比较对象 等于

然后你可以这样使用它(注意要使用Collections.sort(...)函数你必须使用列表结构):

        Collections.sort(list, comparator);

为了给出有关此特定排序的一些提示,我建议您指定字符串中的每个字符是否都应按该方式排序(字母在数字之前)。只需遍历字符串字符并比较它们。 要检查字符是否为数字,请使用 Character.isDigit(...).

以下是一些输入:

  1. 您无法排序 HashSetCollections#sort 消耗 List。您可以创建 ArrayList 将 Set 传递给 Constructor
Set<String> hsNr = new HashSet<String>();
ArrayList list = new ArrayList(hsNr);
  1. 为了按照您需要的方式对列表进行排序,您可以将 Comparator 作为第二个参数传递给 Collections#sort:
        Collections.sort(list, new Comparator<String>() {
            public int compare(String o1, String o2) {
                // write your implementation here
                // return ...  
            }
        });
  1. 您可以看一下字符串比较的标准实现,并将其用作创建 Comparator 的示例:java.lang.StringUTF16#compareTo(byte[], byte[])

这里是一个简单的比较器示例,可以执行您想要的操作。

编辑:您还可以将比较器添加到您的设置中,作为 TreeSet 而不是 HashSet.

Set<String> datas = new TreeSet<>(new SimpleComparator());

详情可参考javadoc

    static class SimpleComparator implements Comparator<String> {
        @Override
        public int compare(String s, String s2)
        {
            if(s == s2)
                return 0;
            if(s != null && s2 == null)
                return -1;
            if(s == null && s2 != null)
                return 1;
            return (s.charAt(2) == 'X' ? s.substring(0, 2) + ' ' + s.substring(3) : s).compareTo(s2);
        }
    }

    @Test
    public void sort() throws Exception{

        List<String> data =  Arrays.asList(
                "1G0EE147546",
                "1G1EE147576",
                "1G3EE147547",
                "1G4EE147577",
                "1G6EE147548",
                "1G6EE147574",
                "1G7EE147578",
                "1G8EE147545",
                "1G9EE147575",
                "1GXEE147579"

        );
        Collections.sort(data, new SimpleComparator());
        System.out.println(data.toString().replaceAll(",", "\n"));
    }

我使用 Java 8 个流实现它:

    public List<String> specialSort(Set<String> hsNr) {
        return hsNr.stream()
                .sorted((a, b) -> a.charAt(2) == 'X' ? b.compareTo(a) : a.compareTo(b))
                .collect(Collectors.toList());
    }

集合无法排序,因为不能保证顺序。请注意,您在使用集合时没有 get(index) 方法。

创建自定义 Collator using the RuleBasedCollator class:

String rules = "< a, A < b, B < c, C < d, D < e, E < f, F < g, G < h, H < i, I" +
              " < j, J < k, K < l, L < m, M < n, N < o, O < p, P < q, Q < r, R" +
              " < s, S < t, T < u, U < v, V < w, W < x, X < y, Y < z, Z" +
              " < 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9";
RuleBasedCollator myCollator = new RuleBasedCollator(rules);

List<String> list = Arrays.asList(
        "1G7EE147578", "1G6EE147548", "1G1EE147576", "1G0EE147546", "1G8EE147545",
        "1G4EE147577", "1G6EE147574", "1GXEE147579", "1G9EE147575", "1G3EE147547");
System.out.println("Before: " + list);
Collections.sort(list, myCollator);
System.out.println("After:  " + list);

输出

Before: [1G7EE147578, 1G6EE147548, 1G1EE147576, 1G0EE147546, 1G8EE147545, 1G4EE147577, 1G6EE147574, 1GXEE147579, 1G9EE147575, 1G3EE147547]
After:  [1GXEE147579, 1G0EE147546, 1G1EE147576, 1G3EE147547, 1G4EE147577, 1G6EE147548, 1G6EE147574, 1G7EE147578, 1G8EE147545, 1G9EE147575]