Java 子列表引发的ConcurrentModificationException
我有非常简单的代码:Java 子列表引发的ConcurrentModificationException,java,list,Java,List,我有非常简单的代码: List<String> list = new ArrayList<String>(); String a = "a"; String b = "b"; String c = "c"; String d = "d"; list.add(a); list.add(b); list.add(c); List<String> backedList = list.subL
List<String> list = new ArrayList<String>();
String a = "a";
String b = "b";
String c = "c";
String d = "d";
list.add(a);
list.add(b);
list.add(c);
List<String> backedList = list.subList(0, 2);
list.add(0, d);
System.out.println("2b: " + backedList);
List List=new ArrayList();
字符串a=“a”;
字符串b=“b”;
字符串c=“c”;
字符串d=“d”;
列表.添加(a);
列表.添加(b);
增加(c)项;
List backedList=List.subList(0,2);
列表。添加(0,d);
System.out.println(“2b:+backedList”);
我通过list.add(0,d)得到ConcurrentModificationException异常。一般来说,这是因为sublist()。我很困惑,因为在sublist()的情况下,文档中说:
返回的列表由该列表支持,因此
返回的列表反映在此列表中,反之亦然
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in list.
Collections.swap(listArr, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in sub list.
Collections.swap(listArrSub, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Structural Change in sub list.
listArrSub.add("Mumbai");
System.out.println("\nAfter Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
您能解释一下捕获点在哪里吗?子列表是原始列表的简单视图(请参阅)。您可以修改其中的元素,但不能更改列表的结构 根据文档,“如果您试图进行结构更改,
子列表
行为未定义。”。我猜在这个特定的实现中,ConcurrentModificationException
被确定为未定义的行为
如果支持列表(即,此列表)以任何方式(而不是通过返回的列表)进行结构修改,则此方法返回的列表的语义将变得未定义。(结构修改是指更改此列表的大小,或以其他方式干扰列表,使正在进行的迭代可能产生不正确的结果。)
添加(0,d)涉及将所有项目移动一个位置并增加列表的大小。这是一个相当结构性的变化
返回的列表由该列表支持,因此返回列表中的非结构性更改将反映在此列表中,反之亦然
上述说法绝对正确,但我们必须牢记非结构性变化。我想描述两个例子来证明上述说法。示例-1:执行非结构性的列表中的更改
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in list.
Collections.swap(listArr, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in sub list.
Collections.swap(listArrSub, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Structural Change in sub list.
listArrSub.add("Mumbai");
System.out.println("\nAfter Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
说明-:根据前面提到的Oracle文档说明,交换操作反映在两个列表中
示例2:执行非结构性的子列表中的更改
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in list.
Collections.swap(listArr, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in sub list.
Collections.swap(listArrSub, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Structural Change in sub list.
listArrSub.add("Mumbai");
System.out.println("\nAfter Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
解释-:根据前面提到的Oracle文档声明,交换操作反映在两个列表中,但它是在子列表上执行的
正如我们在上述两个例子中看到的非结构性的变化。现在,让我们根据Oracle文档中给出的以下语句查看结构上的更改
如果支持列表(即,此列表)以任何方式(而不是通过返回的列表)进行结构修改,则此方法返回的列表的语义将变得未定义。(结构修改是指更改此列表的大小,或以其他方式干扰列表,使正在进行的迭代可能产生不正确的结果。)
示例3:执行列表中的结构更改
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Structural Change in list.
listArr.add("Mumbai");
System.out.println("\nAfter Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
解释-:根据前面提到的Oracle文档声明,如果支持列表(即此列表)未定义此方法返回的列表的语义,则结构修改操作将抛出java.util.ConcurrentModificationException
异常通过返回列表以外的任何方式进行结构修改。
示例4:执行子列表中的结构变化
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in list.
Collections.swap(listArr, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Non-Structural Change in sub list.
Collections.swap(listArrSub, 0, 1);
System.out.println("\nAfter Non-Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
public static void main(String[] args) {
List<String> listArr = new ArrayList<>();
listArr.add("Delhi");
listArr.add("Bangalore");
listArr.add("New York");
listArr.add("London");
List<String> listArrSub = listArr.subList(1, 3);
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
//Performing Structural Change in sub list.
listArrSub.add("Mumbai");
System.out.println("\nAfter Structural Change...\n");
System.out.println("List-: " + listArr);
System.out.println("Sub List-: " + listArrSub);
}
解释-:对返回的列表进行结构修改效果良好,并反映在列表中 遇到此错误的场景
- 我有一份清单(原始清单),比如说100件
- 按升序对原始列表排序
- 子列表it->已创建子列表(升序子列表)
- 按降序排列原始列表
- 迭代子列表(升序有序子列表)列表
- 我有一份清单(原始清单),比如说100件
- 按升序排序
- 子列表it->已创建子列表(升序子列表)
- 迭代子列表(升序有序子列表)列表
- 按降序排列原始列表