Прежде всего, чтобы использовать автоматическую интернирование строк, все строки должны быть
неизменяемый, что делает многие задачи обработки строк сложнее, чем
они должны быть. (И да, я слышал все аргументы за
неизменность в целом. Дело не в этом.)
Это правда, и строка неизменна в Java. Я не уверен, что это плохо. Не вдаваясь в неизменность и изменяемость, мне нравится думать, что это отличный дизайн из-за кеширования и гораздо большей простоты, к которой я не буду подходить.
Каждый раз, когда создается новая строка, она должна быть проверена на соответствие
таблица интернирования строк, которая является как минимум операцией O (N). Так что если
отношение сравнения равенства строк к созданию новой строки
довольно высока, маловероятно, что сэкономленное время является положительным
значение.
Не совсем O (n). Вы можете создавать хеш-карты и / или другие структуры данных, которые приведут это к почти постоянному поиску.
Если в таблице равенства строк используются сильные ссылки, строки будут
никогда не собирать мусор, когда он больше не нужен, таким образом
тратить память. С другой стороны, если таблица использует слабые ссылки,
тогда строковому классу требуется какой-то финализатор для удаления
строка из таблицы, тем самым замедляя процесс GC. (Которая могла бы
быть довольно значительным, в зависимости от того, как таблица строк интерна
реализованы. В худшем случае удаление элемента из хеш-таблицы может
требует O (N) перестроить всю таблицу под определенным
обстоятельства.)
Вы правы в этом, и я бы с вами согласился. Кроме того, я чувствую, что обработка GC и незначительна. Преимущества в долгосрочной перспективе гораздо полезнее, чем сборщик мусора, выполняющий дополнительную проверку. Я не уверен, что вы имеете в виду O (n) для удаления из хеш-таблицы. Большинство операций с хеш-таблицами: O (1)
Итак, в целом, я думаю, что вы предполагаете, что большинство операций являются линейными. Но поиск строк ближе к постоянному времени. Таким образом, этот подход будет иметь незначительную потерю производительности, но огромный выигрыш в памяти. Что, я бы сказал, того стоит.
Вот хорошая цитата о том, что на самом деле происходит и как это экономит память.
Для экономии памяти (и ускорения тестирования на равенство) Java поддерживает
«Интернирование» струн. Когда метод intern () вызывается на
String, поиск выполняется на таблице интернированных строк. Если
Строковый объект с тем же содержимым уже находится в таблице,
ссылка на строку в таблице возвращается. В противном случае
Строка добавляется в таблицу и возвращается ссылка на нее.