I am trying to understand the below examples and how they behave and they do not really behave as I expect.
Example 1:
Map<Long, String> xx = new HashMap<>();
xx.put(1L, "1");
//Does not throw exception even if the map during iteration is changed
for (String value : xx.values()) {
xx.put(Long.parseLong(value) +1 , value + 1);
}
Example 2:
Map<Long, String> xx = new HashMap<>();
xx.put(1L, "1");
// same operation in stream api and throws exception
xx.values()
.forEach(value -> {
xx.put( Long.parseLong(value) + 1, value + 1);
});
Example 3:
Map<Long, String> xx = new HashMap<>();
xx.put(1L, "1");
// stream api this time does not put a new value but updates the former value and does not throw Concurrent Modification exception
xx.values()
.forEach(value -> {
xx.put( Long.parseLong(value), value + 1);
});
I was pretty confused with the behavior here. I expect first one to throw exception because collection is changed during iteration. I would expect second and third example to throw exception. After seeing the first example, I would expect the second example not to throw exception because it is basically the same thing with first one and first one does not throw exception. I would expect third example to throw exception but it does not.
Can someone explain what is happening here?