使用多个迭代器修改集合的麻烦

时间:2014-02-25 17:47:41

标签: java iterator

我想比较集合中的元素,以便合并元素太相似。为了获得一些时间,我想在迭代期间消除相似之处。 我在这里尝试着:

Iterator<Personne> i1 = personnes.iterator();
while (i1.hasNext()) {
     Personne personneObservee = i1.next();
     Set<Personne> tmp = new HashSet<Personne>();
     tmp.addAll(personnes);
     Iterator<Personne> i2 = tmp.iterator();
     while (i2.hasNext()) {
        Personne autrePersonne = i2.next();
        if (personneObservee.isSimilarTo(autrePersonne)) {
            personnes.remove(autrePersonne);
        }
    }
    result.add(personneObservee.toString());
}

正如你可以从我在这里的存在猜测,它不起作用,给我这个漂亮的堆栈跟踪:

java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
        at java.util.HashMap$KeyIterator.next(HashMap.java:960)
        at NameDetectorWithBenefits.mergeSamePersons(NameDetectorWithBenefits.java:41)
        at App.main(App.java:71)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
        at java.lang.Thread.run(Thread.java:744)

起初,我认为i1和i2正在迭代同一组,我会找到答案here。因此,我每次都会创建一个临时集。但是,它没有解决问题。

可能出现问题的任何想法?

4 个答案:

答案 0 :(得分:1)

使用Iterator#remove()而不是Set#remove(Object)

所以替换以下行

personnes.remove(autrePersonne);

i2.remove();

有关详细信息,请参阅here

答案 1 :(得分:1)

在遍历集合时,使用迭代器从集合中删除元素而不是使用set.remove()

// wrong way
personnes.remove(autrePersonne); 

//correct way
it.remove(); 

答案 2 :(得分:0)

由于出现SET异常,您无法更新ConcurrentModificationException而另一个线程正在迭代它。

您正在迭代SET

Iterator<Personne> i1 = personnes.iterator();并使用personnes.remove(autrePersonne);删除元素。

使用Iterator remove方法删除元素

答案 3 :(得分:0)

分两步完成:

  1. 隔离需要删除的内容
  2. 除去
  3. final Set<Personne> toRemove = new HashSet<>();
    for (final Personne personne: personnes) {
        for (final Personne autrePersonne: personnes) {
            if (person.isSimilarTo(autrePersonne)) {
                toRemove.add(autrePersonne);
            }
        }
    }
    personnes.removeAll(toRemove);
    

    此外,您需要注意autrePersonne等于personne

    的情况