powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Неизменность строки в java - как это?
30 сообщений из 30, показаны все 2 страниц
Неизменность строки в java - как это?
    #39362318
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне очень сложно понять как это строка неизменна в java. Нет ли по русски мануалов (статей или топиков) которые проясняют этом момент для новичков?
То есть я пишу
String s = "one ";
s = "two + " + s;
То что происходит с s? Она ведь изменилась!
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362335
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
azsxМне очень сложно понять как это строка неизменна в java. Нет ли по русски мануалов (статей или топиков) которые проясняют этом момент для новичков?
То есть я пишу
String s = "one ";
s = "two + " + s;
То что происходит с s? Она ведь изменилась!
Полагаю что происходит как в .NET, после сложения строк это уже новая строка, а старая попадает в сборщик мусора.
Для оптимизации этого там (в NET) рекомендуется не складывать тупо строки, а использовать StringBuilder.
Кстати, очень удобная вещь. Особенно когда конкатенируются разные типы данных в одну строку.
Есть такая штука в Java пока не знаю.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362336
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008 Есть такая штука в Java пока не знаю.
Спросил у Гугля... Есть, и даже называется так же!
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362338
dimonz80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
azsxМне очень сложно понять как это строка неизменна в java. Нет ли по русски мануалов (статей или топиков) которые проясняют этом момент для новичков?
То есть я пишу
String s = "one ";
s = "two + " + s;
То что происходит с s? Она ведь изменилась!

Все просто: создается новый объект String, в него копируется "two + " и "one" и s становится ссылкой на этот новый объект. Старый объект, на который указывала s ( со строкой "one ") достается GC. Как-то так...
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362352
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть:
Код: java
1.
2.
3.
4.
Sring s = "";
for (int i = 0; i < 100; i++) {
     s = s + ".";
}


Создаст мне 100 новых классов? А насколько нагружает такое создание программу? Допустим, будет программа работать в 30 потоков и вместо точки по мегабайту данных, которые то входят, то выходят из переменной. Будут тормоза?
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362355
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ой, не классов - а объектов.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362364
WGA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
WGA
Гость
azsxТо есть:
Код: java
1.
2.
3.
4.
Sring s = "";
for (int i = 0; i < 100; i++) {
     s = s + ".";
}


Создаст мне 100 новых классов? А насколько нагружает такое создание программу? Допустим, будет программа работать в 30 потоков и вместо точки по мегабайту данных, которые то входят, то выходят из переменной. Будут тормоза?Начиная с JDK 6 компилятор производит оптимизацию работы со строками. Например, под JDK 8 пример кода компилируется в следующее:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
.............................
   #1 = Methodref          #11.#31        // java/lang/Object."<init>":()V
   #2 = String             #32            //
   #3 = Class              #33            // java/lang/StringBuilder
   #4 = Methodref          #3.#31         // java/lang/StringBuilder."<init>":()V
   #5 = Methodref          #3.#34         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #6 = String             #35            // .
   #7 = Methodref          #3.#36         // java/lang/StringBuilder.toString:()Ljava/lang/String;
   #8 = Fieldref           #37.#38        // java/lang/System.out:Ljava/io/PrintStream;
   #9 = Methodref          #39.#40        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #10 = Class              #41            // Main
  #11 = Class              #42            // java/lang/Object
.............................

Так что "под капотом" все равно StringBuilder.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362369
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
azsxТо есть:
Код: java
1.
2.
3.
4.
Sring s = "";
for (int i = 0; i < 100; i++) {
     s = s + ".";
}



Создаст мне 100 новых классов? А насколько нагружает такое создание программу? Допустим, будет программа работать в 30 потоков и вместо точки по мегабайту данных, которые то входят, то выходят из переменной. Будут тормоза?

не создаст. ява штука умная и скорее всего данный цикл будет оптимизирован, а s после первой итерации попадёт в пул. и есть предположение, что в итоговом байткоде цикл вообще будет убран, но это нужно байткод смотреть, а мне лень. вот если бы ты написал
Код: java
1.
s = new String(s + ".");



