如何在java中按Unicode代码点(UTF8或UTF32)排序?

如何在java中按Unicode代码点(UTF8或UTF32)排序?,java,unicode,utf-8,utf-16,codepoint,Java,Unicode,Utf 8,Utf 16,Codepoint,Java的String.compareTo使用UTF16排序顺序 List<String> inputValues = Arrays.asList("Easiest way : inputValues.sort(String.CASE_INSENSITIVE_ORDER.reversed()); List inputValues=Arrays.asList(最简单的方法: String[] arr = new String[inputValues .size()]; f

Java的String.compareTo使用UTF16排序顺序

List<String> inputValues = Arrays.asList("Easiest way :

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

List inputValues=Arrays.asList(最简单的方法:

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


有点复杂,但控制力更强:

String[] arr = new String[inputValues .size()]; 
for (int i =0; i < inputValues .size(); i++) 
    arr[i] = inputValues.get(i); 
将列表转换为数组:

 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;
}
String[]arr=新字符串[inputValues.size()];
对于(int i=0;i
还有其他有效的方法可以将列表转换为数组,但这很容易理解

然后使用此功能:

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;
                }
            });
}
公共静态字符串[]文本排序(字符串[]单词){
for(int i=0;i
字符串温度=单词[i];
字[i]=字[j];
单词[j]=temp;
}
}
}
返回单词;
}

[可能不是所有人都注意到,大写字母a实际上是:

数学斜体大写字母A(U+1D434)

]

您的问题是,在Java中,BMP以外的字符被编码为两个字符

要根据代码点词典顺序对列表进行排序,您需要定义自己的
比较器

公共类CodePointComparator实现Comparator{
@凌驾
公共整数比较(字符串o1、字符串o2){
int len1=o1.length();
int len2=o2.length();
int lim=Math.min(len1,len2);
int k=0;
while(k

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

对不起,我不是在寻找字典排序,而是简单地基于Unicode代码点(UTF-8或UTF-32)进行排序

我尝试使用的其中一个库中有一条注释:

输入值(键)。必须以Unicode代码点(UTF8或UTF32)排序顺序提供给构建器。请注意,按Java的String.compareTo排序(UTF16排序顺序)是不正确的,在构建FST时可能会导致异常

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

公共静态无效排序(列表){
集合。排序(
列表
新比较器(){
@凌驾
公共整数比较(字符串s1、字符串s2){
int n1=s1.length();
int n2=s2.length();
int min=数学最小值(n1,n2);
对于(int i=0;i
也不处理代码点。如果Jave知道UTF-32字符串,那么应该使用这些字符串对它们进行排序,否则Java不会按UTF-16(关于代理)排序,而是按UCS-2排序(每个代码点总是2个字节)。Java的本机
字符串
是UTF-16编码的,内部只是
字符的数组(16位)。您可以将其转换为32位代码点数组,但这需要为每次比较分配内存。使高位代理大于所有其他字符也可以。您的问题令人困惑,因为Unicode代码点与任何编码都不相关,它们只是数字。A“代码点(UTF8或UTF32)“不存在,并且导致响应程序错误。您只需要按代码点、句点进行排序。A正是您编写的:如果字符串
s1
的第一个代码点在
s1
中较小,或者
s1
s2
的前缀,则字符串
s1
小于
s2