В каком контексте класс String является неизменяемым, в отличие от класса StringBuilder?

Зачем было использовать StringBuilder для изменения строки вместо простой конкатенации, которая все равно будет преобразована в String?
  • 7 января 2024 г. 11:17
Ответы на вопрос 2
Класс `String` в Java является неизменяемым (immutable), что означает, что после его создания содержимое объекта класса `String` изменить невозможно. Каждый раз, когда вы выполняете операцию, которая кажется "изменением" строки (например, конкатенацию), фактически создается новый объект `String`.

Например:
```java
String str = "Hello";
str = str + " world!"; // создается новый объект, на который теперь ссылается str
```

Класс `StringBuilder`, напротив, является изменяемым (mutable). Это значит, что вы можете добавлять, удалять и изменять содержимое объекта `StringBuilder`, не создавая каждый раз новый объект. `StringBuilder` оптимизирован для подобных операций и позволяет экономить память и процессорное время, особенно при выполнении большого количества конкатенаций.

Рассмотрим пример с `StringBuilder`:
```java
StringBuilder sb = new StringBuilder("Hello");
sb.append(" world!"); // изменяется содержимое объекта sb, новый объект не создается
```

Использование `StringBuilder` вместо конкатенации строк через оператор `+` целесообразно, когда нам необходимо выполнить множество операций над строками, в частности в циклах. При простой конкатенации внутри цикла будет создаваться множество временных объектов `String`, что неэффективно с точки зрения использования памяти и времени выполнения программы.

Пример использования `StringBuilder` в цикле:
```java
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i); // эффективно изменяет содержимое sb
}
String result = sb.toString(); // преобразование в строку уже после всех изменений
```

Если бы мы использовали конкатенацию строк с `+`, то каждая операция бы приводила к созданию нового объекта `String`, что неэффективно:
```java
String str = "";
for (int i = 0; i < 1000; i++) {
    str += i; // приводит к созданию нового объекта String на каждом шаге
}
```

В целом, если вы знаете, что будете выполнять множественные операции по изменению строки, рекомендуется использовать `StringBuilder`. Если же операции над строками происходят нечасто, использование `String` может быть более удобным и читаемым.

Почему нужно было помимо класса String создавать дополнительные классы по типу StringBuilder?

Потому, что String - иммутабельный класс. Чтобы конструировать строки как раз добавлены StringBuffer (в версии 1.0) и StringBuilder (в 1.5).

В данном примере строка s спокойно изменяется путем конкатенации, что аналогично sb.append

В итоге у вас каждый раз создается новый объект. Не всегда это бывает уместно.

2. Почему все методы StringBuilderнельзя было поместить в класс String, чтобы не плодить классы строк?

Потому, что это нарушает принцип единой ответственности. Так же можно заметить, что мысль не стоит на месте и со временем появляются новые методы для конструирования строк.

3. Почему s.equals(sb) равно false, если мы сравниваем только значения, а не ссылки

Потому, что вы сравниваете разные объекты. StringBuilder - это не String.
Похожие вопросы