2013-07-02 3 views
14

Одним из основных аргументов использования очереди над ArrayList является то, что Queue гарантирует поведение FIFO.Когда использовать очередь над arraylist

Но если я добавлю 10 элементов в ArrayList, а затем перейду через элементы, начиная с 0-го элемента, тогда я извлечу элементы в том же порядке, в каком они были добавлены. По сути, это гарантирует поведение FIFO.

Что такого особенного в отношении очереди по сравнению с традиционным ArrayList?

ответ

12

Если бы я дал вам экземпляр 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 вы не получите элементы в порядке их поступления.

Кроме того, я бы сказал, что еще одна разница - это абстракция. С экземпляром Queue вам не нужно беспокоиться об индексах, и это облегчает думать о том, что вам не нужно все, что может предложить ArrayList.

0

Например, Queue методы poll() и remove() извлекает элемент и удаляет его из очереди.

Некоторая реализация интерфейса Queue (PriorityQueue) позволяет устанавливать приоритет для элементов и извлекать их благодаря этому приоритету. Это гораздо больше, чем поведение FIFO в последнем случае.

12

Вы можете посмотреть javadoc here. Основное отличие: List позволяет вам смотреть на любой элемент, когда захотите. Очередь позволяет вам смотреть только на «следующий».

Подумайте об этом как о реальной очереди или о линии для кассового аппарата в продуктовом магазине. Вы не просите парня в середине или в конце заплатить дальше, вы всегда спрашиваете парня, который находится впереди/ждал дольше всех.

Стоит отметить, что некоторые списки являются очередями. Посмотрите на LinkedList, например.

+0

Так что в этом смысле очереди на самом деле то, что ограничение ArrayList уже дал нам ... это не добавляет никакой новой функции. Что вы можете сделать с очередью, которую вы можете сделать с помощью arraylist (случайный доступ a.k.a) ... но не наоборот – Victor

+3

Это зависит от того, как вы на это смотрите. Если вы пытались внедрить линию продуктового магазина в коде, «ArrayList» будет раздражать, потому что у него нет способа получить следующего клиента таким образом, который так же удобен, как «очередь». Вам нужно будет сделать if if (! List.isEmpty()) list.remove (0); '. Я предпочитаю читать/писать 'queue.poll()' –

+0

Почему Arraylist не может получить следующего клиента легко? Мы просто определяем итератор и делаем iter.next() – Victor

0

Разница в том, что для очереди вам гарантировано вытащить элементы в порядке FIFO. Для ArrayList вы не представляете, какой заказ были добавлены. В зависимости от того, как вы его используете, вы можете применить порядок FIFO в ArrayList. Я мог бы также создать оболочку для очереди, которая позволила мне вытащить тот элемент, который мне нужен.

То, что я пытаюсь сделать, состоит в том, что эти классы предназначены для того, чтобы быть хорошими в чем-то. Вам не обязательно использовать их для этого, но для этого они разработаны и оптимизированы. Очереди очень хороши при добавлении и удалении элементов, но плохо, если вам нужно их искать. ArrayLists, с другой стороны, немного медленнее добавлять элементы, но позволяют легко получить произвольный доступ. Вы не увидите его в большинстве приложений, которые вы пишете, но часто бывает, что для выбора одного над другим часто возникает штраф за производительность.

4

Ограничения, налагаемые на очередь (FIFO, без произвольного доступа), по сравнению с ArrayList, позволяют лучше оптимизировать структуру данных, улучшать параллелизм и быть более подходящими и более чистыми при необходимости.

Что касается оптимизации и параллелизма, представьте себе общий сценарий, когда производитель заполняет очередь, пока потребитель ее потребляет. Если мы использовали ArrayList для этого, то в наивной реализации каждое удаление первого элемента вызовет операцию сдвига в ArrayList, чтобы перемещаться вниз по каждому другому элементу. Это очень неэффективно, особенно в параллельной реализации, поскольку список будет заблокирован для продолжительности всей операции переключения.

Что касается дизайна, если элементы должны быть доступны в режиме FIFO, то использование очереди автоматически передает это намерение, тогда как в списке нет. Эта ясность коммуникации позволяет легче понять код и, возможно, сделать код более надежным и без ошибок.

0

Да!

Я бы использовал методы poll() и peek() в очереди, которые возвращают значение, а также удаляют, проверяют элемент head соответственно. Также эти методы предоставляют вам специальное значение null, если операция завершается с ошибкой и не выполняется выдает исключение, так как метод remove() будет вызывать исключение nosuchelement.

Ref: docs.oracle.com

0

Рассмотрим ситуацию, в которой случайные процессы обновления в ArrayList случайным образом, и мы должны обработать их в ФИФО?

Там нет абсолютно никакого способа, чтобы сделать это, но, чтобы изменить структуру данных из ArrayList в очередь

Смежные вопросы