Как уже отмечали другие, предпочтительным способом является использование:
new StringBuilder(hi).reverse().toString()
, но если вы хотите реализовать это самостоятельно, я боюсь, что остальные ответынедостатки.
Причина в том, что String представляет список Unicode точек, закодированных в массиве char[]
в соответствии с кодировкой переменной длины: UTF-16 ,
Это означает, что некоторые кодовые точки используют один элемент массива (одну кодовую единицу), но другие используют два из них, поэтому могут быть пары символов, которые должны рассматриваться как одна единица (последовательный «высокий»)и "низкие" суррогаты)
public static String reverseString(String s) {
char[] chars = new char[s.length()];
boolean twoCharCodepoint = false;
for (int i = 0; i < s.length(); i++) {
chars[s.length() - 1 - i] = s.charAt(i);
if (twoCharCodepoint) {
swap(chars, s.length() - 1 - i, s.length() - i);
}
twoCharCodepoint = !Character.isBmpCodePoint(s.codePointAt(i));
}
return new String(chars);
}
private static void swap(char[] array, int i, int j) {
char temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("C:/temp/reverse-string.txt");
StringBuilder sb = new StringBuilder("Linear B Syllable B008 A: ");
sb.appendCodePoint(65536); //http://unicode-table.com/es/#10000
sb.append(".");
fos.write(sb.toString().getBytes("UTF-16"));
fos.write("\n".getBytes("UTF-16"));
fos.write(reverseString(sb.toString()).getBytes("UTF-16"));
}