在下面的函数中,我声明了局部变量allPeopel
和itr
(它们覆盖了全局变量)。如果我注释掉局部变量(在下面的Astrixes之间),则抛出ConcurrentModificationError。但是,如果我使用局部变量而不是全局变量,那么代码工作正常。我不明白为什么会这样?该类中还有许多其他函数,因此我尝试使用全局变量来获得更高效的代码。
public void removeAPerson(){
int id;
Scanner sc = new Scanner(System.in);
System.out.print("Enter ID of person to delete > ");
id = sc.nextInt();
sc.nextLine();
System.out.println();
/*************************************/
ArrayList<Person> allPeople;
allPeople = Person.getAllPeople();
Iterator itr = allPeople.iterator();
/*************************************/
while(itr.hasNext()){
Person obj = (Person) itr.next();
int ID = obj.getID2();
if(ID == id){
itr.remove();
break;
}
}
}
答案 0 :(得分:2)
这是你可能拥有的草图:
public class MyClass {
List<Person> persons = new ArrayList<>();
Iterator<Person> iter = strs.iterator();
public void addPerson(Person p) {
persons.add(p);
}
public void removePerson() {
... your posted code ...
}
public static void main(String... args) {
MyClass c = new MyClass();
c.addPerson(new Person());
c.removePerson();
}
只会将迭代器实例化一次,然后向列表添加内容,然后使用迭代器。重用像这样的迭代器的全局实例永远不会有意义。具体来说,在实例化之后,除非通过迭代器本身,否则不得更改列表。
使用全局变量是一回事,但使用迭代器的全局实例是另一回事。两者都是错的,但后者是致命的。
答案 1 :(得分:0)
使用局部变量,每次线程调用您的方法时都会创建这些变量的新实例,这些变量不可用于任何其他线程(除非您特别允许传递引用)。因此,没有其他线程可以修改您的对象。
使用全局(我认为你的意思是instance
变量,属性),所有有权访问你对象的线程都可以访问对象的那些属性(让它直接使用,让它运行你的对象方法)并且可以在其他线程运行迭代时修改它们。由于iterator
可以检测到正在迭代的Collection
何时被修改,当发生这种情况时它会抛出异常(这意味着没有别的“我正在迭代集合的所有对象但是这些对象不再相同,所以这太混乱了,我失败了。“