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.

Reply via email to