0

I have an Array full of Objects, and if two Objects are the same, I want to delete both of them.

Here is my current approach, which returns a

java.util.ConcurrentModificationException

public void deleteDuplicates(ArrayList<Object> objectArrayList){

    Iterator<Object> objectIterator = objectArrayList.iterator();
    Iterator<Object> objectIterator2 = objectArrayList.iterator();

    while(objectIterator.hasNext()){
        Object object = objectIterator.next();

        while(objectIterator2.hasNext()){
            if(object.equals(objectIterator2.next())){
                objectIterator2.remove();
                objectIterator.remove();
            }
        }
    }
}
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
Oliver-R
  • 163
  • 1
  • 9
  • But the looks of it, if we're being _really_ picky, you've got an [`ArrayList`](http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html), which is a [`List`](http://docs.oracle.com/javase/7/docs/api/java/util/List.html), not [an array](http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.1) :-). – Edd Aug 26 '15 at 19:49
  • Edited the title, thanks – Oliver-R Aug 26 '15 at 19:52
  • How can you move from element to element if you remove some in between? – MaxZoom Aug 26 '15 at 19:52
  • What do you want to happen when an odd number of objects are the same? – Andy Thomas Aug 26 '15 at 20:03
  • @AndyThomas I want to remove any repeated objects, so that includes odd amounts – Oliver-R Aug 26 '15 at 20:14

1 Answers1

0

This code will remove all list members that are present more than once.

This approach handles an odd number of repeats. So it does not detect and remove repeat pairs, because that could leave an orphan repeat. Instead, it counts first, and then removes repeats.

public static void deleteDuplicates( List<Object> objectList) {
    HashMap<Object,Integer> counts = new HashMap<>();
    for ( Object o : objectList ) {
        int oldCount = counts.containsKey( o )
            ? counts.get( o ).intValue()
            : 0;
        counts.put( o, oldCount + 1 );
    }

    for ( Iterator<Object> it = objectList.iterator(); it.hasNext(); ) {
        Object o = it.next();
        if ( 1 < counts.get( o )) {
            it.remove();
        }
    }
}

Note that this approach requires that the hashCode() method of the list members satisfy the contract specified by Object.hashCode(), including:

If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151