Задать вопрос
@MishaXXL

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

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

Из учебника.
Класс String аналогичен классу StringBuilder за исключением того, что он является неизменяемым.


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

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

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

public class MyClass {
    public static void main(String args[]) {
        String s = "Hello";
        s += " Java!";
        
        String s2 = new String("Hello Java!");
        
        StringBuilder sb = new StringBuilder("Hello");
        sb.append(" Java!");
        
        System.out.println(s.equals(s2));
        System.out.println(s.equals(sb));
    }
}


Наткнулся на код из статьи и не понял для чего тут используют StringBuilderс append, а не просто Stringс конкатенацией, ведь после всё равно превращают его в String.
Для чего здесь эти манипуляции с классами String и почему здесь не обошлись без StringBuilder?
StringBuilder requestBuilder = new StringBuilder();
String line;
while (!(line = br.readLine()).isBlank()) {
   requestBuilder.append(line + "\r\n");
}
String request = requestBuilder.toString();
String[] requestsLines = request.split("\r\n");


Ссылка на статью
https://dev.to/mateuszjarzyna/build-your-own-http-...
  • Вопрос задан
  • 185 просмотров
Подписаться 1 Простой 2 комментария
Решение пользователя My1Name К ответам на вопрос (5)
@My1Name
Массив — структура данных хранящая набор значений, в простейшем случае фиксированой длины. Массивы не всегда удобно использовать, поэтому ряд языков программирования поддерживают динамические массивы и, Java один из таких языков. ⇨ Данные типа String - это массив char-ов в таких языках как Pascal, C, C++, Java и др.. В Java все строковые литералы помещаются в специальный объект (класс) под который выделяется память, а уже адрес этого объекта помещается в переменную, под которую тоже выделяется память. Java коллекции расширяют возможности работы с массивами и это пожалуй ответ на все ваши вопросы.
https://javarush.com/quests/lectures/questsyntaxpr...

Например, если вы заполните HashSet<String> то сможете проверить наличие определенного String-а в массиве строк, заменив s.equals(sb) на list.contains(sb) Такой код будет работать в оперативной памяти используя hashcode (32 битный идентификатор объекта). Это работает быстро и эффективно, так как числовые значения гораздо легче и быстрей сравнить. Однако, каждая строка будет представлять собой отдельный объект и занимать свою ячейку в памяти.

При конкатенации происходит приблизительно то же самое: Создаётся массив, где каждая строка - это отдельный объект (массив) разного размера. В момент конкатенации создаётся новый объект типа String с размером == сумма двух String и + 2 объекта "склеивания". А если у нас таких операций (итераций) много, то велика вероятность получить outofmemoryerror прежде чем GC (сборщик мусора) успеет собрать все созданные объекты.

В отличие от языков C/C++ в Java нет доступа к памяти. Программист не может удалить "cell memory" хранящую ссылку на объект и в этом нет необходимости. Эту работу выполняет Garbage collectors (GC) а вся работа с памятью происходит только через Java-машину (JVM).

С целью экономии памяти, начиная с версии JDK 5 для работы со String-ами в Java имеется StringBuilder. Таким образом у нас всегда один объект, который пропорционально заполненяет StringBuffer, подобно HashSet<String> но с одной ("резиновой") ячейкой в памяти.
https://docs.oracle.com/javase/8/docs/api/java/lan...
Ответ написан