У меня есть следующая строка: ąbc. Я хотел бы получить его первый символ, т.е. ą. Когда я использую следующий код
"ąbc".substring(0,1)
Я получаю правильный результат, используя jshell. Однако при использовании IntelliJ я получаю a вместо ą. В чем дело?
Следующий модульный тест отлично работает (в IntelliJ и в Maven):
@Test
void test() {
// GIVEN
String string = "ąbc";
// WHEN
final String substring = string.substring(0, 1);
// THEN
assertThat(substring).isEqualTo("ą");
}
@Progman Разве "ąbc".substring(0,1) недостаточно?
или вы можете использовать System.out.println("ąbc".charAt(0));
И как получить вывод? Вы используете System.out.println? Вы смотрите на это в консоли операционной системы или внутри IDE?
@aled Я использую IntelliJ в качестве IDE. Только тогда я получаю неверный результат.
Между прочим, char — это устаревший тип, по сути сломанный со времен Java 2. Одним из последствий этого является то, что String#substring может не работать с большинством символов. Вместо этого возьмите за привычку использовать целые числа кодовой точки. System.out.println ( Character.toString ( "ąbc".codePoints ( ).toArray ( )[ 0 ] ) );
Интересно, действительно ли «ąbc» в этой программе — это "\u0061\u0238bc", а не "\u0105bc".
@VGR, как скопировано и вставлено с этой страницы, это U + 0105 (ЛАТИНСКАЯ СТРОЧНАЯ БУКВА A С ОГОНЕКОМ)
Если вы сначала разложите строку, используя String s = Normalizer.normalize("ąbc", Normalizer.Form.NFD);, то она все равно напечатает ąbc, но если вы попытаетесь напечатать первый символ, вы получите обычный a: System.out.println(Character.toString(s.codePoints().toArray()[0]));. Диакритический знак отделяется от основного символа. Измените [0] на [1], чтобы увидеть это.
@andrewJames Так как мне тогда получить ą?
Следующий модульный тест работает нормально: Уточнение, пожалуйста: вы говорите, что он отлично работает и в IntelliJ?
Я вижу, вы приняли ответ - и это здорово - проблема решена! Как конкретно вы ее решили? Какие конкретные изменения вы внесли в IntelliJ? (На самом деле мой комментарий о разложении — просто примечание. Должен признаться, я удивлен, что IntelliJ когда-либо автоматически разлагает ą на a — но я думаю, что это так!)
@andrewJames Я изменил шрифт. Ответ предложил это решение.
Спасибо за уточнение. Какой шрифт вы используете сейчас?
Теперь пользуюсь IBM Plex Sans JP Medm. Раньше я использовал Dejavu Sans, если я правильно помню.
На самом деле у Deja Vu Sans нет проблем с отображением U+0105 afaics.




Вероятно, это связано с неправильной настройкой консоли IDE для кодировки символов.
Независимо от видимого символа вы можете подтвердить, что это правильный символ, напечатав шестнадцатеричное значение символа:
System.out.println(String.format("%04x", (int) "ąbc".charAt(0)));
Результат должен быть 0105 для этого персонажа.
Для отображения правильного символа вам может потребоваться изменить тему Intellij или конфигурацию.
Согласно комментарию @Basil Bourque, это было бы лучше, чем System.out.printf("%04x%n", "ąbc".codePointAt(0));
Пожалуйста, отредактируйте свой вопрос, чтобы включить исходный код в качестве рабочего минимального воспроизводимого примера, который может быть скомпилирован и протестирован другими. Также подробно объясните, как именно вы компилируете свой код, какую кодировку вы используете в своем исходном коде и как вы запускаете свое приложение.