Example of non-interference in Java 8
Clash Royale CLAN TAG#URR8PPP
up vote
11
down vote
favorite
According to this question, we can modify the source and it's not called interference:
you can modify the stream elements themselves and it should not be called as "interference".
According to this question, the code
List<String> list = new ArrayList<>();
list.add("test");
list.forEach(x -> list.add(x));
will throw ConcurrentModificationException
.
But my code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");return s;).forEach(System.out::print);
doesn't throw ConcurrentModificationException
, even though it in fact changes the source.
And this code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
throws
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at java8.Streams.lambda$0(Streams.java:33)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
So, I don't exactly understand what type of modifications are allowed to the source and what are not. It would be very helpful to see an example which interferes and have a stateful and side-effect producing stream, with proper indication that which is which.
java java-8 java-stream
add a comment |Â
up vote
11
down vote
favorite
According to this question, we can modify the source and it's not called interference:
you can modify the stream elements themselves and it should not be called as "interference".
According to this question, the code
List<String> list = new ArrayList<>();
list.add("test");
list.forEach(x -> list.add(x));
will throw ConcurrentModificationException
.
But my code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");return s;).forEach(System.out::print);
doesn't throw ConcurrentModificationException
, even though it in fact changes the source.
And this code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
throws
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at java8.Streams.lambda$0(Streams.java:33)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
So, I don't exactly understand what type of modifications are allowed to the source and what are not. It would be very helpful to see an example which interferes and have a stateful and side-effect producing stream, with proper indication that which is which.
java java-8 java-stream
1
whoa! lot of answers already. can someone post an example code which contains statefull, interfering,side-effect behavior to get accepted ans answer.please !
– amarnath harish
Aug 27 at 6:49
add a comment |Â
up vote
11
down vote
favorite
up vote
11
down vote
favorite
According to this question, we can modify the source and it's not called interference:
you can modify the stream elements themselves and it should not be called as "interference".
According to this question, the code
List<String> list = new ArrayList<>();
list.add("test");
list.forEach(x -> list.add(x));
will throw ConcurrentModificationException
.
But my code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");return s;).forEach(System.out::print);
doesn't throw ConcurrentModificationException
, even though it in fact changes the source.
And this code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
throws
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at java8.Streams.lambda$0(Streams.java:33)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
So, I don't exactly understand what type of modifications are allowed to the source and what are not. It would be very helpful to see an example which interferes and have a stateful and side-effect producing stream, with proper indication that which is which.
java java-8 java-stream
According to this question, we can modify the source and it's not called interference:
you can modify the stream elements themselves and it should not be called as "interference".
According to this question, the code
List<String> list = new ArrayList<>();
list.add("test");
list.forEach(x -> list.add(x));
will throw ConcurrentModificationException
.
But my code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");return s;).forEach(System.out::print);
doesn't throw ConcurrentModificationException
, even though it in fact changes the source.
And this code,
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos"),
new Employee(2, "Bill Gates"),
new Employee(3, "hendry cavilg"),
new Employee(4, "mark cuban"),
new Employee(5, "zoe"),
new Employee(6, "billl clinton"),
new Employee(7, "ariana") ,
new Employee(8, "cathre"),
new Employee(9, "hostile"),
new Employee(10, "verner"),
;
Employee el=new Employee(1, "Jeff Bezos");
List<Employee> li=Arrays.asList(arrayOfEmps);
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
throws
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at java8.Streams.lambda$0(Streams.java:33)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
So, I don't exactly understand what type of modifications are allowed to the source and what are not. It would be very helpful to see an example which interferes and have a stateful and side-effect producing stream, with proper indication that which is which.
java java-8 java-stream
edited Aug 27 at 19:19


