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

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


Создаст мне 100 новых классов? А насколько нагружает такое создание программу? Допустим, будет программа работать в 30 потоков и вместо точки по мегабайту данных, которые то входят, то выходят из переменной. Будут тормоза?
...
Рейтинг: 0 / 0
08.12.2016, 11:05
    #39362355
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
ой, не классов - а объектов.
...
Рейтинг: 0 / 0
08.12.2016, 11:14
    #39362364
WGA
WGA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
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
08.12.2016, 11:20
    #39362369
ponuch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
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
08.12.2016, 11:22
    #39362374
ponuch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
WGA,

а если без println ? тьфу, что-то я протупил в предыдущем ответе :)
...
Рейтинг: 0 / 0
08.12.2016, 11:41
    #39362397
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
Благодаря терминам нашёл https://habrahabr.ru/post/260767/ То есть получается s = s + 1; Может быть использован StringBuffer. А может и нет?
автортогда да, лишние 100 объектов.
И эти объекты сильно нагружают программу? Напомню, переменная от 1 до 100 мб, добавляем, удаляем другую до от 5 до 500 мб, работаю в 30 потоков.
авторне создаст. ява штука умная и скорее всего данный цикл будет оптимизирован
Конечно, это цикл для примера, мои циклы внутри именно обрабатывают переменную всяко разно. При этом код иногда меняется.
---
Пока я понял, что вместо String для постоянно меняющихся переменных надо создавать StringBuffer s = ""; - верно?
...
Рейтинг: 0 / 0
08.12.2016, 12:03
    #39362435
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
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
08.12.2016, 12:17
    #39362447
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
спасибо.
авторЛибо использовать сторонние библиотеки, которые работают с char[].
Назовите, пожалуйста, хоть одно название, чтобы сравнить с потоками.
...
Рейтинг: 0 / 0
08.12.2016, 12:41
    #39362473
Alexey Tomin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
azsxПока я понял, что вместо String для постоянно меняющихся переменных надо создавать StringBuffer s = ""; - верно?

Почти. Лучше StringBuilder. Почитай про разницу.
...
Рейтинг: 0 / 0
08.12.2016, 21:51
    #39363001
uid unique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
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
08.12.2016, 22:20
    #39363019
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
azsxспасибо.
авторЛибо использовать сторонние библиотеки, которые работают с char[].
Назовите, пожалуйста, хоть одно название, чтобы сравнить с потоками.

org.apache.commons.collections.primitives.ArrayCharList;
...
Рейтинг: 0 / 0
08.12.2016, 22:57
    #39363034
uid unique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
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
09.12.2016, 18:26
    #39363768
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
Почитал разницу между 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
09.12.2016, 20:23
    #39363840
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
azsxНадо ли ваще выделять память самому?
интересно, каким способом, - сходить в магазин докупить ram?
...
Рейтинг: 0 / 0
10.12.2016, 03:01
    #39363952
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
авторинтересно, каким способом
StringBuilder output = new StringBuilder(23552);
...
Рейтинг: 0 / 0
10.12.2016, 09:15
    #39363980
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
azsx,

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

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

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

azsxЧто такое 16?

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

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

YouTube Video
...
Рейтинг: 0 / 0
10.12.2016, 14:28
    #39364071
azsx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Неизменность строки в java - как это?
именно по такой формуле? ((23552 +1)* 2) + 2
А где вы формулу прочитали?
А как всё таки память в переменной освобождать?
Видео скоро посмотрю.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Неизменность строки в java - как это? / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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