在arraylist for循环中进行Collections.swap()是否安全?

Zip*_*Zip 4 java collections for-loop list arraylist

我有以下代码:

private List<String> listOfStrings = new ArrayList<>();
listOfStrings.add("a");
listOfStrings.add("b");
listOfStrings.add("c");
listOfStrings.add("d");

for (String temp : listOfStrings) {
  if (temp.equals("c")) {
    Collections.swap(listOfStrings, 0, listOfStrings.indexOf(temp));
  }
}
Run Code Online (Sandbox Code Playgroud)

该列表可能不仅仅是String列表,而且可能是我编写的类所定义的对象列表.我不确定这里的交换,我看到它编译并运行良好,但我不知道它是否安全.

有没有人对此有任何建议?如果我需要进行交换.我打算使用for (int i = 0; i < size; i++)迭代和使用list.get(i)来获取项目,但我认为list.get(i)在arraylist 上使用它并不是一个好主意?

任何帮助将不胜感激!!提前致谢!!

Hoo*_*pje 5

如果您担心a ConcurrentModificationException,是的,从循环内调用swap是安全的.

增强的for循环将在内部使用迭代器,并且迭代器可以ConcurrentModificationException在检测到列表的结构修改时抛出一个迭代器本身未完成的结构修改.虽然您确实修改了列表,但您没有进行结构修改:结构修改是一种修改,其中列表(或后备数组)的大小发生了变化.仅仅设置一个值不被视为结构修改.从Java API文档:

(结构修改是添加或删除一个或多个元素的任何操作,或显式调整后备数组的大小;仅设置元素的值不是结构修改.)

但是,在您的情况下使用基于索引的for循环将更快.原因是indexOf(temp)调用实际上需要找到对象来获取其索引,因此它必须再次遍历列表项.因此,您的算法具有二次运行时间.在基于索引的for循环中,您已经知道要交换的元素的索引,因此这不是必需的,并且您具有线性运行时.