Peter Mortensen
12.9k1983111
12.9k1983111
asked Aug 27 at 6:38
amarnath harish
370212
370212
1
whoa! lot of answers already. can someone post an example code which contains statefull, interfering,side-effect behavior to get accepted ans answer.please !
– amarnath harish
Aug 27 at 6:49
add a comment |Â
1
whoa! lot of answers already. can someone post an example code which contains statefull, interfering,side-effect behavior to get accepted ans answer.please !
– amarnath harish
Aug 27 at 6:49
1
1
whoa! lot of answers already. can someone post an example code which contains statefull, interfering,side-effect behavior to get accepted ans answer.please !
– amarnath harish
Aug 27 at 6:49
whoa! lot of answers already. can someone post an example code which contains statefull, interfering,side-effect behavior to get accepted ans answer.please !
– amarnath harish
Aug 27 at 6:49
add a comment |Â
6 Answers
6
active
oldest
votes
up vote
11
down vote
accepted
When you do this:
li.stream().map(s->s.setName("newname");return s;)
you didn't alter the list itself but an element within this list; so it doesn't trigger a ConcurrentModificationException
as you expected.
In the last code snippet, you are using Array.asList
.
You have to know that Array.asList
returns a mere read-only wrapper over an array (a specific inner ArrayList class) explaining why add
is not supported.
Indeed this inner class does not override AbstractList#add method by design; causing UnsupportedOperationException
; and still not ConcurrentModificationException
as you expected again.
Here's an example similar to your last snippet that does throw a ConcurrentModificationException
:
public static void main(String args)
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos")
;
Employee el = new Employee(11, "Bill Gates");
List<Employee> li = new ArrayList<>(Arrays.asList(arrayOfEmps)); // to avoid read-only restriction
li.stream().peek(s -> li.add(el)).forEach(System.out::print);
Note that I'm wrapping the Arrays.List
return with a "true" ArrayList
, allowing writing because this one implements the add
method ;)
2
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
add a comment |Â
up vote
4
down vote
Your first example changes the existing elements of the Stream
, but doesn't add or remove elements from the source. Therefore it's not an interference.
Your second example attempts to do interference, by adding an element to the source during the Stream
pipeline. However, you get UnsupportedOperationException
instead of ConcurrentModificationException
, since you try to add elements to a fixed sized List
(which is returned by Arrays.asList
).
Change your second example to:
List<Employee> li=new ArrayList<>(Arrays.asList(arrayOfEmps));
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
and you should get ConcurrentModificationException
.
add a comment |Â
up vote
3
down vote
This is called a structural on non-structural change of the source of the Stream
. For example ArrayList
doc says:
merely setting the value of an element is not a structural modification...
So in your example this means that changing Employee
per-se, does not changes the List
itself (does not remove or add an element). But changing the List
itself, will fail with a ConcurrentModificationException
:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.stream().forEach(x -> list.remove(x));
But there are sources where interference is more than OK, called weakly consistent traversal, like ConcurrentHashMap
:
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();
chm.put(1, "one");
chm.put(2, "two");
chm.put(3, "three");
chm.entrySet().stream()
.forEach(x -> chm.remove(x.getKey()));
This will not fail with ConcurrentModificationException
.
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
add a comment |Â
up vote
2
down vote
Your code is modifying the stream element, not the list itself:
s->{s.setName("newname")
changes a field name in the element of the stream, this doesn't interfere with the stream or its source.
The java.lang.UnsupportedOperationException
is also unrelated, it's caused by the fact that you attempt to call add
on a fixed-size list (which is the result of Arrays.asList
).
Any time one calls add
, remove
, etc. on the result of Arrays.asList
, the unsupported operation exception is raised, as the collect is fixed in size.
add a comment |Â
up vote
2
down vote
Your first example does not modify the initial list.
A stream is just a view on the list, therefore the initial list is not at all affected by your stream code.
Whereas the second example makes explicit use of list.add()
.
That is all there is to this.
add a comment |Â
up vote
2
down vote
You can't change the size of the list you are working on.
In the first example you are changing a value of the Employee object inside of your list.
In the second you are adding an item in your list.
That's the difference!
add a comment |Â
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
11
down vote
accepted
When you do this:
li.stream().map(s->s.setName("newname");return s;)
you didn't alter the list itself but an element within this list; so it doesn't trigger a ConcurrentModificationException
as you expected.
In the last code snippet, you are using Array.asList
.
You have to know that Array.asList
returns a mere read-only wrapper over an array (a specific inner ArrayList class) explaining why add
is not supported.
Indeed this inner class does not override AbstractList#add method by design; causing UnsupportedOperationException
; and still not ConcurrentModificationException
as you expected again.
Here's an example similar to your last snippet that does throw a ConcurrentModificationException
:
public static void main(String args)
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos")
;
Employee el = new Employee(11, "Bill Gates");
List<Employee> li = new ArrayList<>(Arrays.asList(arrayOfEmps)); // to avoid read-only restriction
li.stream().peek(s -> li.add(el)).forEach(System.out::print);
Note that I'm wrapping the Arrays.List
return with a "true" ArrayList
, allowing writing because this one implements the add
method ;)
2
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
add a comment |Â
up vote
11
down vote
accepted
When you do this:
li.stream().map(s->s.setName("newname");return s;)
you didn't alter the list itself but an element within this list; so it doesn't trigger a ConcurrentModificationException
as you expected.
In the last code snippet, you are using Array.asList
.
You have to know that Array.asList
returns a mere read-only wrapper over an array (a specific inner ArrayList class) explaining why add
is not supported.
Indeed this inner class does not override AbstractList#add method by design; causing UnsupportedOperationException
; and still not ConcurrentModificationException
as you expected again.
Here's an example similar to your last snippet that does throw a ConcurrentModificationException
:
public static void main(String args)
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos")
;
Employee el = new Employee(11, "Bill Gates");
List<Employee> li = new ArrayList<>(Arrays.asList(arrayOfEmps)); // to avoid read-only restriction
li.stream().peek(s -> li.add(el)).forEach(System.out::print);
Note that I'm wrapping the Arrays.List
return with a "true" ArrayList
, allowing writing because this one implements the add
method ;)
2
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
add a comment |Â
up vote
11
down vote
accepted
up vote
11
down vote
accepted
When you do this:
li.stream().map(s->s.setName("newname");return s;)
you didn't alter the list itself but an element within this list; so it doesn't trigger a ConcurrentModificationException
as you expected.
In the last code snippet, you are using Array.asList
.
You have to know that Array.asList
returns a mere read-only wrapper over an array (a specific inner ArrayList class) explaining why add
is not supported.
Indeed this inner class does not override AbstractList#add method by design; causing UnsupportedOperationException
; and still not ConcurrentModificationException
as you expected again.
Here's an example similar to your last snippet that does throw a ConcurrentModificationException
:
public static void main(String args)
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos")
;
Employee el = new Employee(11, "Bill Gates");
List<Employee> li = new ArrayList<>(Arrays.asList(arrayOfEmps)); // to avoid read-only restriction
li.stream().peek(s -> li.add(el)).forEach(System.out::print);
Note that I'm wrapping the Arrays.List
return with a "true" ArrayList
, allowing writing because this one implements the add
method ;)
When you do this:
li.stream().map(s->s.setName("newname");return s;)
you didn't alter the list itself but an element within this list; so it doesn't trigger a ConcurrentModificationException
as you expected.
In the last code snippet, you are using Array.asList
.
You have to know that Array.asList
returns a mere read-only wrapper over an array (a specific inner ArrayList class) explaining why add
is not supported.
Indeed this inner class does not override AbstractList#add method by design; causing UnsupportedOperationException
; and still not ConcurrentModificationException
as you expected again.
Here's an example similar to your last snippet that does throw a ConcurrentModificationException
:
public static void main(String args)
Employee arrayOfEmps =
new Employee(1, "Jeff Bezos")
;
Employee el = new Employee(11, "Bill Gates");
List<Employee> li = new ArrayList<>(Arrays.asList(arrayOfEmps)); // to avoid read-only restriction
li.stream().peek(s -> li.add(el)).forEach(System.out::print);
Note that I'm wrapping the Arrays.List
return with a "true" ArrayList
, allowing writing because this one implements the add
method ;)
edited Aug 27 at 7:22
answered Aug 27 at 6:44


