On Jun 14, 2013, at 2:41 PM, Remi Forax <fo...@univ-mlv.fr> wrote: >> >>>> It would be a shame for overriding forEach/forEachRemaining >>>> implementations to conform to such behaviour when they can implement >>>> stronger/consistent failure guarantees. >>> While I could agree with you in theory, in practice I have seen several >>> times codes that rely on this behaviour, >>> usually there is a bunch of method calls between the for loop and the >>> list.remove() so this is not something that can be easily fixed. >> A bug none the less, yes? > > In the codes I was referring to, there was always a way to know that the > remove was done at the end by example by knowing that the last element was a > special sentinel or by using a counter. > So is the following program bugged ? >
No, but gives off an unpleasant odour. > List<Integer> l = new ArrayList<>(Arrays.asList(1, 2, null)); > for (Integer i : l) { > if (i == null) { > l.set(l.size() - 1, 3); // change the last value to 3 > } > } > This works fine: List<Integer> l = new ArrayList<>(Arrays.asList(1, 2, null)); l.forEach(e -> { if (e == null) { l.set(l.size() - 1, 3); // change the last value to 3 } }); The reason being is set() is not a structural modification. There is a grey area here to what constitutes a co-modification but usually the line is drawn at anything that structurally modifies the collection's data structure. Paul.