Как получить букву с акцентом, используя substring()?

У меня есть следующая строка: ą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 29.05.2023 21:41

@Progman Разве "ąbc".substring(0,1) недостаточно?

menteith 29.05.2023 21:43
Нет
Progman 29.05.2023 21:47

или вы можете использовать System.out.println("ąbc".charAt(0));

Vinay 29.05.2023 21:51

И как получить вывод? Вы используете System.out.println? Вы смотрите на это в консоли операционной системы или внутри IDE?

aled 29.05.2023 21:54

@aled Я использую IntelliJ в качестве IDE. Только тогда я получаю неверный результат.

menteith 29.05.2023 21:57

Между прочим, char — это устаревший тип, по сути сломанный со времен Java 2. Одним из последствий этого является то, что String#substring может не работать с большинством символов. Вместо этого возьмите за привычку использовать целые числа кодовой точки. System.out.println ( Character.toString ( "ąbc".codePoints ( ).toArray ( )[ 0 ] ) );

Basil Bourque 29.05.2023 23:35

Интересно, действительно ли «ąbc» в этой программе — это "\u0061\u0238bc", а не "\u0105bc".

VGR 30.05.2023 04:52

@VGR, как скопировано и вставлено с этой страницы, это U + 0105 (ЛАТИНСКАЯ СТРОЧНАЯ БУКВА A С ОГОНЕКОМ)

g00se 30.05.2023 11:08

Если вы сначала разложите строку, используя String s = Normalizer.normalize("ąbc", Normalizer.Form.NFD);, то она все равно напечатает ąbc, но если вы попытаетесь напечатать первый символ, вы получите обычный a: System.out.println(Character.toString(s.codePoints().toArray‌​()[0]));. Диакритический знак отделяется от основного символа. Измените [0] на [1], чтобы увидеть это.

andrewJames 30.05.2023 14:08

@andrewJames Так как мне тогда получить ą?

menteith 30.05.2023 15:38

Следующий модульный тест работает нормально: Уточнение, пожалуйста: вы говорите, что он отлично работает и в IntelliJ?

g00se 30.05.2023 15:51

Я вижу, вы приняли ответ - и это здорово - проблема решена! Как конкретно вы ее решили? Какие конкретные изменения вы внесли в IntelliJ? (На самом деле мой комментарий о разложении — просто примечание. Должен признаться, я удивлен, что IntelliJ когда-либо автоматически разлагает ą на a — но я думаю, что это так!)

andrewJames 30.05.2023 15:55

@andrewJames Я изменил шрифт. Ответ предложил это решение.

menteith 31.05.2023 17:42

Спасибо за уточнение. Какой шрифт вы используете сейчас?

andrewJames 31.05.2023 17:46

Теперь пользуюсь IBM Plex Sans JP Medm. Раньше я использовал Dejavu Sans, если я правильно помню.

menteith 31.05.2023 17:51

На самом деле у Deja Vu Sans нет проблем с отображением U+0105 afaics.

g00se 31.05.2023 19:03
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
17
92
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вероятно, это связано с неправильной настройкой консоли IDE для кодировки символов.

Независимо от видимого символа вы можете подтвердить, что это правильный символ, напечатав шестнадцатеричное значение символа:

      System.out.println(String.format("%04x", (int) "ąbc".charAt(0)));

Результат должен быть 0105 для этого персонажа.

Для отображения правильного символа вам может потребоваться изменить тему Intellij или конфигурацию.

Согласно комментарию @Basil Bourque, это было бы лучше, чем System.out.printf("%04x%n", "ąbc".codePointAt(0));

g00se 30.05.2023 00:43

Другие вопросы по теме