0

I'd like to compare elements within a set, in order to merge elements too similar. In order to gain some time, I would like to erase similarities during the iteration. Here how I try to proceed:

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

As you can guess from my presence here, it doesn't work, giving me this nice stacktrace :

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)

At first, I thought i1 and i2 were iterating over the same set and that I would find an answer here. As a consequence, I create a temporary set each time. However, it didn't resolve the problem.

Any ideas where the trouble might come from ?

2
  • How does your isSimilarTo(Personne) differ from the code that would be inside equals(Object)? Commented Feb 25, 2014 at 17:56
  • It has some calculations over the differents attributes but reads onlyinformation. Commented Feb 25, 2014 at 18:04

4 Answers 4

1

While iterating through a set use the iterator to delete elements from the set rather than using set.remove()

// wrong way
personnes.remove(autrePersonne); 

//correct way
it.remove(); 
Sign up to request clarification or add additional context in comments.

1 Comment

It erased the exception, thanks ! I'll check if it works as expected tomorrow.
1

Use Iterator#remove() rather than Set#remove(Object).

So replace the following line

personnes.remove(autrePersonne);

with

i2.remove();

See here for more details.

3 Comments

Although this is correct, how do you apply this to his particular example?
Is there a difference between It#remove and It.remove or is this just convention ?
@fxm Iterator#remove() simply refers to the remove() method of the Iterator class. In your code you'd call that method on your Iterator object (i.e. 12.remove())
0

You can't update the SET while another thread is iterating it due to which ConcurrentModificationException exception arise.

You are iterating the SET

Iterator<Personne> i1 = personnes.iterator(); and use personnes.remove(autrePersonne); to remove the element.

use Iterator remove method to remove the element

6 Comments

But you cant update parent SET while iterating.Also what is ur desired output ?
A set containing elements which aren't similars.
you are using set so it will not contain similar entry
Well, similar in my way, not strictly equal (hence the isSimilar function).
what isSimilarTo method do /
|
0

Do it in two steps:

  1. isolate what need removal
  2. remove

.

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

Also, you need to take care of the case where autrePersonne equals personne

1 Comment

While it probably works, it's more expensive in terms of complexity than what I'm trying to achieve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.