Вы можете использовать ArrayList для этого. Сегодняшние компьютеры копируют данные с такой скоростью, что это не имеет значения, если ваш список не может содержать миллиарды элементов.
Информация об исполнении: Копирование 10 миллионов элементов принимает 13ms (thirteen milliseconds) на моем двойном ядре. Поэтому, думая даже секунду об оптимальной структуре данных, это отходы , если только ваш случай использования сильно отличается. В этом случае: у вас более 10 миллионов элементов, и ваше приложение ничего не делает, кроме как вставки и удаления элементов. Если вы каким-либо образом работаете с вставленными/удаленными элементами, есть вероятность, что время, затраченное на эту операцию, превышает стоимость вставки/удаления.
Связанный список кажется лучше на первый взгляд, но ему требуется больше времени, когда выделение памяти плюс код более сложный (со всем обновлением указателя). Таким образом, время работы хуже. Единственное преимущество использования LinkedList в Java - это то, что класс уже реализует интерфейс Queue, поэтому его естественнее использовать в вашем коде (используя peek() и pop()).
[EDIT] Итак, давайте посмотрим на эффективность. Что такое эффективность? Самый быстрый алгоритм? Тот, который занимает наименьшее количество строк (и, следовательно, имеет наименьшее количество ошибок)? Алгоритм, который проще всего использовать (= наименьшее количество кода на стороне разработчика + меньше ошибок)? Алгоритм, который работает лучше всего (что не всегда является самым быстрым алгоритмом)?
Давайте рассмотрим некоторые детали: LinkedList реализует Queue, поэтому код, который использует этот список, является более простым (list.pop() вместо list.remove (0)). Но LinkedList будет выделять память для каждого add(), в то время как ArrayList выделяет память только один раз за N элементов. И чтобы уменьшить это еще дальше, ArrayList будет выделять элементы N * 3/2, так как ваш список будет расти, количество распределений сократится. Если вы знаете размер своего списка заранее, ArrayList будет выделять память только один раз. Это также означает, что GC имеет меньше помех для очистки. Таким образом, с точки зрения производительности, ArrayList выигрывает на порядок в среднем случае.
Синхронизированные версии необходимы только тогда, когда несколько потоков обращаются к структуре данных.С Java 5 многие из них значительно улучшили скорость. Если у вас есть несколько потоков для ввода и ввода потоков, используйте ArrayBlockingQueue, но в этом случае LinkedBlockingQueue может быть вариантом, несмотря на плохую производительность распределения, так как реализация может разрешить push и pop из двух разных потоков одновременно, пока размер очереди> = 2 (в этом специальном случае потокам не нужно будет обращаться к тем же указателям). Чтобы решить это, единственный вариант - запустить профилировщик и определить, какая версия выполняется быстрее.
Это говорит о том, что любой совет о производительности неправильный в 90% случаев, если он не подкреплен измерением. Сегодняшние системы стали настолько сложными, и на заднем плане так много происходит, что человеку просто невозможно понять или даже перечислить все факторы, которые играют определенную роль.
Ха-ха, это было для меня, что я ошибался. Тем не менее, я имею в виду то же самое! :) – DivideByHero