Java并发修改异常错误
我正在为我的大学课程编写一些代码,并改变了一种方法Java并发修改异常错误,java,arraylist,Java,Arraylist,我正在为我的大学课程编写一些代码,并改变了一种方法 public boolean removeStudent(String studentName) { int index = 0; for (Student student : students) { if (studentName.equalsIgnoreCasee(student.getName())) { students.remove(index);
public boolean removeStudent(String studentName)
{
int index = 0;
for (Student student : students)
{
if (studentName.equalsIgnoreCasee(student.getName()))
{
students.remove(index);
return true;
}
index++;
}
return false;
}
致:
但是,新方法不断给出一个并发修改错误。我怎样才能绕过这个问题以及为什么会发生这种情况?这是因为您在执行
remove()
之后继续遍历列表
您同时读取和写入列表,这打破了foreach循环底层迭代器的约定
使用迭代器.remove()
for(迭代器iter=students.Iterator();iter.hasNext();){
Student=iter.next();
if(studentName.equalsIgnoreCase(student.getName()){
iter.remove();
}
}
其描述如下:
返回迭代中的下一个元素
如果迭代没有更多元素,则抛出NoTouchElementException
您可以使用
Iterator.hasNext()
检查是否有下一个元素可用。发生此错误是因为您在迭代集合时试图更改集合的大小。如果有10个学生,则开始循环时希望经过10次迭代。删除学生时,还需要进行多少次迭代?答案显然取决于w在这里,您从列表中删除了您的学生以及您当前所在的位置。显然,java不知道这一点
要解决此问题,必须使用迭代器。您可以按如下方式完成此操作:
Iterator<Student> studentsIterator;
for(studentsIterator = students.iterator(); studentsIterator.hasNext();)
{
Student student = studentsIterator.next();
if(student... /* condition */)
{
studentIterator.remove(); //This removes student from the collection safely
}
}
迭代器studentsIterator;
for(studentsIterator=students.iterator();studentsIterator.hasNext();)
{
Student=studentsIterator.next();
如果(学生…/*条件*/)
{
studentIterator.remove();//这将安全地从集合中删除student
}
}
在遍历学生
集合时,不允许从学生
集合中删除元素
当对象的并发修改不允许时,检测到该修改的方法可能会引发此异常
例如,通常不允许一个线程在另一个线程对集合进行迭代时修改集合。通常,在这些情况下,迭代的结果是未定义的
试着换成
Iterator<Student> itr = students.iterator();
while (itr.hasNext()) {
Student student = itr.next();
if (studentName.equalsIgnoreCase(student.getName()))
{
itr.remove();
}
}
Iterator itr=students.Iterator();
while(itr.hasNext()){
学生=itr.next();
if(studentName.equalsIgnoreCase(student.getName()))
{
itr.remove();
}
}
如果要在循环中删除,应使用迭代器及其方法
public boolean removeStudent(字符串studentName)
{
迭代器itS=students.Iterator();
while(itS.hasNext())
{
Student=itS.next();
if(studentName.equalsIgnoreCasee(student.getName()))
{
它的.remove();
返回true;
}
}
返回false;
}
迭代时,不允许从集合中删除元素。迭代器在使用过程中检测到结构更改,并引发异常。许多集合都是以这种方式实现的
直接使用迭代器:
Iterator<Student> it = students.iterator();
while (it.hasNext()) {
Student student = it.next();
if (studentName.equalsIgnoreCase(student.getName())) {
it.remove();
return true;
}
}
return false;
Iterator it=students.Iterator();
while(it.hasNext()){
学生=it.next();
if(studentName.equalsIgnoreCase(student.getName())){
it.remove();
返回true;
}
}
返回false;
foreach
构造使用底层的迭代器
在第二种方法中,即使从列表中删除了一个项目,您仍会继续迭代。这会导致出现您看到的异常。请查看取自ConcurrentModificationException
文档的以下语句:
例如,通常不允许一个螺纹进行修改
一个集合,而另一个线程正在对其进行迭代。通常,
在这些情况下,迭代的结果是未定义的。
一些迭代器实现(包括所有通用
JRE提供的目的集合实现可以选择
如果检测到此行为,则引发此异常
使用时不应从集合中删除对象
for-each语句-这将导致异常,因为迭代器在其迭代过程中面对更改的集合。(for循环)
或者使用常规for循环(对于int i=0;i<100;i++)等。。。
或者将要删除的对象保留在列表中,并将其删除到for循环之外
此外,还可以按索引删除对象,其中索引为:0、1、2
但是index实际上应该是学生的索引。您可以避免并发修改错误,只要在删除元素后中断循环,或者如果方法具有返回类型,则在删除元素后返回一个值。这可能是三个最常见的Java问题之一。您必须使用迭代器并调用>iterator.remove
。您在对列表进行迭代时正在更改列表,java集合不允许这样做。可以找到完整的解释。谢谢,伙计!这很有效。我不知道为什么没有对此进行投票。
Iterator<Student> itr = students.iterator();
while (itr.hasNext()) {
Student student = itr.next();
if (studentName.equalsIgnoreCase(student.getName()))
{
itr.remove();
}
}
public boolean removeStudent(String studentName)
{
Iterator<Student> itS = students.iterator();
while(itS.hasNext())
{
Student student = itS.next();
if (studentName.equalsIgnoreCasee(student.getName()))
{
itS.remove();
return true;
}
}
return false;
}
Iterator<Student> it = students.iterator();
while (it.hasNext()) {
Student student = it.next();
if (studentName.equalsIgnoreCase(student.getName())) {
it.remove();
return true;
}
}
return false;