Когда использовать очередь над arraylist
Одним из основных аргументов использования очереди над ArrayList является то, что Queue гарантирует поведение FIFO.
Но если я добавлю 10 элементов в ArrayList, а затем перейду по элементам, начиная с 0-го элемента, тогда я извлечу элементы в том же порядке, в каком они были добавлены. По сути, это гарантирует поведение FIFO.
Что такого особенного в Queue по сравнению с традиционным ArrayList?
Ответы
Ответ 1
Если бы я дал вам экземпляр Queue
, то вы бы знали, что путем итеративного вызова remove()
вы должны получить элементы в порядке FIFO. Если я дал вам экземпляр ArrayList
, тогда вы не можете гарантировать такую гарантию.
В качестве примера возьмем следующий код:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(4);
list.add(3);
list.add(2);
list.add(1);
list.set(4,5);
list.set(3,4);
list.set(2,3);
list.set(1,2);
list.set(0,1);
System.out.println(list);
Если бы я теперь дал вам этот список, то после повтора с 0 до 4 вы не получили бы элементы в порядке FIFO.
Кроме того, я бы сказал, что другая разница - это абстракция. С экземпляром Queue
вам не нужно беспокоиться об индексах, и это облегчает думать, если вам не нужно все, что может предложить ArrayList
.
Ответ 2
Вы можете посмотреть здесь javadoc. Основное отличие: List
позволяет вам просматривать любой элемент, когда захотите. Очередь позволяет вам смотреть только на "следующий".
Подумайте об этом как о реальной очереди или о линии для кассового аппарата в продуктовом магазине. Вы не спрашиваете парня в середине или в конце, чтобы заплатить дальше, вы всегда спрашиваете парня, который впереди/ожидал самого длинного.
Стоит отметить, что некоторые списки представляют собой очереди. Например, посмотрите LinkedList.
Ответ 3
Ограничения, налагаемые на очередь (FIFO, без произвольного доступа), по сравнению с ArrayList, позволяют лучше оптимизировать структуру данных, иметь лучше concurrency и быть более подходящим и более чистым при вызове.
Что касается оптимизации и concurrency, представьте себе общий сценарий, когда производитель заполняет очередь, пока потребитель ее потребляет. Если мы использовали ArrayList для этого, то в наивной реализации каждое удаление первого элемента вызовет операцию сдвига в ArrayList, чтобы перемещаться вниз по каждому другому элементу. Это очень неэффективно, особенно в параллельной реализации, поскольку список будет заблокирован для продолжительности всей операции переключения.
В отношении дизайна, если элементы должны быть доступны в режиме FIFO, то использование очереди автоматически передает это намерение, тогда как в списке нет. Эта ясность коммуникации позволяет легче понять код и, возможно, сделать код более надежным и без ошибок.
Ответ 4
Например, Queue
методы poll()
и remove()
извлекают элемент и удаляют его из очереди.
Некоторая реализация интерфейса Queue
(PriorityQueue
) позволяет установить приоритет для элементов и получить их благодаря этому приоритету. Это гораздо больше, чем поведение FIFO в последнем случае.
Ответ 5
Разница в том, что для очереди вам гарантировано вытащить элементы в порядке FIFO. Для ArrayList вы не представляете, какой заказ были добавлены. В зависимости от того, как вы его используете, вы можете применить порядок FIFO в ArrayList. Я мог бы также создать оболочку для очереди, которая позволила мне вытащить тот элемент, который мне нужен.
То, что я пытаюсь сделать, это то, что эти классы предназначены для того, чтобы быть хорошими в чем-то. Вам не обязательно использовать их для этого, но для чего они предназначены и оптимизированы. Очереди очень хороши при добавлении и удалении элементов, но плохо, если вам нужно их искать. ArrayLists, с другой стороны, немного медленнее добавлять элементы, но позволяют легко получить произвольный доступ. Вы не увидите его в большинстве приложений, которые вы пишете, но часто бывает, что для выбора одного над другим часто возникает штраф.
Ответ 6
Да!
Я бы использовал методы poll() и peek() в очереди, которые возвращают значение, а также удаляют, соответственно проверяют элемент head. Также эти методы предоставляют вам специальное значение null, если операция завершается с ошибкой и не выбрасывает исключение, как и метод remove(), выдает исключение nosuchelement.
Ссылка: docs.oracle.com
Ответ 7
Рассмотрим ситуацию, в которой случайные процессы случайным образом обновляют arraylist, и мы должны обрабатывать их в fifo?
Нет абсолютно никакого способа сделать это, но изменить структуру данных от arraylist до очереди