Почему String.intern() возвращает разные экземпляры одинаковых строк?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Почему String.intern() возвращает разные экземпляры одинаковых строк?

Сообщение Anonymous »

Я заметил поведение String.intern(), которое пытаюсь понять. Кажется, это противоречит документации этого метода.
private static String buildSampleString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10; i++) {
builder.append((char)(i + 'a'));
}
return builder.toString();
}

private static void performTest(String a) {
String b = buildSampleString().intern();
System.out.println("a vs. b: " + (a == b) + ", " + a.equals(b));
System.out.println(b + ": " + System.identityHashCode(b));
}

public static void main(String[] args) {
String a = buildSampleString();
performTest(a);
performComputation(); // see below for details
performTest(a);
}

buildSampleString() создает новые одинаковые строки при каждом вызове. Один из этих экземпляров, , сохраняется на протяжении всего времени существования программы. PerformTest(a) создает новый b, интернирует его, затем сравнивает с a (как на идентичность, так и на равенство), и, как и ожидалось, они равны, но не идентичны. Последнее связано с тем, что не был интернирован.
В документации для String.intern() сказано:
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

Из-за транзитивности методаquals() две строки b равны, поэтому, согласно документации, они идентичны. Таким образом, вызов System.identityHashCode(b) должен возвращать то же значение. Иногда это так и происходит, но только если метод PerformComputation() не выполняет слишком много работы в середине. Если это действительно работает слишком усердно - и я подозреваю, что это связано с перебором кучи - тогда System.identityHashCode(b) возвращает другое значение во второй раз... что должно быть невозможно, если документация верна.
Это код для выполнения вычислений:
private static final Random random = new Random();

private static String randomString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10000000; i++) {
builder.append((char)(random.nextInt(127 - 32) + 32));
}
return builder.toString();
}

private static void performComputation() {
for (int i = 0; i < 10; i++) {
String s = randomString();
System.out.println(s.substring(0, 3) + "..." + s.substring(s.length() - 3));
}
}

Если я изменю цикл с 10000000 итераций на 10, я получу тот же хэш идентификатора.
Что именно здесь происходит?
Если я изменю цикл с 10000000 итераций на 10, то получу тот же хэш идентификатора.
Что именно здесь происходит?
p>
Изменить: полный код для воспроизведения поведения:
import java.util.Random;

public class Main {

private static final Random random = new Random();

private static String randomString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10000000; i++) {
builder.append((char)(random.nextInt(127 - 32) + 32));
}
return builder.toString();
}

private static void performComputation() {
for (int i = 0; i < 10; i++) {
String s = randomString();
System.out.println(s.substring(0, 3) + "..." + s.substring(s.length() - 3));
}
}

// ----------------------------------------------------------------------------------------------------------------

private static String buildSampleString() {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 10; i++) {
builder.append((char)(i + 'a'));
}
return builder.toString();
}

private static void performTest(String a) {
String b = buildSampleString().intern();
System.out.println("a vs. b: " + (a == b) + ", " + a.equals(b));
System.out.println(b + ": " + System.identityHashCode(b));
}

public static void main(String[] args) {
String a = buildSampleString();
performTest(a);
performComputation();
performTest(a);
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... al-strings
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»