Mik378
15.6k1353133
15.6k1353133
2
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
add a comment |Â
2
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
2
2
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
this is also called a non-structural modification
– Eugene
Aug 27 at 9:05
add a comment |Â
up vote
4
down vote
Your first example changes the existing elements of the Stream
, but doesn't add or remove elements from the source. Therefore it's not an interference.
Your second example attempts to do interference, by adding an element to the source during the Stream
pipeline. However, you get UnsupportedOperationException
instead of ConcurrentModificationException
, since you try to add elements to a fixed sized List
(which is returned by Arrays.asList
).
Change your second example to:
List<Employee> li=new ArrayList<>(Arrays.asList(arrayOfEmps));
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
and you should get ConcurrentModificationException
.
add a comment |Â
up vote
4
down vote
Your first example changes the existing elements of the Stream
, but doesn't add or remove elements from the source. Therefore it's not an interference.
Your second example attempts to do interference, by adding an element to the source during the Stream
pipeline. However, you get UnsupportedOperationException
instead of ConcurrentModificationException
, since you try to add elements to a fixed sized List
(which is returned by Arrays.asList
).
Change your second example to:
List<Employee> li=new ArrayList<>(Arrays.asList(arrayOfEmps));
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
and you should get ConcurrentModificationException
.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Your first example changes the existing elements of the Stream
, but doesn't add or remove elements from the source. Therefore it's not an interference.
Your second example attempts to do interference, by adding an element to the source during the Stream
pipeline. However, you get UnsupportedOperationException
instead of ConcurrentModificationException
, since you try to add elements to a fixed sized List
(which is returned by Arrays.asList
).
Change your second example to:
List<Employee> li=new ArrayList<>(Arrays.asList(arrayOfEmps));
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
and you should get ConcurrentModificationException
.
Your first example changes the existing elements of the Stream
, but doesn't add or remove elements from the source. Therefore it's not an interference.
Your second example attempts to do interference, by adding an element to the source during the Stream
pipeline. However, you get UnsupportedOperationException
instead of ConcurrentModificationException
, since you try to add elements to a fixed sized List
(which is returned by Arrays.asList
).
Change your second example to:
List<Employee> li=new ArrayList<>(Arrays.asList(arrayOfEmps));
li.stream().map(s->s.setName("newname");li.add(s);return s;).limit(10).forEach(System.out::print);
and you should get ConcurrentModificationException
.
answered Aug 27 at 6:43


