Я решил написать односвязный список, и у меня был план сделать внутреннюю структуру узлов неизменной.
Я столкнулся с загадкой, хотя. Скажем, у меня есть следующие связанные узлы (из предыдущих add
операций):
1 -> 2 -> 3 -> 4
и сказать, что я хочу добавить 5
.
Чтобы сделать это, так как узел 4
является неизменным, мне нужно создать новую копию 4
, но заменить его next
поле новым узлом, содержащим 5
. Проблема сейчас в том, чтобы 3
ссылаться на старое 4
; тот, без добавления 5
. Теперь мне нужно скопировать 3
и заменить его next
поле для ссылки на 4
копию, но теперь 2
ссылается на старый 3
...
Или, другими словами, чтобы добавить, кажется, что весь список нужно скопировать.
Мои вопросы:
Правильно ли мое мышление? Есть ли способ сделать дополнение, не копируя всю структуру?
Видимо "Эффективная Java" содержит рекомендацию:
Классы должны быть неизменяемыми, если только нет веской причины сделать их изменяемыми ...
Это хороший случай для изменчивости?
Я не думаю, что это дубликат предлагаемого ответа, так как я не говорю о самом списке; очевидно, что он должен быть изменяемым, чтобы соответствовать интерфейсу (без необходимости делать что-то вроде внутреннего хранения нового списка и извлечения его через геттер. Однако, подумав, даже это потребует некоторой мутации; он просто будет сведен к минимуму). Я говорю о том, должны ли внутренности списка быть неизменными.
CopyOnWritexxx
классы, используемые для многопоточности. Никто не ожидает, что коллекции действительно будут неизменными (хотя это создает некоторые причуды)