тогда да, лишние 100 объектов.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362374
Фотография ponuch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WGA,

а если без println ? тьфу, что-то я протупил в предыдущем ответе :)
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362397
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Благодаря терминам нашёл https://habrahabr.ru/post/260767/ То есть получается s = s + 1; Может быть использован StringBuffer. А может и нет?
автортогда да, лишние 100 объектов.
И эти объекты сильно нагружают программу? Напомню, переменная от 1 до 100 мб, добавляем, удаляем другую до от 5 до 500 мб, работаю в 30 потоков.
авторне создаст. ява штука умная и скорее всего данный цикл будет оптимизирован
Конечно, это цикл для примера, мои циклы внутри именно обрабатывают переменную всяко разно. При этом код иногда меняется.
---
Пока я понял, что вместо String для постоянно меняющихся переменных надо создавать StringBuffer s = ""; - верно?
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362435
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Научитесь различать объекты и переменные. Объект типа String не изменился - был создан новый. Переменная типа String ссылается на новый объект. В термине immutable string речь идёт о состоянии объектов, а не о значении переменных.

2. Из-за этой фигни конкатенация строк в Java - очень дорогая операция. Для того чтобы обойти ограничения по скорости был добавлен класс StringBuffer.

3. Класс StringBuffer синхронизирован для потокобезопасности, что создаёт дополнительные накладные раходы. Поэтому был создан класс StringBuilder, так как в 99.99% случаев никто многопоточно строки не собирает.

4. Синхронизацию потом оптимизировали, так чтобы в одном потоке она работала так же быстро как без синхронизации, поэтому разницы между StringBuilder и StringBuffer уже почти нет.

5. Java компилятор оптимизировали, чтобы он вместо конкатенации строк создавал StringBuilder незаметно для разработчика. Это помогает если вы склеиваете в ряд кучу строк. Но это не помогает когда у вас есть цикл. Компилятор не такой умный чтобы вынести StringBuilder за цикл. Поэтому в циклах StringBuilder приходится использовать явно.

6. В Java 9 планируются дальнейшие оптимизации строк. В том числе и конкатенация, вроде, должна стать быстрее.

7. Если вы работаете с большим количеством текстовых данных, то иногда есть смысл отказаться от строк в пользу таких классов как Reader/Writer. Либо использовать сторонние библиотеки, которые работают с char[].
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362447
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо.
авторЛибо использовать сторонние библиотеки, которые работают с char[].
Назовите, пожалуйста, хоть одно название, чтобы сравнить с потоками.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39362473
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
azsxПока я понял, что вместо String для постоянно меняющихся переменных надо создавать StringBuffer s = ""; - верно?

Почти. Лучше StringBuilder. Почитай про разницу.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363001
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
azsx,

можете массив byte/char (и пул с ними) использовать как в старом добром С для хранения временных данных до момемта создания строки (объекта), потом этим конструктором создадите String: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#String(byte [],%20int,%20int)

Но String объекты все равно будут улетать в мусорку как только вы уберете reference на них от переменной.
Внутри строка использует массив char, можно получить reference на него и поменять содержимое строки без изменения reference на нее. Это конечно извращение и акробатика но по почему не пофантазировать?

На Stackoverflow нашелся пример хака:
(modfy(String) можете поменять на modify(char[], int length) или подобие. Копировать содержимое буфере скорее всего все равно придется так что особой экономии не получится)
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
public class MutableStringTest {


    // http://stackoverflow.com/questions/11146255/how-to-create-mutable-java-lang-string#11146288
    @Test
    public void testMutableString() throws Exception {
        final String s = createModifiableString();
        System.out.println(s);
        modify(s);
        System.out.println(s);
    }

