如何按 java 中的 Unicode 代码点(UTF8 或 UTF32)排序顺序进行排序?

How to sort in Unicode code point (UTF8 or UTF32) sorted order in java?

Java 的 String.compareTo 使用 UTF16 排序。

List<String> inputValues = Arrays.asList("","figure", "flagship", "zion");
Collections.sort(inputValues);

以上代码结果排序[zion, , figure, flagship] 但是,我希望这个排序顺序是 [zion, figure, flagship, ] 请注意,某些字符是连字。

最简单的方法:

inputValues.sort(String.CASE_INSENSITIVE_ORDER.reversed());



完成度不高,但控制力更强:

将列表转换为数组:

String[] arr = new String[inputValues .size()]; 
for (int i =0; i < inputValues .size(); i++) 
    arr[i] = inputValues.get(i); 

还有其他有效的方法可以将 List 转换为数组,但这是简单易懂的方法!

然后使用这个函数:

 public static String[] textSort(String[] words) {
    for (int i = 0; i < words.length; i++) {
        for (int j = i + 1; j < words.length; j++) {
            if (words[i].toUpperCase().compareTo(words[j].toUpperCase()) < 0) {//change this to > if you want to sort reverse order
                String temp = words[i];
                words[i] = words[j];
                words[j] = temp;
            }
        }
    }

    return words;
}

[可能大家没注意到,大写的A实际上是:

Mathematical Italic Capital A (U+1D434)

]

您的问题是 Java BMP 之外的字符被编码为两个字符。

要根据代码点字典顺序对列表进行排序,您需要定义自己的 Comparator:

public class CodePointComparator implements Comparator<String> {
 @Override
 public int compare(String o1, String o2) {
    int len1 = o1.length();
    int len2 = o2.length();
    int lim = Math.min(len1, len2);
    int k = 0;
    while (k < lim) {
      char c1 = o1.charAt(k);
      char c2 = o2.charAt(k);
      if (c1 != c2) {
        // A high surrogate is greater than a non-surrogate character
        if (Character.isHighSurrogate(c1) != Character.isHighSurrogate(c2)) {
          return Character.isHighSurrogate(c1) ? 1 : -1;
        }
        return c1 - c2;
      }
      k++;
    }
    return len1 - len2;
  }
}

并将其作为参数传递给 List#sort 方法。我直接在代理对上操作以获得一些性能。

抱歉,我不是在寻找字典排序,而是简单地根据 Unicode 代码点(UTF-8 或 UTF-32)进行排序。

我尝试使用的其中一个库中有一条评论:

Input values (keys). These must be provided to Builder in Unicode code point (UTF8 or UTF32) sorted order. Note that sorting by Java's String.compareTo, which is UTF16 sorted order, is not correct and can lead to exceptions while building the FST

我遇到了 运行 问题,因为我使用的是 Collections.sort,它是 Java 的 UTF-16 排序顺序。最后,我编写了自己的比较函数,如下所示,它解决了我面临的问题。我很惊讶它在本机或其他一些流行的库中不可用。

public static void sort(List<String> list) {
    Collections.sort(
            list,
            new Comparator<String>() {
                @Override
                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++) {
                        int c1 = s1.codePointAt(i);
                        int c2 = s2.codePointAt(i);
                        if (c1 != c2) {
                            return c1 - c2;
                        }
                    }
                    return n1 - n2;
                }
            });
}