Eran
262k33406490
262k33406490
add a comment |Â
add a comment |Â
up vote
3
down vote
This is called a structural on non-structural change of the source of the Stream
. For example ArrayList
doc says:
merely setting the value of an element is not a structural modification...
So in your example this means that changing Employee
per-se, does not changes the List
itself (does not remove or add an element). But changing the List
itself, will fail with a ConcurrentModificationException
:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.stream().forEach(x -> list.remove(x));
But there are sources where interference is more than OK, called weakly consistent traversal, like ConcurrentHashMap
:
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();
chm.put(1, "one");
chm.put(2, "two");
chm.put(3, "three");
chm.entrySet().stream()
.forEach(x -> chm.remove(x.getKey()));
This will not fail with ConcurrentModificationException
.
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
add a comment |Â
up vote
3
down vote
This is called a structural on non-structural change of the source of the Stream
. For example ArrayList
doc says:
merely setting the value of an element is not a structural modification...
So in your example this means that changing Employee
per-se, does not changes the List
itself (does not remove or add an element). But changing the List
itself, will fail with a ConcurrentModificationException
:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.stream().forEach(x -> list.remove(x));
But there are sources where interference is more than OK, called weakly consistent traversal, like ConcurrentHashMap
:
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();
chm.put(1, "one");
chm.put(2, "two");
chm.put(3, "three");
chm.entrySet().stream()
.forEach(x -> chm.remove(x.getKey()));
This will not fail with ConcurrentModificationException
.
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
add a comment |Â
up vote
3
down vote
up vote
3
down vote
This is called a structural on non-structural change of the source of the Stream
. For example ArrayList
doc says:
merely setting the value of an element is not a structural modification...
So in your example this means that changing Employee
per-se, does not changes the List
itself (does not remove or add an element). But changing the List
itself, will fail with a ConcurrentModificationException
:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.stream().forEach(x -> list.remove(x));
But there are sources where interference is more than OK, called weakly consistent traversal, like ConcurrentHashMap
:
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();
chm.put(1, "one");
chm.put(2, "two");
chm.put(3, "three");
chm.entrySet().stream()
.forEach(x -> chm.remove(x.getKey()));
This will not fail with ConcurrentModificationException
.
This is called a structural on non-structural change of the source of the Stream
. For example ArrayList
doc says:
merely setting the value of an element is not a structural modification...
So in your example this means that changing Employee
per-se, does not changes the List
itself (does not remove or add an element). But changing the List
itself, will fail with a ConcurrentModificationException
:
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.stream().forEach(x -> list.remove(x));
But there are sources where interference is more than OK, called weakly consistent traversal, like ConcurrentHashMap
:
ConcurrentHashMap<Integer, String> chm = new ConcurrentHashMap<>();
chm.put(1, "one");
chm.put(2, "two");
chm.put(3, "three");
chm.entrySet().stream()
.forEach(x -> chm.remove(x.getKey()));
This will not fail with ConcurrentModificationException
.
answered Aug 27 at 11:04


