din*_*ngy 16 java sorting string utf-16
TLDR
Java使用两个字符来表示UTF-16。使用Arrays.sort(不稳定的排序)会使字符排序混乱。我应该将char []转换为int []还是有更好的方法?
细节
Java将字符表示为UTF-16。但是Character类本身会包装char(16位)。对于UTF-16,它将是2的数组char(32位)。
使用内置的排序功能对一串UTF-16字符进行排序会使数据混乱。(Arrays.sort使用双重数据透视快速排序,Collections.sort使用Arrays.sort进行繁重的工作。)
具体来说,您是将char []转换为int []还是有更好的排序方式?
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] utfCodes = {128513, 128531, 128557};
String emojis = new String(utfCodes, 0, 3);
System.out.println("Initial String: " + emojis);
char[] chars = emojis.toCharArray();
Arrays.sort(chars);
System.out.println("Sorted String: " + new String(chars));
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Initial String:
Sorted String: ????
Run Code Online (Sandbox Code Playgroud)
Jac*_* G. 12
我四处张望,没有找到任何干净的方法来对两个元素进行分组来对数组进行排序,而不使用库。
幸运的是,codePoints中的String就是您String在本示例中用于创建自身的内容,因此您可以对它们进行排序并String使用结果创建一个新的对象。
public static void main(String[] args) {
int[] utfCodes = {128531, 128557, 128513};
String emojis = new String(utfCodes, 0, 3);
System.out.println("Initial String: " + emojis);
int[] codePoints = emojis.codePoints().sorted().toArray();
System.out.println("Sorted String: " + new String(codePoints, 0, 3));
}
Run Code Online (Sandbox Code Playgroud)
初始字符串:
排序字符串:
因为您已经对它们进行了排序,所以我在示例中切换了字符的顺序。
如果您使用的是Java 8或更高版本,则这是一种在尊重(不破坏)多字符代码点的同时对字符串中的字符进行排序的简单方法:
int[] codepoints = someString.codePoints().sort().toArray();
String sorted = new String(codepoints, 0, codepoints.length);
Run Code Online (Sandbox Code Playgroud)
在Java 8之前,我认为您要么需要使用循环来迭代原始字符串中的代码点,要么需要使用第三方库方法。
幸运的是,对字符串中的代码点进行排序并不常见,以至于上述解决方案的笨拙和相对效率低下很少引起关注。
(您上次测试表情符号字谜是什么时候?)