何时使用队列而不是arraylist

在ArrayList上使用Queue的一个基本参数是Queue保证FIFO行为。

但是,如果我向ArrayList添加10个元素,然后从第0个元素开始迭代元素,那么我将按照添加它们的顺序检索元素。 基本上,这保证了FIFO行为。

与传统的ArrayList相比,Queue有什么特别之处?

如果我给你一个Queue实例,那么你会知道通过迭代调用remove()你将以FIFO顺序检索元素。 如果我给你一个ArrayList实例,那么你可以不做这样的保证。

以下面的代码为例:

  ArrayList list = new ArrayList(); 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提供的所有内容,这会让您更容易思考。

你可以在这里查看javadoc 。 主要区别在于List允许您随时查看任何元素。 队列只允许您查看“下一个”队列。

把它想象成一个真正的队列或作为杂货店收银机的一条线。 你不要问中间或者下一个人下次付款,你总是问那个在前面/等待时间最长的人。

值得注意的是,有些列表是队列。 例如,查看LinkedList 。

与ArrayList相比,对队列(FIFO,无随机访问)施加的限制允许更好地优化数据结构,具有更好的并发性,并且在被调用时是更合适和更清洁的设计。

关于优化和并发性,想象一下生产者在消费者消费时填充队列的常见场景。 如果我们为此使用了ArrayList,那么在朴素实现中,每次删除第一个元素都会导致对ArrayList进行移位操作,以便向下移动每个其他元素。 这是非常低效的,尤其是在并发实现中,因为列表将在整个移位操作的持续时间内被锁定。

在设计方面,如果要以FIFO方式访问项目,则使用队列自动传达该意图,而列表则不会。 这种通信的清晰度允许更容易理解代码,并且可能使代码更健壮且无错误。

不同之处在于,对于队列,您可以保证以FIFO顺序拉出元素。 对于ArrayList,您不知道添加元素的顺序。 根据您的使用方式,您可以在ArrayList上强制执行FIFO排序。 我还可以为Queue设计一个包装器,它允许我拉出我想要的哪个元素。

我想说的是,这些类的设计是为了擅长某些东西。 您不必为此使用它们,但这就是它们的设计和优化。 队列非常擅长添加和删除元素,但如果需要搜索它们则很糟糕。 另一方面,ArrayLists添加元素有点慢,但允许轻松随机访问。 在您编写的大多数应用程序中都不会看到它,但是选择一个而不是另一个应用程序通常会有性能损失。

是!

我会在队列中使用poll()和peek()方法,它们返回值以及remove,分别检查head元素。另外,如果操作失败并且没有抛出exception,这些方法会为您提供一个特殊值null。用remove()方法会抛出nosuchelementexception。

参考:docs.oracle.com

例如, Queue方法poll()remove()检索元素并将其从队列中删除。

Queue接口( PriorityQueue )的某些实现允许为元素设置优先级并通过此优先级检索它们。 在最后一种情况下,它不仅仅是FIFO行为。

考虑随机进程随机更新arraylist的情况,我们应该在fifo中处理它们?

除了将数据结构从arraylist更改为queue之外,绝对没有办法做到这一点