    private final AtomicReference<CharBuffer> cbRef = new AtomicReference<CharBuffer>();
    private String createModifiableString() {
        Charset charset = new Charset("foo", null) {
            @Override
            public boolean contains(Charset cs) {
                return false;
            }

            @Override
            public CharsetDecoder newDecoder() {
                CharsetDecoder cd = new CharsetDecoder(this, 1.0f, 1.0f) {
                    @Override
                    protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
                        cbRef.set(out);
                        while(in.remaining()>0) {
                            out.append((char)in.get());
                        }
                        return CoderResult.UNDERFLOW;
                    }
                };
                return cd;
            }

            @Override
            public CharsetEncoder newEncoder() {
                return null;
            }
        };
        return new String("abc".getBytes(), charset);
    }
    private void modify(String s) {
        CharBuffer charBuffer = cbRef.get();
        charBuffer.position(0);
        charBuffer.put("xyz");
    }

}
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363019
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
azsxспасибо.
авторЛибо использовать сторонние библиотеки, которые работают с char[].
Назовите, пожалуйста, хоть одно название, чтобы сравнить с потоками.

org.apache.commons.collections.primitives.ArrayCharList;
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363034
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174azsxспасибо.
пропущено...

Назовите, пожалуйста, хоть одно название, чтобы сравнить с потоками.

org.apache.commons.collections.primitives.ArrayCharList;

В дополнение - как то пользовался Trove, может устарела а может и нет, int работали нормально, поддержка char есть, гляньте может прогодится
http://trove4j.sourceforge.net/javadocs/gnu/trove/list/TCharList.html

По сравнению с коллекциами Java, расход памяти примерно в 3 раза ниже у Trove.

Обзор от 2015 года Large HashMap overview: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove – January 2015 version в нем хвалят http://fastutil.di.unimi.it/

Вроде в Guava есть что то по примитивам но увы не помню точно.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363768
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почитал разницу между StringBuilder и StringBuffer. Непонятно:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
class Test {
    StringBuilder output = new StringBuilder(); 
    //StringBuffer output = new StringBuffer(); 
        
        
        void test () {
    output.append("1234567890123456"); 
    
    
    System.out.println("l " + output.length());
    System.out.println("p " + output.capacity());
        
    
    output.append("7"); 
    System.out.println("l " + output.length());
    System.out.println("p " + output.capacity());
    
    // не понимаю
    
    output.deleteCharAt(0);
    System.out.println("l " + output.length());
    System.out.println("p " + output.capacity());

    output.deleteCharAt(output.length()-1);
    System.out.println("l " + output.length());
    System.out.println("p " + output.capacity());
    
    System.out.println(output);
        }
}


l 16
p 16
l 17
p 34
l 16
p 34
l 15
p 34
234567890123456
Вопросы:
0. Вы меня точно не обманываете? Почему все программисты на java пишут String, а не StringBuffer если он изначально настолько лучше? Может на самом деле компилятор всё это преобразует в builder без явных указаний?
1. Что такое 16? utf 8 может быть от 2 до 4 байт, если не английские символы. То есть мне надо 16 делить на 2? Например, в среднем главная занимает 23 кб, мне надо выделять (23*1024) как на диске или ((23*1024)*2)? Надо ли ваще выделять память самому?
2. Почему последние 2 вывода не чистят память? Как снова вернуть 16 байт?
3. Я абсолютно точно понял, что buffer надо юзать, когда строка public и сразу много потоков в неё пишет, стирает. А builder, когда всё в одном объекте.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363840
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
azsxНадо ли ваще выделять память самому?
интересно, каким способом, - сходить в магазин докупить ram?
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363952
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторинтересно, каким способом
StringBuilder output = new StringBuilder(23552);
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363980
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
azsx,

это только если ты точно занешь, что конечная строка будет именно такой длинны

если же понадобится записать 23552 +1, то размерность будет автоматически увеличена на ((23552 +1)* 2) + 2

т.е. если не указана начальная емкость стрингбилдера, то каждый раз для увенличения емкости понадобится
дополнительное время на это увеличение. насколько большое? наверное зависит от размера содержимого и может быть игра не стоит свеч при определенных значениях, т.е. может сущ-я разница будет наблюдаться при значениях, которые тебе не нужны...

azsxЧто такое 16?

начальная емкость стрингбилдера
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363983
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174,
можно этим временем пренебречь. проверял, особой разницы не заметил.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363984
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вадяrema174,
можно этим временем пренебречь. проверял, особой разницы не заметил.

