Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Быстрый способ сравнить строки 
:(
    Опции темы
Skipy
Дата 24.9.2010, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

Репутация: 6
Всего: 16



Цитата(Evgeni68 @ 24.9.2010,  19:45)
Цитата(danilka @ 22.9.2010,  17:46)
То есть Вы хотите сказать что можно создать строку так чтобы в пуле не было соответствующего ей объекта intern()?

Код

String test = new String("Hello world");


Данный код создаст объект типа String не помещая строку в пул.

Ну, сам строковый литерал "Hello world!" в пуле таки будет. Так что при сравнении по equals с вновь созданной строкой вернется именно он. Не совсем удачный пример.

А вот так - строки точно не будет в пуле (разве что случайно такая окажется smile):

Код

byte[] bytes = ...;
String str = new String(bytes, encoding);





--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
Evgeni68
Дата 24.9.2010, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 9.7.2007

Репутация: 2
Всего: 3



Цитата(Skipy @ 24.9.2010,  20:05)
Ну, сам строковый литерал "Hello world!" в пуле таки будет. Так что при сравнении по equals с вновь созданной строкой вернется именно он. Не совсем удачный пример.

Да, действительно, пример не совсем удачный.
Но смысл от того что литерал будет в пуле?

Код

String test1 = "test";
String test2 = new String("test");
        
System.out.println(test1 == test2);


Выводом будет FALSE. Метод equals в классе String сначала проверяет равенство ссылок, а затем обычное сравнение строк по символам. В итоге никакого преимущества в скорости от того, что литерал в пуле - нет.

Или я чего-то не допонимаю? Поправьте.

Это сообщение отредактировал(а) Evgeni68 - 25.9.2010, 09:49
PM MAIL   Вверх
Skipy
Дата 27.9.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

Репутация: 6
Всего: 16



Цитата(Evgeni68 @ 24.9.2010,  22:10)
Но смысл от того что литерал будет в пуле?

Код

String test1 = "test";
String test2 = new String("test");
        
System.out.println(test1 == test2);


Выводом будет FALSE. 

Код

String test1 = "test";
String test2 = new String("test").intern();
        
System.out.println(test1 == test2);


Так лучше? А то Вы как-то упустили, что test2 указывает не на тот экземпляр, который в пуле.


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
danilka
Дата 28.9.2010, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 15.1.2010

Репутация: нет
Всего: нет



Цитата(Skipy @  24.9.2010,  20:05 Найти цитируемый пост)
А вот так - строки точно не будет в пуле (разве что случайно такая окажется smile):

byte[] bytes = ...;
String str = new String(bytes, encoding);


Тут Вы имеете ввиду пул строковых литералов или пул intern()?
PM MAIL   Вверх
Skipy
Дата 28.9.2010, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

Репутация: 6
Всего: 16



Цитата(danilka @ 28.9.2010,  09:43)
Тут Вы имеете ввиду пул строковых литералов или пул intern()?

Пул - он один. Еще раз объясняю - строковые литералы существуют только в исходном коде. При компиляции они помещаются в пул строк. И в него же во время исполнения помещаются отсутствующие в нем строки при вызове на них метода intern().


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
Evgeni68
Дата 28.9.2010, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 9.7.2007

Репутация: 2
Всего: 3



Цитата(Skipy @ 27.9.2010,  12:02)
Цитата(Evgeni68 @ 24.9.2010,  22:10)
Но смысл от того что литерал будет в пуле?

Код

String test1 = "test";
String test2 = new String("test");
        
System.out.println(test1 == test2);


Выводом будет FALSE. 

Код

String test1 = "test";
String test2 = new String("test").intern();
        
System.out.println(test1 == test2);


Так лучше? А то Вы как-то упустили, что test2 указывает не на тот экземпляр, который в пуле.

Так гораздо лучше! Просто я хотел сказать, что создавать новый инстанс строки, передавая в конструктор литерал - мягко говоря не рационально.
PM MAIL   Вверх
danilka
Дата 29.9.2010, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 15.1.2010

Репутация: нет
Всего: нет



Цитата(Skipy @  28.9.2010,  11:54 Найти цитируемый пост)
Пул - он один. Еще раз объясняю - строковые литералы существуют только в исходном коде. При компиляции они помещаются в пул строк. И в него же во время исполнения помещаются отсутствующие в нем строки при вызове на них метода intern(). 


То есть правильно ли я понял?
Представим что каждая из приведенных ниже строк кода выполняется в новом приложении (пул строк пустой)

Код

String s = "test"; //строка "test" помещяется в пул
String s = ss.intern(); //строка с аналогичным ss контентом помещается в пул (если ее там еще не было)
String s = new String("test"); //строка "test" НЕ помещяется в пул

PM MAIL   Вверх
Skipy
Дата 29.9.2010, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

Репутация: 6
Всего: 16



Цитата(Evgeni68 @ 28.9.2010,  21:39)
Просто я хотел сказать, что создавать новый инстанс строки, передавая в конструктор литерал - мягко говоря не рационально.


Ага. И Вы на эти грабли наступили...

Рассказываю.

Допустим, у Вас есть строка. Большая, в несколько тысяч символов. Вы выбираете подстроку, символов 10. Исходная строка выбрасывается. Вопрос. Освобождается ли память, которую занимала эта подстрока?

А вот не освобождается! В качестве базы строки берется текущий массив char-ов. И просто выставляется смещение и длина. Но при этом ВСЯ исходная строка, фактически, остается в памяти. Это оптимизация, чтобы избежать копирования (и память дополнительная нужна, и время).

А вот конструктор String(String) - он КОПИРУЕТ строку. Т.е. если Вы результаты Вашего substring передадите в копирующий конструктор, несмотря на внешнюю бессмысленность этого действия, - у Вас останется массив из нужных 10 символов. А исходный массив соберется как мусор, если Вы убъете на него ссылки.

Так что да, создавать строку на основе литерала прямо в коде - нерационально, если только Вы не хотите, чтобы ссылка была не на объект, находящийся в пуле. Но копирующий конструктор сам по себе - бывает весьма полезен.

Добавлено @ 13:35
Цитата(danilka @ 29.9.2010,  09:43)
Код

String s = "test"; //строка "test" помещяется в пул
String s = ss.intern(); //строка с аналогичным ss контентом помещается в пул (если ее там еще не было)
String s = new String("test"); //строка "test" НЕ помещяется в пул

Да.

Да.

Нет. "test" помещается в пул - ибо есть строковый литерал. s - по значению в пуле будет, ибо создана на основе литерала. Т.е. вызов s.intern() не приведет к помещению новых данных в пул, а вернет ссылку на "test". А вот ссылка на s - не будет совпадать со сcылкой на "test", т.е.  результатом (s =="test") будет false.

Это сообщение отредактировал(а) Skipy - 29.9.2010, 13:37


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
Evgeni68
Дата 29.9.2010, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 9.7.2007

Репутация: 2
Всего: 3



Цитата(Skipy @  29.9.2010,  13:31 Найти цитируемый пост)
Так что да, создавать строку на основе литерала прямо в коде - нерационально, если только Вы не хотите, чтобы ссылка была не на объект, находящийся в пуле. Но копирующий конструктор сам по себе - бывает весьма полезен.


Спасибо, очень полезно. О копирующем конструкторе не задумывался smile .
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1200 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.