允许在迭代时添加和删除的Java集合

Raz*_*zvi 5 java collections frameworks concurrent-collections

如果有任何框架实现了具有以下行为的集合,我感兴趣.


假设它最初包含:[1,2,3]

  • 我迭代它(使用迭代器)并到达元素2,现在我将4添加到结尾(集合现在将是[1,2,3,4]).
  • 现在我创建一个新的迭代器并迭代集合,产生[1,2,3,4]
  • 我继续迭代第一个迭代器,它只给我3并返回
  • 现在重置第一个迭代器会给我[1,2,3,4](类似于创建一个新的迭代器).

同样适用于删除元素.如果我删除3而不是添加,第二个迭代器应该给我[1,2],而第一个迭代器仍然会给我3和结束.


所以,当我得到迭代器时,我想让它给我一个我创建迭代器时的集合(即使我稍后迭代它,我迭代一点然后继续),当我重置迭代器时,它会被垃圾收集它将更新到最新版本,我应该能够在不同的时间创建多个迭代器实例,根据创建迭代器时的数组内容,将提供不同的版本.

我需要它与多线程一起工作,并且最好有一个有效的实现.

有没有人知道这样一个集合的任何实现,还是我必须自己实现它?

Lou*_*man 7

java.util.concurrent.CopyOnWriteArrayList 将表现得像这样,除了没有Java集合"重置"迭代器 - 但获得一个新的迭代器而不是重置具有你在这里请求的效果.


ass*_*ias 6

你描述的内容与CopyOnWriteArrayList工作方式非常相似:

  • 一旦开始迭代,您可以更改集合(包括来自另一个线程)而不会影响迭代
  • 如果您创建一个新的迭代器,它将基于创建时的集合
  • 它是线程安全的

以下简单示例,输出如下:

Iterator 1 - 1
4已添加
Iterator 2 - 1
Iterator 2 - 2
Iterator 2 - 3
Iterator 2 - 4
Iterator 1 - 2
Iterator 1 - 3

public static void main(String[] args) throws InterruptedException {
    final List<Integer> list = new CopyOnWriteArrayList<Integer>();
    list.addAll(Arrays.asList(1, 2, 3));
    new Thread(new Runnable() {

        @Override
        public void run() {
            for (Integer i : list) {
                System.out.println("Iterator 1 - " + i);
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {}
            }
        }
    }).start();
    Thread.sleep(10);
    list.add(4);
    System.out.println("4 has been added");
    for (Integer i : list) {
        System.out.println("Iterator 2 - " + i);
    }

}
Run Code Online (Sandbox Code Playgroud)