Example of non-interference in Java 8

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
11
down vote

favorite
1












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.







share|improve this question


















  • 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














up vote
11
down vote

favorite
1












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.







share|improve this question


















  • 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












up vote
11
down vote

favorite
1









up vote
11
down vote

favorite
1






1





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.







share|improve this question














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.









share|improve this question













share|improve this question




share|improve this question








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












  • 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












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 ;)






share|improve this answer


















  • 2




    this is also called a non-structural modification
    – Eugene
    Aug 27 at 9:05


















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.






share|improve this answer



























    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.






    share|improve this answer




















    • thanks eugene i understood.
      – amarnath harish
      Aug 27 at 11:07

















    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.






    share|improve this answer



























      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.






      share|improve this answer



























        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!






        share|improve this answer






















          Your Answer





          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          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






























          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 ;)






          share|improve this answer


















          • 2




            this is also called a non-structural modification
            – Eugene
            Aug 27 at 9:05















          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 ;)






          share|improve this answer


















          • 2




            this is also called a non-structural modification
            – Eugene
            Aug 27 at 9:05













          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 ;)






          share|improve this answer














          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 ;)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          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













          • 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













          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.






          share|improve this answer
























            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.






            share|improve this answer






















              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.






              share|improve this answer












              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.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Aug 27 at 6:43









              Eran

              262k33406490




              262k33406490




















                  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.






                  share|improve this answer




















                  • thanks eugene i understood.
                    – amarnath harish
                    Aug 27 at 11:07














                  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.






                  share|improve this answer




















                  • thanks eugene i understood.
                    – amarnath harish
                    Aug 27 at 11:07












                  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.






                  share|improve this answer












                  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.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 27 at 11:04









                  Eugene

                  58.8k979138




                  58.8k979138











                  • 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




                  thanks eugene i understood.
                  – amarnath harish
                  Aug 27 at 11:07










                  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.






                  share|improve this answer
























                    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.






                    share|improve this answer






















                      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.






                      share|improve this answer












                      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.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Aug 27 at 6:43









                      ernest_k

                      13.5k31427




                      13.5k31427




















                          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.






                          share|improve this answer
























                            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.






                            share|improve this answer






















                              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.






                              share|improve this answer












                              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.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Aug 27 at 6:44









                              GhostCat

                              81.6k1578135




                              81.6k1578135




















                                  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!






                                  share|improve this answer


























                                    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!






                                    share|improve this answer
























                                      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!






                                      share|improve this answer














                                      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!







                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Aug 27 at 19:20









                                      Peter Mortensen

                                      12.9k1983111




                                      12.9k1983111










                                      answered Aug 27 at 6:43









                                      Leviand

                                      1,1231019




                                      1,1231019



























                                           

                                          draft saved


                                          draft discarded















































                                           


                                          draft saved


                                          draft discarded














                                          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













































































                                          Comments

                                          Popular posts from this blog

                                          What does second last employer means? [closed]

                                          List of Gilmore Girls characters

                                          One-line joke