3

I am deleting 2nd last element of an ArrayList while iterating the same list through enhanced for-loop and I was expecting a ConcurrentModificationException however it is working fine. Kindly help me if java has provided a special case for 2nd last element.

I tried it with different indexes but it is working as expected only for the 2nd last element, it is giving unexpected result

    List<Integer> list=new ArrayList<>();
    list.add(2);
    list.add(4);
    list.add(3);
    list.add(5);
    for(Integer num:list) {
        if(num==3) {
            list.remove(num);
        }
        System.out.println(num);
    }

Expected result: ConcurrentModificationException

Actual Result: Working fine

R-Tech
  • 31
  • 2
  • 1
    The method that throws ConcurrentModificationException is the method ```Iterator#next``` that is being used with the syntax suggar ```for(Integer num : list)``` that will be actually replaced by ```Iterator it = list.iterator(); while(it.hasNext()) num = it.next()``` there's something about hasNext returning false in the first situation. IDK – Marcos Vasconcelos Jul 23 '19 at 16:33
  • 1
    I agree that this is covered in https://stackoverflow.com/q/14673653/3182664 , and specifically the technical reason is explained in sufficient details in https://stackoverflow.com/a/14674151/3182664 (i.e. not the accepted answer there). I'll close this one as a duplicate. If there are objections, drop me a note. – Marco13 Jul 23 '19 at 16:35
  • @Marco13 This question is not the same,can you add your answer for it – flyingfox Jul 23 '19 at 16:37
  • it is definitively `hasNext` returning `false` before `next` can be called to throw the exception - just seen on debugger - the catch is that the for-each loop is transformed to a while loop using that methods – user85421 Jul 23 '19 at 16:37
  • FWIW, according to my tests using JDK 12.0.1, it doesn't matter how long the `List` is, i.e. how many elements it contains, removing any element **except** for the second-last element throws `ConcurrentModificationException`. – Abra Jul 23 '19 at 16:40
  • @lucumt I think that https://stackoverflow.com/a/14674151/3182664 explains this pretty well: `next()` (which could throw) is called, then one element is removed, and the `for` loop basically only checks whether the end has been reached (by calling `hasNext`, which does *not* check the mod count or throw). I wonder which details should be added beyond that...?! – Marco13 Jul 23 '19 at 16:40
  • @Marco13 Thanks,I will check it further! – flyingfox Jul 23 '19 at 16:42
  • now the question is: does the iterator break the `ArrayList` contract? "* if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException.*" – user85421 Jul 23 '19 at 16:45
  • @CarlosHeuberger The next paragraph says "Note that the fail-fast behavior of an iterator cannot be guaranteed...", so I'd say "no", although one could certainly nitpick about the wording in view of the part that you quoted. Checking for a CME in the `hasNext` method is probably not worth the effort, usually... – Marco13 Jul 23 '19 at 16:51

0 Answers0