On Jun 14, 2013, at 2:41 PM, Remi Forax <[email protected]> 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.