Давайте просто посмотрим на соответствующую фактическую реализацию Java (только соответствующий код) для каждого из этих методов по очереди. Это само по себе ответит об их эффективности.
String.charAt:
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
Как мы видим, это просто доступ к одному массиву, который является операцией с постоянным временем .
StringBuffer.charAt:
public synchronized char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
Опять же, доступ к одному массиву, поэтому операция с постоянным временем .
StringBuilder.charAt:
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
Опять же, доступ к одному массиву, поэтому операция с постоянным временем . Хотя все эти три метода выглядят одинаково, есть некоторые незначительные различия. Например, синхронизируется только метод StringBuffer.charAt, но не другие методы. Точно так же , если проверка немного отличается для String.charAt (угадайте почему?). Более внимательное рассмотрение этих реализаций методов дает нам другие незначительные различия между ними.
Теперь давайте посмотрим на реализации deleteCharAt. * 1026 *
Строка не имеет метода deleteCharAt. Причина может быть в том, что это неизменный объект. Поэтому показ API, который явно указывает, что этот метод изменяет объект, не является хорошей идеей.
И StringBuffer, и StringBuilder являются подклассами AbstractStringBuilder. Метод deleteCharAt этих двух классов делегирует реализацию самому родительскому классу.
StringBuffer.deleteCharAt:
public synchronized StringBuffer deleteCharAt(int index) {
super.deleteCharAt(index);
return this;
}
StringBuilder.deleteCharAt:
public StringBuilder deleteCharAt(int index) {
super.deleteCharAt(index);
return this;
}
AbstractStringBuilder.deleteCharAt:
public AbstractStringBuilder deleteCharAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
System.arraycopy(value, index+1, value, index, count-index-1);
count--;
return this;
}
Более внимательный взгляд на метод AbstractStringBuilder.deleteCharAt показывает, что он на самом деле вызывает System.arraycopy. Это может быть O (N) в худшем случае. Так что метод deleteChatAt - это O (N) сложность по времени.