如何在Java中对字母数字字符串进行排序

时间:2015-01-28 12:26:20

标签: java collections

{"SAMPLE:1-1-8-SAM#1", "SAMPLE:1-1-8-SAM#13","DEMO:1-1-4-SAM#13",DEMO:1-1-4-SAM#26,DEMO:1-1-4-SAM#8}

所以,输出将是 字母顺序和数字也

DEMO:1-1-4-SAM#26
DEMO:1-1-4-SAM#13
DEMO:1-1-4-SAM#8
SAMPLE:1-1-8-SAM#1
SAMPLE:1-1-8-SAM#13

我在ArrayList中尝试过。问题是,它将整个字符串作为字符串。但我想排序字符串以及数字。这就是我得到的输出

DEMO:1-1-4-SAM#8
DEMO:1-1-4-SAM#13
DEMO:1-1-4-SAM#26
SAMPLE:1-1-8-SAM#1
SAMPLE:1-1-8-SAM#13

2 个答案:

答案 0 :(得分:4)

您必须编写自己的Comparator,将字符串拆分为词汇部分和数字部分,然后将它们与适当的运算符进行比较。

以下是Comparator唯一方法compareTo的伪代码实现,以说明我建议的内容:

public void compare(String s1, String s2) {
  String[] e1 = split(s1);
  String[] e2 = split(s2);

  int n = Math.min(e1.length, e2.length);

  int ret = 0;

  for (int i = 0; ret == 0 && i < n; i++) {
    if (isNumber(e1[i])) {
      ret = compareNumerical(e1[i], e2[i]));
    } else {
      ret = compareLexical(e1[i], e2[i]));
    }
  }

  return ret;
}

答案 1 :(得分:2)

如果您希望对字符串进行排序并考虑所有数字,可以使用正则表达式和Java 8的组合。

考虑如下字符串:

"SAMPLE:1-2-8-SAM#1"

这可以使用正则表达式分割为String[],如此

String s = "SAMPLE:1-2-8-SAM#1";
String[] arr = s.split("((?<=[:\\-#])|(?=[:\\-#]))");
System.out.println(Arrays.stream(arr).collect(Collectors.toList()));

输出结果为:

  

[SAMPLE,:,1, - ,2, - ,8, - ,SAM,#,1]

这意味着我们可以将索引0视为String,将索引2,4,6和10视为Integer

因此,为了使用它进行排序,可以使用以下代码:

String[] strings = {
        "SAMPLE:1-2-8-SAM#1",
        "SAMPLE:1-1-8-SAM#1",
        "SAMPLE:1-1-8-SAM#13",
        "DEMO:1-1-4-SAM#13",
        "DEMO:1-1-4-SAM#26",
        "DEMO:1-1-4-SAM#8"
};

final List<String> sorted = Arrays.stream(strings)
        .map(str -> str.split("((?<=[:\\-#])|(?=[:\\-#]))"))
        .sorted(Comparator
                .<String[], String>comparing((arr) -> arr[0])      // String compare
                .thenComparing(arr -> Integer.valueOf(arr[2]))     // Integer compare
                .thenComparing(arr -> Integer.valueOf(arr[4]))     // Integer compare
                .thenComparing(arr -> Integer.valueOf(arr[6]))     // Integer compare
                .thenComparing(arr -> Integer.valueOf(arr[10])))   // Integer compare
        .map(l -> Arrays.stream(l).collect(Collectors.joining()))  // Map it back to a String
        .collect(Collectors.toList());                             // Collect it to a List for further processing

它不是超级可读的,但它按照OP的问题工作。如果您还使用一些静态导入,则代码更容易阅读。


但是,我的建议是创建一个Comparator进行排序,使其更具可读性(从而在长期内更容易维护)。