RFR : 8016446 : (m) Add override forEach/replaceAll to HashMap, Hashtable, IdentityHashMap, WeakHashMap, TreeMap
Paul Sandoz
paul.sandoz at oracle.com
Fri Jun 14 13:19:55 UTC 2013
On Jun 14, 2013, at 2:41 PM, Remi Forax <forax at 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.
More information about the core-libs-dev
mailing list