Вы описываете разные проблемы IMO, но ни одна из них не является "реальной" проблемой.
Во-первых, это тот факт, что StringBuilder
выделяет слишком много места - это редко (если вообще когда-либо)проблема на практике. Подумайте о any List/Set/Map
- они делают одно и то же, могут выделять слишком много, но когда вы удаляете элемент, они не уменьшают внутреннее хранилище. У них есть метод для этого;но так же StringBuilder
:
trimToSize
Из-за «компактных строк» построитель строк должен преобразовывать свои байты в символы.
StringBuilder
знает что он хранит через поле coder
в AbstractStringBuilder
, которое он расширяет. С компактными строками String
теперь хранит свои данные в byte[]
(он тоже имеет coder
), поэтому я не понимаю, где это преобразование из byte[]
в char[]
должно происходить. StringBuilder::toString
определяется как:
public String toString() {
// Create a copy, don't share the array
return isLatin1() ? StringLatin1.newString(value, 0, count)
: StringUTF16.newString(value, 0, count);
}
Обратите внимание на проверку isLatin1
- StringBuilder
знает, какой тип данных у него внутри;таким образом, невозможно преобразование, когда это возможно.
Я предполагаю, что следующим образом:
При вызове одного из конструкторов String символы должны быть снова сжаты до байтов
Вы имеете в виду:
char [] some = ...
String s = new String(some);
Я не знаю, почему вы снова используете , но, возможно, я что-то упустил. Просто обратите внимание, что это преобразование из char[]
в byte[]
действительно должно произойти, но это довольно тривиально (последние 8 бит должны быть пустыми), и как только один char
не удовлетворяет предварительному условию,все обращение выручено. Таким образом, вы либо сохраняете все символов в LATIN1
, либо нет.