【发布时间】:2013-06-30 11:11:51
【问题描述】:
在 ArrayList 上使用 Queue 的一个基本论点是 Queue 保证 FIFO 行为。
但是,如果我向 ArrayList 添加 10 个元素,然后从第 0 个元素开始遍历元素,那么我将按照添加元素的顺序检索元素。所以本质上,这保证了 FIFO 行为。
与传统的 ArrayList 相比,Queue 有什么特别之处?
【问题讨论】:
在 ArrayList 上使用 Queue 的一个基本论点是 Queue 保证 FIFO 行为。
但是,如果我向 ArrayList 添加 10 个元素,然后从第 0 个元素开始遍历元素,那么我将按照添加元素的顺序检索元素。所以本质上,这保证了 FIFO 行为。
与传统的 ArrayList 相比,Queue 有什么特别之处?
【问题讨论】:
例如,Queue 方法 poll() 和 remove() 检索元素并将其从队列中删除。
Queue 接口 (PriorityQueue) 的某些实现允许为元素设置优先级并根据此优先级检索它们。在最后一种情况下,它不仅仅是一种 FIFO 行为。
【讨论】:
您可以查看javadoc here。主要区别在于List 让您可以随时查看任何元素。队列只让您查看“下一个”队列。
将其视为真正的队列或杂货店收银台的队列。您不会要求中间或最后的人接下来付款,您总是会问在前面/等待时间最长的人。
值得注意的是,有些列表是队列。以LinkedList 为例。
【讨论】:
ArrayList 会很烦人,因为它无法像Queue 那样方便地吸引下一个客户。你必须做if (!list.isEmpty()) list.remove(0);。我宁愿读/写queue.poll()
queue.poll()那么简单、富有表现力和可读性。您可以为此使用ArrayList。没有人说别的。它只是不适合这项工作。
如果我给你一个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 提供的所有内容,这会让事情变得更容易思考。
【讨论】:
不同之处在于,对于队列,您可以保证按 FIFO 顺序拉出元素。对于 ArrayList,您不知道元素的添加顺序。根据您使用它的方式,您可以对 ArrayList 强制执行 FIFO 排序。我还可以为 Queue 设计一个包装器,让我可以取出我想要的任何元素。
我想说的是,这些课程旨在擅长某些方面。您不必为此使用它们,但这就是它们的设计和优化目的。队列非常擅长添加和删除元素,但如果您需要搜索它们则不好。另一方面,ArrayLists 添加元素有点慢,但允许轻松随机访问。在您编写的大多数应用程序中您不会看到它,但是选择一个而不是另一个通常会降低性能。
【讨论】:
与 ArrayList 相比,对队列施加的限制(FIFO,无随机访问)允许更好地优化数据结构,具有更好的并发性,并在需要时成为更合适和更简洁的设计。
关于优化和并发,想象一下生产者填充队列而消费者消费它的常见场景。如果我们为此使用 ArrayList,那么在幼稚的实现中,每次删除第一个元素都会导致 ArrayList 上的移位操作,以便向下移动所有其他元素。这是非常低效的,尤其是在并发实现中,因为列表将在整个移位操作期间被锁定。
在设计方面,如果要以 FIFO 方式访问项目,则使用队列会自动传达该意图,而列表则不会。这种清晰的沟通有助于更轻松地理解代码,并可能使代码更健壮且无错误。
【讨论】:
是的!
我会在队列中使用 poll() 和 peek() 方法返回值以及 remove ,分别检查 head 元素。此外,如果操作失败并且不抛出,这些方法为您提供特殊值 null与 remove() 方法一样的异常将抛出 nosuchelement 异常。
参考:docs.oracle.com
【讨论】:
考虑随机进程随机更新数组列表的情况,我们应该在 fifo 中处理它们?
除了将数据结构从arraylist更改为queue
【讨论】: