Why do we need to avoid mutations while coding? What is a mutation?

codeme picture codeme · Jun 5, 2015 · Viewed 15.7k times · Source

Why is the second code (the one with the stream) a better solution than the first?

First :

public static void main(String [] args) {
   List<Integer> values = Arrays.asList(1,2,3,4,5,6);
   int total = 0;
   for(int e : values) {
       total += e * 2;

   }

Second :

   System.out.println(total);
   System.out.println(
           values.stream()
           .map(e-> e*2)
           .reduce(0, (c, e)-> c + e)); 

Answer

Sylwester picture Sylwester · Jun 5, 2015

Mutation is changing an object and is one common side effect in programming languages.

A method that has a functional contract will always return the same value to the same arguments and have no other side effects (like storing file, printing, reading). Thus even if you mutate temporary values inside your function it's still pure from the outside. By putting your first example in a function demonstrates it:

public static int squareSum(const List<Integer> values)
{
    int total = 0;
    for(int e : values) {
        total += e * 2;  // mutates a local variable
    }
    return total;
}

A purely functional method doesn't even update local variables. If you put the second version in a function it would be pure:

public static int squareSum(const List<Integer> values)
{
    return values.stream()
           .map(e-> e*2)
           .reduce(0, (c, e)-> c + e);
}

For a person that knows other languages that has long been preferring a functional style map and reduce with lambda is very natural. Both versions are easy to read and easy to test, which is the most important part.

Java has functional classes. java.lang.String is one of them.