如何在可更新列表上循环



我正在构建一个Java Running类,它将逐个处理一组项。工作时(run ning),该集合可能会更新(仅添加项目)。

我如何通过确保该列表将考虑新添加的元素来循环该列表?

更新

根据答案,我实现了我在代码审查中建议的代码。

答案

您应该使用Queue,即java.util.concurrent.ConcurrentLinkedQueuejava.util.concurrent.LinkedBlockingQueuejava.util.concurrent.ArrayBlockingQueue或适合您需要的其他实现之一。

它们有不同的方法,允许您实现不同的场景。您可以检查javadocs中Queue方法之间的差异(有些方法抛出异常或返回null;有些方法用于查看元素或在删除后检索元素)。

抛出异常返回特殊值

插入添加(e)报价(e)

删除Remove()poll()

检查元素()peek()

BlockingQueue实现的情况下,还有两个选项:阻塞方法和超时方法。可能方法的扩展表在它的javadoc中。

仔细选择所需的实施方式。你想要固定容量吗?是否要阻止从空队列中检索?您希望您的队列是有界的还是无界的。如果仍有疑问,请查找解释不同队列类型之间差异的Stack Overflow答案,用谷歌搜索它们或查看javadocs。

咆哮

根据您的设计,您可能会遇到一个问题,也可能不会遇到这个问题——如何判断队列是空的,因为您已经完成了生成元素的工作。您的生产者(无论是向队列中插入元素的人)是否不够快,无法在消费项目之前将其添加到队列中?或者队列是空的,因为所有任务都已完成?在后一种情况下,如果使用阻塞队列,则可以在没有可用的元素时阻塞元素的检索。在这种情况下,您可以考虑使用";"毒丸";标记元素,这意味着生产者已经完成了生产,或者通过使用中间中介类更好地将生产者与消费者解耦,该中介类保存队列,生产者/消费者仅与中介交互。

使用队列(例如java.util.concurrent.LinkedBlockingQueue)而不是列表。队列是专门为这类场景设计的。

不要使用List。

如果我使用Queue实例,那么可以调用remove(),并按FIFO顺序检索元素。如果您使用的是List实例,则不能做出这样的保证。

以以下代码为例:

    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);

另外,另一个区别是抽象。有了Queue实例,您就不必担心索引,如果您不需要List所提供的一切,这会让您更容易思考。

最新更新