Какая функция Java offsetByCodePoints действительно принимает в качестве аргумента? - PullRequest
4 голосов
/ 15 декабря 2011

Я пытаюсь понять некоторые функции класса String в Java. Итак, вот простой код:

/* different experiments with String class */

public class TestStrings {
    public static void main(String[] args) {
        String greeting = "Hello\uD835\uDD6b";

        System.out.println("Number of code units in greeting is " + greeting.length());
        System.out.println("Number of code points " + greeting.codePointCount(0,greeting.length()));

        int index = greeting.offsetByCodePoints(0,6);
        System.out.println("index = " + index);
        int cp = greeting.codePointAt(index);
        System.out.println("Code point at index is " + (char) cp);
    }
}

\ uD835 \ uDD6b - это символ,, так что это нормальная суррогатная пара.

Итак, строка имеет 6 (шесть) кодовых точек и 7 (семь) кодовых единиц (2-байтовые символы). Как это в документации:

offsetByCodePoints

public int offsetByCodePoints(int index,
                              int codePointOffset)

Возвращает индекс в этой строке, который смещен от данного индекса на кодовые точки codePointOffset. Непарные суррогаты в текстовом диапазоне, заданном индексом, и codePointOffset считаются за одну кодовую точку каждый.

Параметры:

index - индекс, подлежащий смещению

codePointOffset - смещение в кодовых точках

Итак, мы даем аргумент в кодовых точках . Но с заданными аргументами (0,6) все равно работает нормально, без исключений. Но терпит неудачу для codePointAt (), потому что это возвращает 7, который находится вне границ. Итак, может быть, функция получает свои аргументы в единицах кода? Или я что-то пропустил.

Ответы [ 2 ]

5 голосов
/ 15 декабря 2011

codePointAt принимает индекс char.

Индекс относится к значениям символов (кодовые единицы Unicode) и находится в диапазоне от 0 до length() - 1.

В этой строке шесть кодовых точек. Вызов offsetByCodePoints возвращает индекс после 6 кодовых точек, который является char-index 7. Затем вы пытаетесь получить codePointAt(7), который находится в конце строки.

Чтобы понять почему, рассмотрим, что

"".offsetByCodePoints(0, 0) == 0

потому что, чтобы считать все 0 кодовых точек, вы должны считать все 0 char с.

Экстраполируя это на вашу строку, чтобы считать все кодовые точки 6, вы должны считать все 7 char с.

Может быть, видение codePointAt в использовании прояснит это. Это идиоматический способ перебора всех кодовых точек в строке (или CharSequence):

for (var charIndex = 0, nChars = s.length(), codepoint;
     charIndex < nChars;
     charIndex += Character.charCount(codepoint)) {
  codepoint = s.codePointAt(charIndex);
  // Do something with codepoint.
}
0 голосов
/ 19 августа 2017

Полезный ответ, Майк ... Для простоты понимания String#offsetByCodePoints я прокомментировал его использование и немного изменил пример вопроса:

Лично я нахожу документацию по Java здесь неоднозначной.*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...