Eugene
58.8k979138
58.8k979138
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
add a comment |Â
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
thanks eugene i understood.
– amarnath harish
Aug 27 at 11:07
add a comment |Â
up vote
2
down vote
Your code is modifying the stream element, not the list itself:
s->{s.setName("newname")
changes a field name in the element of the stream, this doesn't interfere with the stream or its source.
The java.lang.UnsupportedOperationException
is also unrelated, it's caused by the fact that you attempt to call add
on a fixed-size list (which is the result of Arrays.asList
).
Any time one calls add
, remove
, etc. on the result of Arrays.asList
, the unsupported operation exception is raised, as the collect is fixed in size.
add a comment |Â
up vote
2
down vote
Your code is modifying the stream element, not the list itself:
s->{s.setName("newname")
changes a field name in the element of the stream, this doesn't interfere with the stream or its source.
The java.lang.UnsupportedOperationException
is also unrelated, it's caused by the fact that you attempt to call add
on a fixed-size list (which is the result of Arrays.asList
).
Any time one calls add
, remove
, etc. on the result of Arrays.asList
, the unsupported operation exception is raised, as the collect is fixed in size.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Your code is modifying the stream element, not the list itself:
s->{s.setName("newname")
changes a field name in the element of the stream, this doesn't interfere with the stream or its source.
The java.lang.UnsupportedOperationException
is also unrelated, it's caused by the fact that you attempt to call add
on a fixed-size list (which is the result of Arrays.asList
).
Any time one calls add
, remove
, etc. on the result of Arrays.asList
, the unsupported operation exception is raised, as the collect is fixed in size.
Your code is modifying the stream element, not the list itself:
s->{s.setName("newname")
changes a field name in the element of the stream, this doesn't interfere with the stream or its source.
The java.lang.UnsupportedOperationException
is also unrelated, it's caused by the fact that you attempt to call add
on a fixed-size list (which is the result of Arrays.asList
).
Any time one calls add
, remove
, etc. on the result of Arrays.asList
, the unsupported operation exception is raised, as the collect is fixed in size.
answered Aug 27 at 6:43
ernest_k
13.5k31427
13.5k31427
add a comment |Â
add a comment |Â
up vote
2
down vote
Your first example does not modify the initial list.
A stream is just a view on the list, therefore the initial list is not at all affected by your stream code.
Whereas the second example makes explicit use of list.add()
.
That is all there is to this.
add a comment |Â
up vote
2
down vote
Your first example does not modify the initial list.
A stream is just a view on the list, therefore the initial list is not at all affected by your stream code.
Whereas the second example makes explicit use of list.add()
.
That is all there is to this.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Your first example does not modify the initial list.
A stream is just a view on the list, therefore the initial list is not at all affected by your stream code.
Whereas the second example makes explicit use of list.add()
.
That is all there is to this.
Your first example does not modify the initial list.
A stream is just a view on the list, therefore the initial list is not at all affected by your stream code.
Whereas the second example makes explicit use of list.add()
.
That is all there is to this.
answered Aug 27 at 6:44


GhostCat
81.6k1578135
81.6k1578135
add a comment |Â
add a comment |Â
up vote
2
down vote
You can't change the size of the list you are working on.
In the first example you are changing a value of the Employee object inside of your list.
In the second you are adding an item in your list.
That's the difference!
add a comment |Â
up vote
2
down vote
You can't change the size of the list you are working on.
In the first example you are changing a value of the Employee object inside of your list.
In the second you are adding an item in your list.
That's the difference!
add a comment |Â
up vote
2
down vote
up vote
2
down vote
You can't change the size of the list you are working on.
In the first example you are changing a value of the Employee object inside of your list.
In the second you are adding an item in your list.
That's the difference!
You can't change the size of the list you are working on.
In the first example you are changing a value of the Employee object inside of your list.
In the second you are adding an item in your list.
That's the difference!
edited Aug 27 at 19:20


Peter Mortensen
12.9k1983111
12.9k1983111
answered Aug 27 at 6:43


Leviand
1,1231019
1,1231019
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52033763%2fexample-of-non-interference-in-java-8%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
whoa! lot of answers already. can someone post an example code which contains statefull, interfering,side-effect behavior to get accepted ans answer.please !
– amarnath harish
Aug 27 at 6:49