Внутреннее устройство String, метод substring - 1

— Привет, Амиго!

— Привет, Элли.

— Я тебе расскажу о подстроках. Подстрока – это часть строки. И самое частое действие со строками (после склеивания нескольких строк вместе) – это получение подстроки у строки.

7) Как получить часть строки?

Метод substring возвращает часть строки. Есть два варианта этого метода.

Первый вариант возвращает подстроку, заданную начальным и конечным номерами символов. Последний символ при этом не входит! Если передать номера (1,3) – с первого по третий, то в подстроке будут только первый и второй символы.

Второй вариант – от переданного номера и до конца строки.

Метод(ы) Пример(ы)
String substring(int beginIndex, int endIndex)
String s = "Good news everyone!";
s = s.substring(1,6);
Результат:

s == "ood n";
String substring(int beginIndex)
String s = "Good news everyone!";
s = s.substring(1);

— Все достаточно просто. Спасибо, Элли.

— Еще я тебе расскажу о внутреннем устройстве объектов String.

Как ты уже наверное знаешь – String – это immutable класс. И какие же преимущества это дало? Одно из ключевых преимуществ – это как раз получение подстроки. Но обо всем по порядку.

Внутри объект типа String содержит массив символов, о чем не трудно было догадаться. Но кроме этого там хранятся еще две переменные – номер первого символа в массиве и их количество. Для чего они нужны, я сейчас и расскажу.

Когда мы создаем подстроку с помощью метода substring, то создается новый объект String.

Но вместо того, чтобы хранить ссылку на массив с новым набором символов, этот объект хранит ссылку на старый массив символов и вместе с этим хранит две переменные, с помощью которых определяет – какая часть оригинального массива символов относится к нему.

— Ничего не понял.

— Когда создается подстрока, массив символов не копируется в новый объект String. Вместо этого оба объекта хранят ссылку на один и тот же массив символов. Но! Второй объект хранит еще две переменные, в который записано с какого и сколько символов этого массива – его.

Вот смотри:

Получение подстроки Что хранится внутри подстроки
String s = "mama";
Что хранится в s:

char[] value = {'m','a','m','a'};
offset = 0;
count = 4;
Strins s2 = s.substring(1);
Что хранится в s2:

char[] value = {'m','a','m','a'};
offset = 1;
count = 3;
Strins s3 = s.substring(1, 3);
Что хранится в s3:

char[] value = {'m','a','m','a'};
offset = 1;
count = 2;

Все три строки хранят ссылку на один и тот же массив char, просто кроме этого они еще хранят номер первого и последнего символа этого массива, который относится непосредственно к их объекту. Вернее, номер первого символа и количество.

— Теперь ясно.

— Поэтому, если ты возьмешь строку длинной 10,000 символов и наделаешь из нее 10,000 подстрок любой длины, то эти «подстроки» будут занимать очень мало памяти, т.к. массив символов не дублируется. Строки, которые должны занимать кучу места, будут занимать буквально пару байт.

— Круто!

— А если бы строки можно было менять – можно было бы так сделать?

— Нет, кто-то мог поменять ту первую строку, и тогда поменялись бы все ее «подстроки». Теперь понятно, почему так сделали. Это действительно крутое решение.

— Рада, что тебе понравилось.