Friday 3 October 2014

Java 8 it's easy : Higher-order Function

higher-order what?

Higher-order means that it is possible to pass to a method both values and functions and in the same way the method itself can return either a value or a function.

Example:
   •    public void doSomething(String name, Function someFunction){...}


   •    public Function createAnAction(Integer someInteger)

EASY!!!!


Use case 1:

Print a message with weight information in kilos. 

This is easy : 

package com.marco.higherOrder;
public class Printer {

        public void print(int weight) {
                System.out.println("Printing : your weight is " + weight + " kilos");
        }

        public static void main(String[] args) {
                Printer printer = new Printer();
                printer.print(65);

        }
}

Use case 2:

I need to be able to print different weight unit like stone and pounds.




Ok, just put an if and shut up!!

Putting an if it means to add and pass a boolean and then check that boolean and put a boring if/else.

Also what about open close principle? what if we need to add yet another weight unit?



Higher-order Function to the rescue:

I want a class in charge of handling different weight units :


package com.marco.higherOrder;
public class Scale {

        public String toStones(int weight) {
                return "your weight is " + weight + " stones";
        }

        public String toKilos(int weight) {
                return "the weight is " + weight + " kilos";
        }

        public String toPounds(int weight) {
                return "the weight is " + weight + " pounds";
        }
}

Then I can add a Function in my Printer.print method and pass functions:


package com.marco.higherOrder;
import java.util.function.Function;
public class Printer {

        public void print(int weight, Function<Integer, String> scale) {
                System.out.println("Printing : " + scale.apply(weight));
        }

        public static void main(String[] args) {
                Printer sender = new Printer();
                Scale scale = new Scale();

                sender.print(65, scale::toKilos);

                sender.print(65, scale::toStones);

                sender.print(65, scale::toPounds);

        }
}

Function<Integer, String> means that this function will accept an Integer and will return a String.

 scale::toKilos means that the method toKilos of the scale instance will be called.
EASY!!!!

What if I don't need the Scale class?

Then don't don't it :)!!!


package com.marco.higherOrder;
import java.util.function.Function;
public class Printer {

        public void print(int weight, Function<Integer, String> scale) {
                System.out.println("Printing : " + scale.apply(weight));
        }

        public static void main(String[] args) {
                Printer sender = new Printer();

                sender.print(65, p -> "your weight is " + p + " kilos");

                sender.print(65, p -> "your weight is " + p + " stones");

                sender.print(65, p -> "your weight is " + p + " pounds");

        }
}
p -> "your weight is " + p + " kilos" the p is simply the int that will be passed to the method.





Functional it’s easy , don’t trust who says it’s hard!


Have a great weekend


Ciao.