-1

在下面的函数中,我声明了局部变量allPeopelitr(它们是覆盖全局变量)。如果我注释掉局部变量(在下面的 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;
            }
        }
    }
4

2 回答 2

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();
  }

发生的情况是您只实例化迭代器一次,然后将一些内容添加到列表中,然后使用迭代器。像这样重用迭代器的全局实例是没有意义的。具体来说,在实例化它之后,除了通过迭代器本身之外,您不得更改列表。

使用全局变量是一回事,但使用迭代器的全局实例是另一回事。两者都是错误的,但后者是致命的。

于 2012-11-10T13:57:30.773 回答
0

使用局部变量,每次线程调用您的方法时,都会创建这些变量的新实例,这些变量对任何其他线程都不可用(除非您特别允许传递引用)。因此,没有其他线程可以修改您的对象。

使用全局(我认为您的意思是instance变量、属性),所有有权访问您的对象的线程都可以访问对象的这些属性(让它直接访问,让它通过运行您的对象方法)并且可以修改它们同时您的另一个线程正在运行迭代。由于iterator可以检测到Collection被迭代的对象何时被修改,当发生这种情况时它会抛出异常(这意味着“我正在迭代集合的所有对象但这些对象不再相同,所以这也是令人困惑,我失败了”。

于 2012-11-10T13:55:57.613 回答