тогда можно пренебречь конструктором с начальной емкостью
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39363986
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
хотя конечно, память экономней будет использоваться при конструкторе с размерностью, но если уж нужна такая экономия имеет смысл, то нужно смотреть в сторону сторонних библиотек, которые работают с char[]
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364013
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Докину чужие Шипилевские 5 копеек.

YouTube Video
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364071
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
именно по такой формуле? ((23552 +1)* 2) + 2
А где вы формулу прочитали?
А как всё таки память в переменной освобождать?
Видео скоро посмотрю.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364086
rema174
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
azsxименно по такой формуле? ((23552 +1)* 2) + 2
уточнение: на самом деле увеличиваться будет по формуле ((х)*2) + 2, где х - исходная емкость

azsxгде вы формулу прочитали?
google

azsxА как всё таки память в переменной освобождать?
присвоить переменной null
чтобы понимать что же произойдет дальше - читай про GC
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364100
azsx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо вот теперь стало понятно. К сожалению, про gc мне пока рановато читать.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364113
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rema174azsxименно по такой формуле? ((23552 +1)* 2) + 2
уточнение: на самом деле увеличиваться будет по формуле ((х)*2) + 2, где х - исходная емкость

azsxгде вы формулу прочитали?
google

azsxА как всё таки память в переменной освобождать?
присвоить переменной null
чтобы понимать что же произойдет дальше - читай про GC
В исходниках, увеличение массива char происходит по формуле (х + 1)*2. Остальными байтами в классе пренебрегаем для больших строк.

http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/tip/src/share/classes/java/lang/AbstractStringBuilder.java
Код: java
1.
2.
void expandCapacity(int minimumCapacity) {
        int newCapacity = (value.length + 1) * 2;


Хотя нет, в 8й версия непонятная оптимизация произошла в той же фунции:
http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/lang/AbstractStringBuilder.java
Код: java
1.
2.
void expandCapacity(int minimumCapacity) {
     int newCapacity = value.length * 2 + 2;


Могли бы бинарные операции с маской использовать << 1 | 1;

PS Кстати проверка переполнение int странная
Код: java
1.
2.
3.
if (newCapacity < 0) {
     newCapacity = Integer.MAX_VALUE;
} 


может быть имело смысл кинуть exception а проверку делать выше? А то втихую выделили или проигнорировали запрос на увеличения буфера для очень больших строк. Все таки переменная называется minimumCapacity и если минимум не обеспечивается, желательно бросить ошибку чем потом падать по array out of bounds.
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364125
uid unique
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uid unique Все таки переменная называется minimumCapacity и если минимум не обеспечивается, желательно бросить ошибку чем потом падать по array out of bounds.
пардон, глупость сказал там же индекс int, надо больше отдыхать ;-)
...
Рейтинг: 0 / 0
Неизменность строки в java - как это?
    #39364610
Alexey Tomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
azsx0. Вы меня точно не обманываете? Почему все программисты на java пишут String, а не StringBuffer если он изначально настолько лучше? Может на самом деле компилятор всё это преобразует в builder без явных указаний?

Храниить строки надо в string - он для этого лучше. Создавать- билдером.

azsx1. Что такое 16? utf 8 может быть от 2 до 4 байт, если не английские символы. То есть мне надо 16 делить на 2? Например, в среднем главная занимает 23 кб, мне надо выделять (23*1024) как на диске или ((23*1024)*2)? Надо ли ваще выделять память самому?

16 символов.

azsx2. Почему последние 2 вывода не чистят память? Как снова вернуть 16 байт?

Билдер- чтобы собрать строку и выкинуть билдер. Поэтому он память не чистит- он весь в мусор.

azsx3. Я абсолютно точно понял, что buffer надо юзать, когда строка public и сразу много потоков в неё пишет, стирает. А builder, когда всё в одном объекте.

Даже в приватное поле без доступа снаружеиможет ломиться много потоков.
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / Неизменность строки в java - как это?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]