Sunday 10 February 2019

Functional Programming using Java 8

Functional Programming using Java 8


Java 8 brings the power of functional programming. Let's dig into the java code library and understand it better.

Let's create a small application called Adder which can take a few types of java wrappers and add those and return a result.

1. Create a Java interface called Adder as below. Here I, J are the type of input arguments and R is the type of return 


public interface Adder<I, J, R> {
    public R add(I arg1, J arg2); 
}

2. Create another java class called TraditionalDifferentAdders and a few implementations of Adder interface. This is a java traditional implementation of an interface and uses it in code.


import java.math.BigDecimal;

public class TraditionalDifferentAdders {
 
 public static void main(String[] args) {
  Adder<Integer, Integer, Integer> integerAdder = 
                     new TraditionalDifferentAdders().new IntergerAdder();
  System.out.println(integerAdder.add(10, 20));
  
  Adder<Double, Double, Double> doubleAdder = 
                     new TraditionalDifferentAdders().new DoubleAdder();
  System.out.println(doubleAdder.add(10.0, 20.0));
  
  Adder<BigDecimal, BigDecimal, BigDecimal> bigDecimalAdder = 
                     new TraditionalDifferentAdders().new BigDecimalAdder();
  System.out.println(bigDecimalAdder.add(new BigDecimal(10 ), new BigDecimal(20)));
  
  Adder<String, String, String> stringAdder = 
                    new TraditionalDifferentAdders().new StringAdder();
  System.out.println(stringAdder.add("10", "20"));
  
 }
 
 class IntergerAdder implements Adder<Integer, Integer, Integer>{

  @Override
  public Integer add(Integer arg1, Integer arg2) {
   return arg1 + arg2;
  }
  
 }
 
 class DoubleAdder implements Adder<Double, Double, Double>{

  @Override
  public Double add(Double arg1, Double arg2) {
   return arg1 + arg2;
  }
  
 }
 
 class BigDecimalAdder implements Adder<BigDecimal, BigDecimal, BigDecimal>{

  @Override
  public BigDecimal add(BigDecimal arg1, BigDecimal arg2) {
   return arg1.add(arg2);
  }
  
 }
 
 class StringAdder implements Adder<String, String, String>{

  @Override
  public String add(String arg1, String arg2) {
   return arg1.concat(arg2);
  }
  
 }
 
}


3. Let us simplify it by using anonymous inner classes. This will improve the code readability and reduce a few lines of codes.



import java.math.BigDecimal;

public class AnonymousAdders {
 
 public static void main(String[] args) {
 
  Adder<Integer, Integer, Integer> integerAdder = 
    new Adder<Integer, Integer, Integer>() {
   @Override
   public Integer add(Integer arg1, Integer arg2) {
    return arg1 + arg2;
   }
  };
  
  System.out.println(integerAdder.add(10, 20));
  
  Adder<Double, Double, Double> doubleAdder = 
    new Adder<Double, Double, Double>(){
   
   @Override
   public Double add(Double arg1, Double arg2) {
    return arg1 + arg2;
   }
  };
  
  System.out.println(doubleAdder.add(10.0, 20.0));
  
  Adder<BigDecimal, BigDecimal, BigDecimal> bigDecimalAdder = 
    new Adder<BigDecimal, BigDecimal, BigDecimal>() {
   
   @Override
   public BigDecimal add(BigDecimal arg1, BigDecimal arg2) {
    return arg1.add(arg2);
   }
   
  };
  System.out.println(bigDecimalAdder.add(new BigDecimal(10 ), new BigDecimal(20)));
  
  Adder<String, String, String> stringAdder = new Adder<String, String, String>() {
   @Override
   public String add(String arg1, String arg2) {
    return arg1.concat("+").concat(arg2);
   }
  };
  
  System.out.println(stringAdder.add("10", "20"));
    
 }

}


4. Let us further simplify this by using a Lambda adder



import java.math.BigDecimal;

public class LamdaAdder {
 
 public static void main(String[] args) {
  
  /*
    Way to reduce the unwanted codes from Lamda functions
    
   Adder<Integer, Integer, Integer> integerAdder = 
    (Integer arg1, Integer arg2) -> { return arg1 + arg2;};
  
  Adder<Integer, Integer, Integer> integerAdder = 
    (Integer arg1, Integer arg2) -> arg1 + arg2;
    
   */
  
  Adder<Integer, Integer, Integer> integerAdder = 
    (arg1, arg2) -> arg1 + arg2;
  
  System.out.println(integerAdder.add(10, 20));
  
  Adder<Double, Double, Double> doubleAdder = 
    (arg1, arg2) -> arg1 + arg2;
  System.out.println(doubleAdder.add(10.0, 20.0));
  
  Adder<BigDecimal, BigDecimal, BigDecimal> bigDecimalAdder = 
    (arg1, arg2) -> arg1.add(arg2);
  System.out.println(bigDecimalAdder.add(new BigDecimal(10 ), new BigDecimal(20)));
  
  Adder<String, String, String> stringAdder = (arg1, arg2) -> arg1 + arg2;
  System.out.println(stringAdder.add("10", "20"));
  
 }

}

5. Let us further tweak it by removing the Adder interface



import java.math.BigDecimal;
import java.util.function.BiFunction;

public class FunctionalInterfaceAdder {
 
 
 public static void main(String[] args) {
  
  BiFunction<Integer, Integer, Integer> integerAdder = 
    (arg1, arg2) -> arg1 + arg2;
  System.out.println(integerAdder.apply(10, 20));
  
  BiFunction<Double, Double, Double> doubleAdder = 
    (arg1, arg2) -> arg1 + arg2;
  System.out.println(doubleAdder.apply(10.0, 20.0));
  
  BiFunction<BigDecimal, BigDecimal, BigDecimal> bigDecimalAdder = 
    (arg1, arg2) -> arg1.add(arg2);
  System.out.println(bigDecimalAdder.apply(new BigDecimal(10 ), new BigDecimal(20)));
  
  BiFunction<String, String, String> stringAdder = 
    (arg1, arg2) -> arg1 + arg2;
  System.out.println(stringAdder.apply("10", "20"));
  
 }

}


By looking at the above code, it is very clear that if we use functional interfaces, our code looks neat and clean. There are several other advantages like we can pass the functional interfaces as an argument to functions. Also, we can return the same.


No comments:

Post a Comment