Кейс: subList изменил исходный список

Ситуация

При перестановке элементов я получил диапазон списка через subList() и добавил в него другие элементы. Неожиданно вырос не только временный диапазон, но и исходный список. Следующая нумерация стала неверной.

Причина

List.subList(from, to) возвращает представление исходного списка, а не независимую коллекцию.

List<String> source = new ArrayList<>(
        List.of("a", "b", "c", "d")
);
List<String> window = source.subList(1, 3);
 
window.add("x");
 
System.out.println(source); // [a, b, c, x, d]

Структурное изменение представления меняет исходный список. Обратная связь тоже действует: несогласованное изменение source может сделать дальнейшую работу с window некорректной.

Мой вклад

Мне нужен был самостоятельный рабочий набор, поэтому я материализовал копию:

List<Task> tasksToMove =
        new ArrayList<>(allTasks.subList(from, to));
 
tasksToMove.addAll(additionalTasks);

После этого операции с tasksToMove перестали менять allTasks.

Результат

Исходная коллекция сохраняла ожидаемый размер и порядок. Алгоритм перестановки снова работал только с теми элементами, которые должен был изменять.

Технический вывод

subList полезен, когда нужно редактировать диапазон исходной коллекции. Если диапазон должен жить и изменяться независимо, его нужно скопировать.

На собеседовании важно сказать не просто «subList — список», а уточнить: это backed view, связанное с исходной коллекцией.

Связанные заметки