Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java集合,允许在迭代时添加和删除_Java_Collections_Frameworks_Concurrent Collections - Fatal编程技术网

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

Java集合,允许在迭代时添加和删除,java,collections,frameworks,concurrent-collections,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和结尾 因此,当我得到和迭代

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


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

  • 我迭代它(使用迭代器)并到达元素2,现在我在末尾添加4(集合现在是[1,2,3,4])
  • 现在我创建一个新的迭代器并迭代集合,结果是[1,2,3,4]
  • 我继续使用第一个迭代器进行迭代,它只会给我3,然后返回
  • 现在重置第一个迭代器将得到[1,2,3,4](类似于创建一个新迭代器)
移除元件时也应如此。如果我删除3而不是添加,第二个迭代器应该给我[1,2],而第一个迭代器仍然给我3和结尾


因此,当我得到和迭代器时,我希望它给我创建迭代器时的集合(即使我稍后迭代它,在上迭代一点,然后继续),当我重置迭代器时,它将被垃圾收集,并将更新到最新版本,我应该能够在不同的时间创建多个迭代器实例,根据创建迭代器时数组的内容,这些实例将提供不同的版本

我需要它能够很好地处理多线程,最好有一个高效的实现


有人知道这样一个集合的任何实现吗,或者我必须自己实现吗?

的行为将类似于此,除了没有Java集合具有“重置”迭代器的功能——但是获得一个新的迭代器而不是重置迭代器具有您在此请求的效果。

您描述的内容与工作原理非常相似:

  • 一旦开始迭代,就可以在不影响迭代的情况下更改集合(包括来自另一个线程的集合)
  • 如果创建新迭代器,它将基于创建时的集合
  • 它是线程安全的
下面的简单示例具有以下输出:

迭代器1-1
已添加4个
迭代器2-1
迭代器2-2
迭代器2-3
迭代器2-4
迭代器1-2
迭代器1-3

publicstaticvoidmain(String[]args)抛出InterruptedException{
最终列表=新CopyOnWriteArrayList();
addAll(Arrays.asList(1,2,3));
新线程(newrunnable()){
@凌驾
公开募捐{
for(整数i:列表){
System.out.println(“迭代器1-”+i);
试一试{
睡眠(10);
}捕获(中断异常e){}
}
}
}).start();
睡眠(10);
增加(4);
System.out.println(“已添加4”);
for(整数i:列表){
System.out.println(“迭代器2-”+i);
}
}
您可以使用guava库中的

返回的ImmutableList经常是--不总是,但经常是 --恒定的俯视图,而不是显式副本。也就是说,它通常比你的平均列表更聪明——例如,它将使用 高效的包含支持集合的方法

你可以利用

根据文件:

ArrayList的一种线程安全变体,其中包含所有变异操作 (添加、设置等)通过创建 底层数组

成本高昂,但线程安全。

这通常成本太高,但可能比 当遍历操作的数量远远超过突变时的替代方案,以及 当您还不能或不想同步遍历时,此选项非常有用 需要排除并发线程之间的干扰。“快照” 样式迭代器方法使用对 创建迭代器的点


由于迭代发生在一种快照上,因此不支持
迭代器
本身上的操作(
删除
设置
、和
添加
)。

javolution拥有线程安全快速映射

它是否在更改时(内部)创建集合的新副本?或者它是以一种更有效的方式实现的?是的,正如javadoc中所描述的:“所有的变异操作(添加、设置等)都是通过创建底层数组的新副本来实现的。”这种行为看起来就像我所需要的。但是这个收藏品里面会有很多东西。迭代器经常在其上创建,但我相信更改更为罕见(因此更改后的副本可能不会导致太多性能损失)。@Razvi在这种情况下,您应该很好。如果你的表现不符合你的期望,你总能找到一些东西。
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);
    }

}