Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Максимальная длина String


Автор: batigoal 4.2.2005, 16:41
Есть ли какое-нибудь ограничение на длину строки String? Или я могу ее наращивать, как обычный массив, пока память не кончится?

Автор: LSD 4.2.2005, 19:07
Integer.MAX_VALUE. Массив большего размера не создать.

Автор: batigoal 7.2.2005, 10:33
Ну что ж, вполне достаточно smile
Спасибо

Автор: Zandr 22.2.2005, 09:57
Кста....... String наращивать нельзя smile
Если пишем
Код

String s1 = "aaa";
String s1 += "bbb";

то на самом деле происходит примерно следующее:
Код

String s1 = new String( "aaa");
StringBuffer tmpSb = new StringBuffer( s1);
tmpSb.append( new String ( "bbb"));
s1 = tmpSb.toString();

Порой встречается такое:
Код

String s1=....
while(.....) {
   ....
   s1 = s1 + ......
   ....
}

По умолчанию не помню сколько Java выделяет памяти... Что-то около 60-80 метров, и при таком стиле наращивания длина строки не может превысить 30-40 метров (мы не считаем что память используется не только для наших строк). Так что работаем через StringBuffer, причем желательно угадать заранее максимальную длину строки и при создании StringBuffer'а её указать.
И напоследок вопрос: зачем такие строки? Если с большими файлами работаешь - можно попытаться найти альтернативу в nio. Можно строчки поразбить и хранить их в List'е или еще как-нить.

Автор: Domestic Cat 22.2.2005, 10:29
ЗЫ

Цитата(Zandr @ 22.2.2005, 00:57)
String s1 = new String( "aaa");
StringBuffer tmpSb = new StringBuffer( s1);
tmpSb.append( new String ( "bbb"));
s1 = tmpSb.toString();


В Java 1.5 используется StringBuilder вместо StringBuffer.

Автор: batigoal 22.2.2005, 14:23
Zandr
Спасибо за совет. Знал же, а не подумал. Учту.
Это может привести к выделению памяти под кучу строк без ее освобождения?

Domestic Cat
Цитата(Domestic @ 22.2.2005, 10:29)
В Java 1.5 используется StringBuilder вместо StringBuffer

Это аналогичный заменитель или есть качественная разница?

Автор: Domestic Cat 22.2.2005, 18:54
StringBuilder быстрее, т.к. не синхронизирован. Он используется там, где гарантированно будет работать 1 тред.

Автор: batigoal 22.2.2005, 19:04
Т.е. только один тред будет работать с моей строкой, да? А если в каждом потоке будет своя строка обрабатываться, то его можно использовать, верно?

Автор: Domestic Cat 22.2.2005, 19:25
Конечно.

Автор: Zandr 26.2.2005, 12:13
Цитата
Это может привести к выделению памяти под кучу строк без ее освобождения?

Нет, память то будет освобождаться, просто видел один раз как для JME приложения кто-то свою функцию рекомендовал для загрузки файла в кодировке win-1251. Так там в цикле к строчке прибавлялась буковка. Автор функции (а может и не автор) еще заметил, что она медленно работает... Я вот тоже подумал с чего бы это smile
Просто это называется memory burning, или как-то так, когда без толку создается-уничтожается много объектов, когда можно было бы обойтись одним. Кстати, если не задать StringBuffer'у достаточной начальной емкости, то получим примерно тот же эффект.

Автор: batigoal 26.2.2005, 21:17
Цитата(Zandr @ 26.2.2005, 12:13)
Кстати, если не задать StringBuffer'у достаточной начальной емкости, то получим примерно тот же эффект.

Плохо. Строка формируется по записям из БД. В зависимости от настрек пользователя некоторые таблицы загружаются, некоторые нет, т.е. невозможно предугадать необходимую емкость.

Автор: LSD 27.2.2005, 00:04
Цитата(Zandr @ 26.2.2005, 12:13)
если не задать StringBuffer'у достаточной начальной емкости, то получим примерно тот же эффект

StringBuffer при расширении, удваивает буфер. Так что тут ничего особо страшного не будет. Конечно если есть возможность спрогнозировать размер лучше ей пользоваться, но если нет, то StringBuffer работает достаточно рационально.

Автор: Sardar 27.2.2005, 00:46
Еще лучше организовать свою структуру на связанных контейнерах строк. Если нужно отредатктировать подстроку разбитую на два контейнера(replace например), то тогда обьеденяем оба контейнера в один. Память при таком подходе практически не засоряется и почти не хаваем лишнего.

Для выборок из БД лучше такие быстрые структуры как HAT.

Автор: batigoal 27.2.2005, 11:17
Цитата(Sardar @ 27.2.2005, 00:46)
Для выборок из БД лучше такие быстрые структуры как HAT

Что такое НАТ?
У меня выборка происходит не напрямую, а через объект.

Автор: Sardar 27.2.2005, 12:01
http://algolist.manual.ru/download.php?path=/ds/hat_ru.zip очень простая и главная её задача эффективно увеличиватся в размерах. Естественно есть куча ограничений, потому и смотрим что конкретно нужно. Обычно выборка из БД это забивание контейнера даными и потом уже обработка. Если запрос не сортирующий и не групирующий, то можно использовать простые быстрые связанные списки, иначе разного рода деревья, позволяющие после набивки без дополнительных усилий представить как надо выборку. Нагрузка на процессор и память при таком подходе минимальная.

Цитата(Lamer @ 4.2.2005, 15:41)
Или я могу ее наращивать, как обычный массив, пока память не кончится?

Для наращивания создай свою стуктуру похожую на связанный список, хранить ты будешь строки. Естественно предлагается интерфейс строки + метод normalize, который разом склеивает все строки в одну для последующей быстрой обработки, если надо. При таком подходе память продублируется в конце(что не необходимо), в момент работы лишнего мусора не будет.

Автор: batigoal 27.2.2005, 16:56
C хэш-таблицами я, в общем, знаком. Спасибо за ссылку, почитаю.

Автор: Sardar 27.2.2005, 17:17
Цитата(Lamer @ 27.2.2005, 15:56)
C хэш-таблицами я, в общем, знаком

Это не хешь таблицы, это эффективная замена Vector'у или ArrayList.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)