Небольшое объяснение того, как они работают.
ListBuffer
использует внутренне Nil
и ::
для построения неизменяемого List
и позволяет в постоянное время удалять первый и последний элементов.Для этого он сохраняет указатель на первый и последний элемент списка и фактически может изменять заголовок и хвост (* в противном случае неизменяемый) класса ::
(хороший прием, допускаемый членами private[scala] var
::
).Его метод toList
возвращает также обычный неизменный List
в постоянное время, поскольку он может напрямую возвращать структуру, поддерживаемую внутри.Он также является компоновщиком по умолчанию для неизменных List
с (и, следовательно, действительно можно ожидать, что он будет добавляться в постоянное время).Если вы вызываете toList
, а затем снова добавляете элемент в буфер, для воссоздания новой структуры требуется линейное время по отношению к текущему количеству элементов в буфере, поскольку он больше не должен изменять экспортированный список.
MutableList
внутренне работает с LinkedList
вместо этого (открыто, не как ::
) реализация изменяемого связанного списка, которая знает о своем элементе и преемнике (например, ::
).MutableList
также сохраняет указатели на первый и последний элемент, но toList
возвращается за линейное время, так как результирующий List
построен из LinkedList
.Таким образом, нет необходимости повторно инициализировать буфер после экспорта List
.
Учитывая ваши требования, я бы сказал, что ListBuffer
и MutableList
эквивалентны.Если вы хотите экспортировать их внутренний список в какой-то момент, спросите себя, где вы хотите использовать издержки: когда вы экспортируете список, а затем никаких накладных расходов, если вы используете мутирующий буфер (затем перейдите к MutableList
), или только если выснова изменяемый буфер, и ни один во время экспорта (затем перейдите к ListBuffer
).
Я предполагаю, что в капитальном ремонте коллекции 2.8 MutableList
предшествовал ListBuffer
и всей системе Builder
.На самом деле, MutableList
преимущественно полезен из пакета collection.mutable
: у него есть метод private[mutable] def toLinkedList
, который возвращается в постоянное время, и, таким образом, может эффективно использоваться в качестве делегированного компоновщика для всех структур, которые поддерживают LinkedList
внутри.
Так что я бы также порекомендовал ListBuffer
, так как это может также привлечь внимание и оптимизировать в будущем, чем «чисто изменяемые» структуры, такие как MutableList
и LinkedList
.