Метод codePointAt() в Java
Есть ли разница в использовании методов
static int codePointAt(CharSequence seq, int index)
из класса Character
и
int codePointAt(int index)
из класса String (кроме того, что в первом используется CharSequence)? Результат возвращают вроде бы один и тот же.
Ответы (1 шт):
Данные методы незначительно отличаются реализацией при доступе к символам.
Пример (для Open JDK 8):
Character.codePointAt(CharSequence seq, int index):
Вызывает методCharSequence::charAtдля заданного входного аргументаseq
public static int codePointAt(CharSequence seq, int index) {
char c1 = seq.charAt(index);
if (isHighSurrogate(c1) && ++index < seq.length()) {
char c2 = seq.charAt(index);
if (isLowSurrogate(c2)) {
return toCodePoint(c1, c2);
}
}
return c1;
}
Соответственно, для строки реализация метода String::charAt сводится к проверке индекса и прямому доступу через внутренний массив символов char[] value:
// String::charAt
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
String::codePointAt:
Фактически он просто проверяет индекс, чтобы выбросить особое исключениеStringIndexOutOfBoundsExceptionпри выходе за пределы строки и вызывает статический методCharacter.codePointAtImpl(доступный по умолчанию только в пакетеjava.lang), передавая в него ссылку на внутренний массив символов данной строки:
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
}
Аналогично, реализация метода Character.codePointAtImpl напрямую обращается по индексу к элементам массива:
static int codePointAtImpl(char[] a, int index, int limit) {
char c1 = a[index];
if (isHighSurrogate(c1) && ++index < limit) {
char c2 = a[index];
if (isLowSurrogate(c2)) {
return toCodePoint(c1, c2);
}
}
return c1;
}
То есть, вызов метода String::codePointAt несколько эффективнее, так как позволяет избежать двойной проверки выхода за пределы массива символов, которая происходит при двойном вызове метода String::charAt.