Google

Aug 1, 2014

Top 8 things you must know about Java 8 to start coding on the job and talking at the job interviews

Are you ready to get cracking with Java 8 new features? Here are a comprehensive Java 8 features, tutorials, and examples. Drill down into each.

#1: Transforming your thinking from OOP to FOP: One needs to get used to the transformation from imperative programming to functional  programming. You like it or not, you will be using functional programming in Java 8, and interviewers are going to quiz you on functional programming. Fortunately, Java is not a fully functional programming language, and hence one does not require the full leap to functional programming. Java 8 supports both imperative and functional programming approaches.


#2: Here are top 6 Java 8 features you can start using now by downloading Java 8. 


  1. Interface can have static and default methods.
  2. Lambda expression for supporting closures.
  3. Java 8 adopts Joda. 
  4. Java 8 corrects its lack of good support for JavaScript with the engine Nashorn. 
  5. Parallel processing piggy backing the Java 7 Fork/Join.
  6. The java.util.concurrent.atomic package has been expanded to include four new classes -- LongAccumulator, LongAdder, DoubleAccumulator and DoubleAdder




#3: Writing functional programs with Java 8 with simple examples. 

The Operate interface with the annotation @FunctionalInterface. This annotation ensures that you can only have a single abstract method (aka SAM). You can have additional default and static method implementations. The default methods provide default behaviors, and the closures are used to have  special behaviors. The static methods are used as helper methods. 

So, no longer you need to have the pre Java 8 patterns like


  • java.utilCollection is an interface and java.util.Collections is utility class with helper methods
  • java.nio.file.Path is an interface  and java.nio.file.Paths is a helper class.



Thanks to Java 8 as you can have static helper methods. 

#4: 7 useful Java 8 miscellaneous additions worth knowing and talking about in the job interviews if asked. 


  1. String.join( ) method, which is an opposite of String.split(...). 
  2. Comparator interfaces have a number of useful methods to sort objects with options to nest multiple fields with thenComparing(...), and other handy methods like nullsFirst( ), nullsLast( ), naturalOrder( ), reverseOrder( ), etc.
  3. In Java 8, java.util.Optional class has been added to deal with optional object references.
  4. In cases where you want to detect result overflow errors in int and long, the methods addExact, subtractExact, multiplyExact, and toIntExact in Java 8, the java.lang.Math class throws an ArithmeticException when the results overflow. 
  5. The ability to lazily read lines from a file with Files.lines(...).
  6. In Java 8, you can repeat the same annotation with the @Repeatable annotation. 
  7. Java 8 introduces the "Type Annotations", which are annotations that can be placed anywhere you use a type.



  1. Java library Comparator pre Java 8
  2. Apache commons library BeanComparator pre Java 8
  3. Google Gauva library functional programming style Pre Java 8
  4. Java 8 functional programming approach. Concise and powerful.


#6: Java 8 functional programming is not a silver bullet. Where does it really shine? When will you use it?

  1. Where the functional code has increased readability and maintainability
  2. Where performance improvement is possible with Fork/Join parallel processing.
  3. Where code becomes easier to refactor in the future
  4. Where the code is easier to test and debug.

So, OO programming and functional programming can co-exist.


#7: Understanding Java 8 Streams. A stream is an infinite sequence of consumable elements (i.e a data structure) for the consumption of an operation or iteration. Any Collection can be exposed as a stream. The operations you perform on a stream can either be intermediate (map, filter, sorted, limit, skip,concat, substream, distinct, etc) producing another stream or terminal (forEach, reduce, collect, sum, max, count, matchAny, findFirst, findAny, etc) producing an object that is not a stream. Basically, you are building a pipeline as in Unix.

ls -l | grep "Dec" | Sort +4n | more


#8: Using the Predicate functional interface. The java.util.function package in Java 8 has a number of functional interfaces, and Predicate interface  is used for filtering objects from a collection.


Labels:

Java 8 using the Predicate functional interface

The java.util.function package in Java 8 has a number of functional interfaces. Let's look at the Predicate<T> interface that is used for filtering objects from a collection. If you are using a Java version pre Java 8 refer Creating sub lists from a list using predicates to filter.

Here is the Java 8 example:

Step 1: Create a Driver domain class using the builder design pattern. Refer How to create elegant immutable objects in Java for the Driver code.


public class Driver {
 enum SEX {
  MALE, FEMALE
 }

 private String name;
 private int age;
 private SEX sex;

    //builder, and getters,
 
}

If not sure how to apply the builder design pattern to the Driver class.

Step 2: Define a static method to have methods that return Predicates via static methods.

package com.java8.examples;

import java.util.function.Predicate;

public class DriverPredicate {

 public static Predicate<Driver> isEligibleForDriving() {
  return p -> p.getAge() > 18;
 }

 public static Predicate<Driver> isEligibleMaleDriver() {
  return p -> p.getAge() > 18 && p.getSex() == Driver.SEX.MALE;
 }
 
}




Step 3: Create sub lists using the predicates. It is much easier to create sub lists in Java 8.

package com.java8.examples;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DriverTest {

 public static void main(String[] args) {
  List<Driver> drivers = Arrays.asList(
    new Driver.Builder().name("John").age(34).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("James").age(24).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("Samantha").age(16).sex(Driver.SEX.FEMALE).build()
  );

  
  //using the predicates
  List<Driver> eligibleDriverList = drivers.stream().filter(DriverPredicate.isEligibleForDriving())
    .collect(Collectors.toList());

  List<Driver> eligibleMaleDriverList = drivers.stream().filter(DriverPredicate.isEligibleMaleDriver())
    .collect(Collectors.toList());
  
  System.out.println("eligibleDriverList-->" + eligibleDriverList);
  System.out.println("eligibleMaleDriverList-->" + eligibleMaleDriverList);
  
 }

}


Output:

eligibleDriverList-->[Driver [name=John, age=34, sex=MALE], Driver [name=James, age=24, sex=MALE]]
eligibleMaleDriverList-->[Driver [name=John, age=34, sex=MALE], Driver [name=James, age=24, sex=MALE]]


Optional: You could have written the above trivial code without the DriverPredicate class as shown below. But, in industrial strength applications, you will end up violation the DRY (Don't Repeat Yourself) principle by repeating the filter logic in lambda expressions in multiple places. If the rule changes, you need to modify it in multiple locations.


package com.java8.examples;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class DriverTest {

 public static void main(String[] args) {
  List<Driver> drivers = Arrays.asList(
    new Driver.Builder().name("John").age(34).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("James").age(24).sex(Driver.SEX.MALE).build(),
    new Driver.Builder().name("Samantha").age(16).sex(Driver.SEX.FEMALE).build()
  );

  
  //using the predicates
  List<Driver> eligibleDriverList = drivers.stream().filter(p -> p.getAge() > 18)
    .collect(Collectors.toList());

  List<Driver> eligibleMaleDriverList = drivers.stream().filter(p -> p.getAge() > 18 && p.getSex() == Driver.SEX.MALE)
    .collect(Collectors.toList());
  
  System.out.println("eligibleDriverList-->" + eligibleDriverList);
  System.out.println("eligibleMaleDriverList-->" + eligibleMaleDriverList);
  
 }

}

Labels: ,

May 27, 2014

Learning to write functional programming with Java 8 with examples -- part 2

In the last post I created custom functional interfaces to explain functional programming, closure, and lambda expressions in Java 8. This post gives Java 8 API examples using lambda expressions and functional programming.

Example 1: The java.lang.Runnable interface has been made a functional interface.


package com.java8.examples;

public class Example1 {
 
 public static void main(String[] args) {
   System.out.println("main thread: " + Thread.currentThread().getName());
   
   //run method takes no arguments so: () -> (body)
   //closure worker thread1
   Runnable r = () -> (System.out.println("worker thread: " + Thread.currentThread().getName())); 
   new Thread(r).start(); //pass the Runnable closure to Thread constructor
   
   //closure worker thread2
   new Thread( () -> (System.out.println("worker thread: " + Thread.currentThread().getName()))).start(); 
 }
}


Output:

main thread: main
worker thread: Thread-0
worker thread: Thread-1


Example 2: The java.util.function package has a number of functional interfaces.

package com.java8.examples;

import java.util.function.Consumer;

public class Example2 {
 
  public static void main(String[] args) {
   //closure of Consumer 1. the accept(T t) method takes Integer here
   Consumer<Integer>  c1 = (x) -> {System.out.println("consumed: " + x);};
   //closure of Consumer 2. x is an Integer  
   Consumer<Integer>  c2 = (x) -> {System.out.println("consumed: " + x*x);};

   
   c1.accept(5);
   c2.accept(5);
   
   //andThen is a default method implementation in Consumer interface
   Consumer<Integer> c3 = c1.andThen(c2);
   c3.accept(6);
 }
}

Output:

consumed: 5
consumed: 25
consumed: 6
consumed: 36


Example 3: The Function&ltT, R> is similar to Consumer<T>, but the Function interface has a return value in its apply(T t) method, whereas the Consumer  has a void method accept(T t).

package com.java8.examples;

import java.util.function.Function;

public class Example3 {
 
  public static void main(String[] args) {
   //closure of Function.  apply(T t) method takes Double here
   Function<Double, Double>  c1 = (arg) -> (arg + arg);
   Function<Double, Double>  c2 = (arg) -> (arg * arg);
  
   Double result1 = c1.apply(5.0);
   Double result2 = c2.apply(5.0);
   
   System.out.println("result1= " + result1);
   System.out.println("result2= " + result2);
   
   //andThen is a default method implementation in Function interface
   Function<Double, Double> c3 = c1.andThen(c2);
   Double result3 = c3.apply(6.0);
   
   System.out.println("result3= " + result3);// 6 + 6 = 12, 12 * 12 = 144;
   
 }
}


Output:

result1= 10.0
result2= 25.0
result3= 144.0


Example 4: The Predicate<T> interface from java.util.function package has test(T t) method that returns a boolean value indicating test condition has passed or failed. The predicates are often used to  filter a collection of objects.

package com.java8.examples;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Example4 {
 
 private static final int SHORT_NAME_LENGTH = 3;
 
 public static void main(String[] args) {
  
  List<String> languages = Arrays.asList("Java", "C++", "PHP", "C#", "Scala", "JRuby", "Jython");
  
  //The Predicate interface has test(T t) that returns a boolean
  Predicate<String> shortNamePredicate = (s) -> (s.length() <= SHORT_NAME_LENGTH); // closure
  
 
  Predicate<String> startsWithCPredicate = (s) -> (s.startsWith("J")); //closure
  
  languages.stream()
           .filter(shortNamePredicate)
           .forEach(e -> System.out.println("short names: " + e));
  
  languages.stream()
           .filter(startsWithCPredicate)
           .forEach(e -> System.out.println("starts with J: " + e));
   
 }
}


Output:

short names: C++
short names: PHP
short names: C#
starts with J: Java
starts with J: JRuby
starts with J: Jython


There are more examples relating working with Java collection -> Understanding Java 8 Streams and working with collections using Lambda expressions

Labels: ,

May 26, 2014

Learning to write functional programming with Java 8 with examples -- part 1

In the earlier post entitled  Understanding Java 8 Lambda expressions with working examples -- part 1, we looked at Summable example to illustrate functional programming. In this tutorial, I will go in more detail with similar examples with scenarios. The example is a a simple arithmetic operation.

Scenario 1:  The Operate interface with the annotation @FunctionalInterface. This annotation ensures that you can only have a single abstract method. You can have additional default and static method implementations.

Step 1: Define the interface. It is an abstract method by default, and  @FunctionalInterface ensures that you can only define a Single Abstract Method (aka SAM).


package com.java8.examples;

@FunctionalInterface
public interface Operation {
    int operate(int operand1, int operand2); 
}

Step 2: The OperationTest class that uses the functional interface with lambda expressions like (x, y) -> (x + y); and  (x, y) -> (x * y) to add and multiply respectively. The method name operate(int operand1, int operand2) is not explictly called as the compiler knows to work it out from the parameters passed int operand1, int operand2 which method to invoke.

package com.java8.examples;

public class OperationTest {

 public static void main(String[] args) {
   OperationTest test = new OperationTest();
   System.out.println("add result = " + test.add(2, 3));
   System.out.println("multiply result = " + test.multiply(2, 3));
 }

 public int add( int input1,  int input2) {
   Operation adder = (x, y) -> (x + y);
   return adder.operate(input1, input2);
 }  
 
 public int multiply( int input1,  int input2) {
   Operation multiplier = (x, y) -> (x * y);
   return multiplier.operate(input1, input2);
 }  
}

Output:

add result = 5
multiply result = 6

The above example will give the same output even without the @FunctionalInterface annotation. You could even have "abstract" in front of  int operate(int operand1, int operand2);

package com.java8.examples;

public interface Operation {
 abstract int operate(int operand1, int operand2);
}



Scenario 2: Have another Operation2 interface that takes 3 integer parameters.


package com.java8.examples;

public interface Operation2 {
 abstract int operate(int operand1, int operand2, int operand3); 
}


The OperationTest class that uses both interfaces. The Operation that take 2 integer parameters and Operation2 that takes 3 integer parameters.

package com.java8.examples;

public class OperationTest {

 public static void main(String[] args) {
   OperationTest test = new OperationTest();
   System.out.println("add result = " + test.add(2, 3));
   System.out.println("multiply result = " + test.multiply(2, 3));
   System.out.println("add 3 numbers result = " + test.add2(2, 3, 4));
 }

 public int add( int input1,  int input2) {
   Operation adder = (x, y)  -> (x + y);
   return adder.operate(input1, input2);
 }  
 
 
 public int multiply( int input1,  int input2) {
   Operation subtracter =  (x, y) -> (x * y);
   return subtracter.operate(input1, input2);
 } 
 
 public int add2( int input1,  int input2, int input3) {
   Operation2 adder = (x, y, z)  -> (x + y + z);
   return adder.operate(input1, input2, input3);
 }  
 
}


Output:

add result = 5
multiply result = 6
add 3 numbers result = 9



Scenario 3: Why do you have default methods in Java 8 interfaces?

This example demonstrates that default methods provide default behaviors, and closures are used to have  special behaviors like add, multiply, divide, subtract, print, etc.

Step 1: Here is the revised Operation interface with default methods.

package com.java8.examples;

import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.Objects;

@FunctionalInterface
public interface Operation<Intetger>  {
 
    //SAM -- Single Abstract Method.
    //identifier abstract is optional
    Integer operate(Integer operand);
 
    default Operation<Integer> add(Integer o){
       return (o1) -> operate(o1) +   o;
    }
 
    default Operation<Integer> multiply(Integer o){
      return (o1) -> operate(o1) * o;
    }
 
    //define other default methods for divide, subtract, etc
 
    default Integer getResult() {
    return operate(0);
    }
    
 default void print(){
  System.out.println("result is = " + getResult());
 }
   
}





Step 2: The revised OperationTest class.

package com.java8.examples;

import static java.lang.System.out;

public class OperationTest {
 
 public static void main(String[] args) {
 
  Operation<Integer> calc = (x) -> (2);
  
  Operation complexOp = calc.add(3)
         .multiply(4)
         .multiply(2)
         .multiply(2)
         .add(4);
  
  complexOp.print();
 
  int result = complexOp.getResult();
 } 
 
}




Output:

result is = 84


We know that Java does not support multiple implementation inheritance to solve the diamond problem (till Java 8). Java did only support multiple interface inheritance. That is, a class can implement multiple interfaces. By having default method implementations in interfaces, you can now have multiple behavioral inheritance in Java 8.  Partially solving the diamond problem.


Scenario 4: Why do you have static methods in Java 8 interfaces?

The static methods are helper methods. Prior to Java 8, the Java APIs used to have separate interfaces and utility methods. For example, Collection interface and Collections utility class, Path interface and Paths utility class, etc.

So, instead of doing Collections.sort(list, ordering), in Java 8 APIs you could do list.sort(ordering);

Secondly, static helper methods are more expressive with meaningful names like plus5, plus10, etc as shown below.

package com.java8.examples;

import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.Objects;

@FunctionalInterface
public interface Operation<Intetger>  {
 
 //SAM -- Single Abstract Method.
 //identifier abstract is optional
 Integer operate(Integer operand);
 
    default Operation<Integer> add(Integer o){
       return (o1) -> operate(o1) +   o;
    }
 
    default Operation<Integer> multiply(Integer o){
      return (o1) -> operate(o1) * o;
    }
 
    //define other default methods for divide, subtract, etc
 
    default Integer getResult() {
    return operate(0);
    }
    
 default void print(){
  System.out.println("result is = " + getResult());
 }
   
 
 //ads 5 to a given number
 static Integer plus5(Integer input) {
  return input + 5 ;
 }
}


Now, how to invoke the static method via Lambda expressions:

package com.java8.examples;

import static java.lang.System.out;

public class OperationTest {
 
 public static void main(String[] args) {
 
  //plus5 is an expressive static helper method that adds 5 to a given number
  Operation<Integer> calc = (x) -> Operation.plus5(2);
  
  Operation complexOp = calc.add(3)
         .multiply(4)
         .multiply(2)
         .multiply(2)
         .add(4);
  
  complexOp.print();
 
  int result = complexOp.getResult();
  
 } 
}


Output:

result is = 164


Learning to write functional programming with Java 8 with examples -- part 2

Labels: ,

May 22, 2014

Java 8 Optional class to alleviate some of the pains of unsightly null pointer checks and defensive coding

The most prevalent runtime exception (aka unchecked) exception in Java is the NullPointerException. You need to code defensively to avoid NullPointerException as shown below. Later, we will see how the class java.util.Optional that was introduced in Java 8 will alleviate this problem to some extent.

Pre Java 8 without the java.util.Optional class


public class Person {

 private String name;
 private int age;
 
 private HealthInsurance insurance; 
 
 //getters and setter
}


public class HealthInsurance {

 private String name;
 private Extra[] extras;

 //getters and setters
}


public class Extra {
      
 private String name;

 //getters and setters 
}


Now, here is the main class that invokes printExtras(Person person), where you need to check for null

public class PersonTest {

 public static void main(String[] args) {

  Person person1 = new Person();
  person1.setName("John");
  printExtras(person1);
  
  Person person2 = new Person();
  person2.setName("Peter");
  
  HealthInsurance healthIns = new HealthInsurance();
  Extra[] healthExtras = { new Extra("Physio"), new Extra("Optical"), new Extra("Chiro") };
  healthIns.setExtras(healthExtras);
  
  person2.setInsurance(healthIns);
  printExtras(person2);

 }

 private static void printExtras(Person person) {
  if (person != null && 
   person.getInsurance() != null 
   && person.getInsurance().getExtras() != null) {
   
   Extra[] extras = person.getInsurance().getExtras();
   for (Extra extra : extras) {
    System.out.println(extra.getName());
   }
  }

 }
}


In Java 8 with java.util.Optional class


Take note of the Optional class.
package com.java8.examples;

import java.util.Optional;

public class Person {
 
 private String name;
 private int age;
 private Optional<HealthInsurance> insurance = Optional.empty(); //default
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 
 public void setAge(int age) {
  this.age = age;
 }
 
 
 public Optional<HealthInsurance> getInsurance() {
  return insurance;
 }
 public void setInsurance(Optional<HealthInsurance> insurance) {
  this.insurance = insurance;
 }
}


package com.java8.examples;

import java.util.Optional;

public class  HealthInsurance{

 private String name;
 private Optional<Extra[]> extras = Optional.empty(); //default

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Optional<Extra[]> getExtras() {
  return extras;
 }

 public void setExtras(Optional<Extra[]> extras) {
  this.extras = extras;
 }
}


package com.java8.examples;

public class Extra {

 private String name;

 public Extra(String name) {
  super();
  this.name = name;
 }

 public String getName() {
  return name;
 }
}


Finally, the main class that make use of the Optional.of methods, and the printExtras(Optional person) is much simpler with functional programming and lambda expressions.


package com.java8.examples;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

public class PersonTest {

 public static void main(String[] args) {

  Person person1 = new Person();
  person1.setName("John");

  Optional<Person> p1 = Optional.of(person1);
  printExtras(p1);

  Person person2 = new Person();
  person2.setName("Peter");

  // health ins and extras are supplied
  HealthInsurance healthIns = new HealthInsurance();
  Extra[] healthExtras = { new Extra("Physio"), new Extra("Optical"), new Extra("Chiro") };

  healthIns.setExtras(Optional.of(healthExtras));
  person2.setInsurance(Optional.of(healthIns));

  Optional<Person> p2 = Optional.of(person2);
  printExtras(p2);

 }

 private static void printExtras(Optional<Person> person) {
  person
      .flatMap(Person::getInsurance)
      .flatMap(HealthInsurance::getExtras)
      .ifPresent((p) -> {for(int i = 0; i < p.length; i++) {
                        System.out.println(p[i].getName());
                }
                        });
         
     }
}


Both approaches outputs

Physio
Optical
Chiro


Here are the convenient methods that the Optional class support

  • ifPresent( ):  returns true if a value is present in the optional.
  • get( ):  returns a reference to the item contained in the optional object, if present, otherwise throws a NoSuchElementException.
  • ifPresent(Consumer<T>consumer):  passes the optional value, if present, to the provided Consumer (lambda expression or method reference).
  • orElse(T other): returns the value, if present, otherwise returns the value in other.
  • orElseGet(Supplier<T> other):  returns the value if present, otherwise returns the value provided by the Supplier (lambda expression or method reference).
  • orElseThrow(Supplier<T> exceptionSupplier): returns the value if present, otherwise throws the exception provided by the Supplier (lambda expression or method reference)

Note:  In Java you cannot simply get rid of the null references that have historically existed, but before Java 8, you need to rely on your code and proper documentation to understand if a reference is optional. java.util.Optional<T> class has been added to deal with optional object references. The intention with the Optional class is not to replace every null-able reference, but to help in the creation of more robust APIs you could tell if  you can expect an optional reference by reading the signature of a method.

Labels: , ,

May 21, 2014

7 useful miscellaneous additions you must know in Java 8

The much awaited addition in Java 8 are Lambda expressions to be used in functional programming and default and static methods in interfaces to support multiple behavior inheritance and helper methods. Here are a few other additional handy additions in Java 8.

Addition #1: String.join( ) method, which is an opposite of String.split(...) was there from pre Java 8.

Example 1:

String[] javaTechnologies = {"Java", "JEE", "JDBC", "Spring"};
String joined = String.join(",", javaTechnologies); //Java,JEE,JDBC,Spring

Example 2:

 String joined = String.join("/", "var", "opt", "oracle"); // var/opt/oracle

Addition #2: The Comparator interfaces have a number of useful methods to sort objects with options to nest multiple fields with thenComparing(...), and other handy methods like nullsFirst( ), nullsLast( ), naturalOrder( ), reverseOrder( ), etc. This was made possible as Java 8 interfaces can have default methods (which gives you multiple behavior inheritance) and static methods (a replacement for helper classes).

Example 1:

Arrays.sort(people, Comparator.comparing(Person::getName)  
                               .thenComparing(Person::getAge) ;
  
Example 2:

Comparator<Person> multiFieldComparator = 
    Comparator.comparing(Person::getGender, Comparator.nullsFirst(Comparator.naturalOrder()))
              .thenComparing(Person::getName, Comparator.nullsLast(Comparator.naturalOrder()))
              .thenComparing(Person::getAge,  Comparator.nullsLast(Comparator.reverseOrder())) ;
     
//parallel() processing using Fork/Join 
List<Object> sortedPeople = people.stream().parallel().sorted(multiFieldComparator).collect(Collectors.toList());   


Addition #3: In Java you cannot simply get rid of the null references that have historically existed, but before Java 8, you need to rely on your code and proper documentation to understand if a reference is optional (i.e can be null) as shown below,

import java.util.ArrayList;
import java.util.List;

public class PersonTest {

 public static void main(String[] args) {

  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));
  
  Person foundPerson = find("Sam", people); 
  System.out.println(foundPerson.getName()); //NullPointerException
  
 }

 public static Person find(String name, List<Person> Persons) {
  for (Person person : Persons) {
   if (person.getName().equalsIgnoreCase(name)) {
    return person;
   }
  }
  return null;
 }
}




In Java 8, java.util.Optional<T> class has been added to deal with optional object references. The intention with the Optional class is not to replace every null-able reference, but to help in the creation of more robust APIs you could tell if  you can expect an optional reference by reading the signature of a method.

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class PersonTest {

 public static void main(String[] args) {

  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));

  Optional<Person> foundPerson = find("Sam", people);
  System.out.println(foundPerson.orElse(new Person("Sam", 35, Person.Gender.MALE))); 
  
 }

 public static Optional<Person> find(String name, List<Person> Persons) {
  for (Person Person : Persons) {
   if (Person.getName().equals(name)) {
    return Optional.of(Person);
   }
  }
  return Optional.empty();
 }
}


The find method signature tells you that it returns a person optionally.

Addition #4: In cases where you want to detect result overflow errors in int and long, the methods addExact, subtractExact, multiplyExact, and toIntExact in Java 8, the java.lang.Math class throws an ArithmeticException when the results overflow. Generally, it is recommended to use BigInteger if you expect large values.

public class DataOverflowTest {
 
 public static void main(String[] args) {
  
  //for int -2^31 and a maximum value of 2^31-1, which is -2147483648 to 2147483647
  
  int i = 2147483647 + 1;
  System.out.println(i); //wrong -- prints -2147483648 due to data overflow 
  
  //Java 8
  Math.addExact(2147483647, 1);  //java.lang.ArithmeticException: integer overflow
 }
}


Addition #5: The ability to lazily read lines from a file with Files.lines(...). For example, let's read technologies.txt that has

Java
JEE
JDBC
Hibernate
Spring

Now the code that covers previous additions as well.

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.stream.CloseableStream;

public class FileReadTest {
 
 public static void main(String[] args) {
  Path path = Paths.get("c:\\temp\\technologies.txt");
  try(CloseableStream<String> lines = Files.lines(path, Charset.forName("UTF-8"))){
   Optional<String> found = lines.filter(p -> p.contains("Spring")).findFirst();
   System.out.println(found.orElse("NOT FOUND!!"));
  } catch (IOException e) {
   e.printStackTrace();
  }//CloseableStream is AutoCloseable 
 }
}


Addition #6: The @Repeatable annotation.

Pre Java 8:

public @interface Habit {
 String value();
}

public @interface Habits {
     Habit[] value();
}

@Habits({@Habit("habit1"), @Habit("habit2")})
public class Person  {
   //......
}


Post Java 8:

import java.lang.annotation.Repeatable;

@Repeatable(Habits.class)
public @interface Habit {
 String value();
}


@Habit("habit1")
@Habit("habit2")
public class Person  {
   //...
}

In Pre Java 8, if you repeat the same annotation, you will get a compile-time error "Duplicate annotation". In Java 8, you can repeat the same annotation with the @Repeatable annotation.


Addition #7: Java 8 introduces the "Type Annotations", which are annotations that can be placed anywhere you use a type.


  • new operator, 
  • type casts, 
  • implements clauses and 
  • throws clauses. 

Handy for stronger type checking, but can clutter your code. Use them judiciously. For example,

@NotNull String str1 = ...
@Email String str2 = ...
Map.@NonNull Entry = ...
new @NonEmpty List<String>(notEmptySet)
List<@ReadOnly @Localized Message> messages = ...

Labels: ,

May 19, 2014

Different ways to sort a collection of objects in pre and post Java 8

The object we are going to sort is a Person.

public class Person  {
 
 public enum Gender {FEMALE, MALE};

 private String name;
 private Integer age;
 private Gender gender;

 public Person(String name, Integer age, Gender gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
 }

 //getter, setter, equals(...), and hashCode() methods skipped

 @Override
 public String toString() {
  return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
 }
}


Option 1: Writing your own Comparator implementation. This can be done as an anonymous inner class instead of a separate class.


import java.util.Comparator;

public class PersonComparator implements Comparator<Person> {

 @Override
 public int compare(Person o1, Person o2) {
  
  //by gender first
  int i1 = o1.getGender().compareTo(o2.getGender());
  if (i1 != 0) return i1;
  
  //by name next
  int i2 =  o1.getName().compareTo(o2.getName());
  if (i2 != 0) return i2;
  
  //by age
  return o1.getAge().compareTo(o2.getAge());
 }
}


The test class

import java.util.ArrayList;
import java.util.List;

public class PersonTest {
 
 public static void main(String[] args) {
  
  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("John", 32, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));
  
  System.out.println("before sorting = "  + people);
  people.sort(new PersonComparator());
  System.out.println("after sorting = "  + people);
 
 }
}


Option 2: The Option 1 is not bad, but the the moment you need to handle null element values, the PersonComparator will have more code. One of the best practices in Java is "Don't reinvent the wheel". So, let's use the BeanComparator,NullComparator, and ComparatorChain from the Apache commons library commons-beanutils -> commons-beanutils-bean-collections that uses reflection. The example below also handles null values.

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.comparators.ComparatorChain;
import org.apache.commons.collections.comparators.NullComparator;

public class PersonTest {
 
 public static void main(String[] args) {
  
  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("John", 32, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));
  people.add(new Person("Shawn", 30, null));
  
  System.out.println("before sorting = "  + people);
  
  //Apache commons-beanutils.commons-beanutils-bean-collections
  ComparatorChain comparatorChain = new ComparatorChain();
  //null is compared s lower
  comparatorChain.addComparator(new BeanComparator("gender", new NullComparator(false)));
  //null is compared as higher
  comparatorChain.addComparator(new BeanComparator("name", new NullComparator(true)));
  comparatorChain.addComparator(new BeanComparator("age", new NullComparator(true)));
  people.sort(comparatorChain);
  
  System.out.println("after sorting = "  + people);
 
 }
}





Option 3: Using the Google Gauva library to sort the collection in functional programming style.

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Ordering;

public class PersonTest {
 
 public static void main(String[] args) {
  
  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("John", 32, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));
  people.add(new Person("Shawn", 30, null));
  
  System.out.println("before sorting = "  + people);
  
  //anonymous inner class using the Google Gauva library
  people.sort(new Comparator<Person>() {

   @Override
   public int compare(Person o1, Person o2) {
    return ComparisonChain.start()
          .compare(o1.getGender(), o2.getGender(),  Ordering.natural().nullsFirst())
          .compare(o1.getName(), o2.getName(), Ordering.natural().nullsLast())
          .compare(o1.getAge(), o2.getAge(), Ordering.natural().nullsLast())
          .result();
   }

  
  });
  
  System.out.println("after sorting = "  + people);
 
 }
}


Option 4: If you are using Java 8, using the functional programming approach.

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class PersonTest {
 
 public static void main(String[] args) {
  
  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("John", 32, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));
  people.add(new Person("Shawn", 30, null));
  
  System.out.println("before sorting = "  + people);
  
  //java 8 approach fro multi-fields
  Comparator<Person> multiFieldComparator = 
            Comparator.comparing(Person::getGender, Comparator.nullsFirst(Comparator.naturalOrder()))
                      .thenComparing(Person::getName, Comparator.nullsLast(Comparator.naturalOrder()))
                      .thenComparing(Person::getAge,  Comparator.nullsLast(Comparator.naturalOrder())) ;
  
  people.sort(multiFieldComparator);
  System.out.println("after sorting = "  + people);
 
 }
}


Option 5: If you are using Java 8, using parallel processing. Very similar to option 4, but processed in parallel with minor changes.

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class PersonTest {
 
 public static void main(String[] args) {
  
  List<Person> people = new ArrayList<>();
  people.add(new Person("John", 35, Person.Gender.MALE));
  people.add(new Person("John", 32, Person.Gender.MALE));
  people.add(new Person("Simone", 30, Person.Gender.FEMALE));
  people.add(new Person("Shawn", 30, Person.Gender.MALE));
  people.add(new Person("Shawn", 30, null));
  
  System.out.println("before sorting = "  + people);
  
  Comparator<Person> multiFieldComparator = 
          Comparator.comparing(Person::getGender, Comparator.nullsFirst(Comparator.naturalOrder()))
                    .thenComparing(Person::getName, Comparator.nullsLast(Comparator.naturalOrder()))
                    .thenComparing(Person::getAge,  Comparator.nullsLast(Comparator.naturalOrder())) ;
  
     //parallel() processing using Fork/Join 
  List<Object> sortedPeople = people.stream()
                                          .parallel()
                                          .sorted(multiFieldComparator)
                                          .collect(Collectors.toList());
            
  System.out.println("after sorting = "  + sortedPeople);
 
 }
}


Output:

before sorting = [Person [name=John, age=35, gender=MALE], Person [name=John, age=32, gender=MALE], Person [name=Simone, age=30, gender=FEMALE], Person [name=Shawn, age=30, gender=MALE], Person [name=Shawn, age=30, gender=null]]

after sorting = [Person [name=Shawn, age=30, gender=null], Person [name=Simone, age=30, gender=FEMALE], Person [name=John, age=32, gender=MALE], Person [name=John, age=35, gender=MALE], Person [name=Shawn, age=30, gender=MALE]]

Labels: ,

May 5, 2014

Transforming your thinking from OOP to FOP with Java 8 examples

One needs to get used to the transformation from imperative programming to functional  programming. You like it or not, you will be using functional programming in Java, and interviewers are going to quiz you on functional programming. Fortunately, Java is not a fully functional programming language, and hence one does not require the full leap to functional programming. Java 8 supports both imperative and functional programming approaches.

Q. What are the differences between OOP and FOP?
A.



In OOP, x = x+ 5 makes sense, but in mathematics or functional programming, you can't say  x = x + 5 because if x were to be 2, you can't say that 2 = 2 + 5. In functional programming you need to say f(x) -> x + 5.

Q. What are the characteristics of functional programming you need to be familiar with?
A.
  1. A focus on what is to be computed rather then how to compute it. 
  2. Function Closure Support
  3. Higher-order functions
  4. Use of recursion as a mechanism for flow control
  5. Referential transparency
  6. No side-effects
Let's look at these one by one:

1. A focus on what is to be computed rather then how to compute it

This was discussed with the following example in the post entitled -- When to use Java 8 functional programming, and where does it shine?


Integer[] numbers = {1,2,3,4,5,6};

//focusses on what to do as opposed to how to do it
//no fluff like for loops, mutations, etc
Arrays.asList(numbers)
       .stream()
       .filter((e) -> (e % 2 != 0))
       .map((e) -> (e * 2))
       .forEach(System.out::println);
    


2. Function closure support

In order to create closures, you need a language where the function type is a 1st class citizen, where a function can be assigned to a variable, and then passed around like any other variables like a string, int or boolean. closure is basically a snapshot of the stack at the point that the lambda function is created. Then when the function is re-executed or  called back the stack is restored to that state before executing the function.

The java.util.function package provides a number of functional interfaces like Consumer<T>, Function&ltT, U>, etc to define closures or you can define your own functional interfaces.

package com.java8.examples;

import java.util.function.Function;

public class ClosureTest {

 public static void main(String[] args) {
  
  //closure 1 that adds 5 to a given number
  Function<Integer, Integer> plus5 = (i) -> (i+5); 
  //closure 2 that times by 2 a given number
  Function<Integer, Integer> times2 = (i) -> (i*2);
  //closure 3 that adds 5 and then multiply the result by 2
  Function<Integer, Integer> plus5AndThenTimes2 = plus5.andThen(times2);  
  //closure 4 that times by 2 and then adds 5
  Function<Integer, Integer> times2AndThenplus5 = times2.andThen(plus5);
    
        //callback or execute closure
  //functions plus5, times2, etc can be passed as arguments
  System.out.println("9+5=" + execute(plus5, 9));
  System.out.println("9*2=" + execute(times2, 9));
  System.out.println("(9+5)*2=" + execute(plus5AndThenTimes2, 9));
  System.out.println("9*2+5=" + execute(times2AndThenplus5, 9));

 }


 //functions can be used as method parameters
 private static Integer execute(Function<Integer, Integer> function, Integer number){
  return function.apply(number); //execute the function
 }
}

Output:

9+5=14
9*2=18
(9+5)*2=28
9*2+5=23

In pre Java 8, you can use anonymous inner classes to define closures. In Java 8, lambda operators like (i) -> (i+5) are used to denote anonymous functions.




Is currying possible in Java 8?

Currying (named after Haskell Curry) is the fact of evaluating function arguments one by one, producing a new function with one argument less on each step.

Java 8 still does not have first class functions, but currying is “practically” possible with verbose type signatures, which is less than ideal. Here is a very simple example:

package com.java8.examples;

import java.util.function.Function;

public class CurryTest {
 
 public static void main(String[] args) {
  Function<Integer,Function<Integer,Integer>> add = (a) -> (b) -> a + b;
  
  Function<Integer,Integer> addOne = add.apply(1);
  Function<Integer,Integer> addFive = add.apply(5);
  Function<Integer,Integer> addTen = add.apply(10);
  
  Integer result1 = addOne.apply(2); // returns 3
  Integer result2 = addFive.apply(2); // returns 7
  Integer result3 = addTen.apply(2); // returns 12
  
  System.out.println("result1 = "  + result1);
  System.out.println("result2 = "  + result2);
  System.out.println("result3 = "  + result3);
 
 }
}

The output is

result1 = 3
result2 = 7
result3 = 12


3. Higher order functions

In mathematics and computer science, a higher-order function (aka functional form) is a function that does at least one of the following:


  1. takes one or more functions as an input -- for example g(f(x)), where f and g are functions, and function g composes the function f. 
  2. outputs a function -- for example, in the code above plus5 and plus2 outputs a function


        Function<Integer, Integer> plus5 = (i) -> (i+5); 
 //closure 2 that times by 2 a given number
 Function<Integer, Integer> times2 = (i) -> (i*2);


also

        Function<integer integer> plus5AndThenTimes2 = plus5.andThen(times2);  


outputs another function, where the plus5 function takes plus2 function as an input.


4. Use of recursion as a mechanism for flow control

Java is a stack based language that supports reentrant (a method can call itself) methods. This means recursion is possible in Java. Using recursion you don't need a mutable state, hence the problems can be solved in a much simpler fashion compared to using an iterative approach with a loop.

package com.java8.examples;

import java.util.function.Function;

public class RecursionTest {
 
   static Function<Integer, Integer> factorial = 
       x -> { 
           return  ( x == 0) ? 1 : x  * factorial.apply(x-1);
                  };
 
  public static void main(String[] args) {
       
       int result = factorial.apply(3);
       System.out.println("factorial of 3 = " + result);
  }
}


Recursion is used in the Lambda expression to calculate the factorial.


5. Referential Transparency

Referential transparency is a term commonly used in functional programming, which means that given a function and an input value, you will always receive the same output. There is no external state used in the function. In other words, a referentially transparent function is one which only depends on its input. The plus5 and times2 functions shown above are referentially transparent.

A function that reads from a text file and prints the output is not referentially transparent. The external text file could change at any time so the function would be referentially opaque


6. No side-effects




One way to do programming without side effects is to use only immutable classes. In real world, you try to minimize the mutations, but can't eliminate them. Lambdas can refer to local variables that are not declared final but are never modified. This is known as "effectively final". 

When you are using methods like reduce on a stream, you need to be aware of the side effects due to parallelism. For example, the following code will have no side effects when run in serial mode.


public static void main(String[] args) {  
 Integer[] numbers = {10, 6};
 Integer result = Arrays.asList(numbers).stream()
                      .reduce(20, (a,b) -> (a - b));
          
 System.out.println(result);
}


Outputs:

4

It starts with 20, and then subtracts 10 and 6. 20 - 10 - 6 = 4; But if you run it again in parallel mode as shown below

public static void main(String[] args) {  
 Integer[] numbers = {10, 6};
 Integer result = Arrays.asList(numbers).parallelStream()
                         .reduce(20, (a,b) -> (a - b));
          
 System.out.println(result);
} 


The output will be:

-4

What happened here? 10 - (20 - 6) =  -4;

This means the reduce method on a stream produce side effects when run in parallel for non-associative operations.

Q. What is an associative property?
A. Associative operations are operations where the order in which the operations were performed does not matter. For example.

Associative:

3 + (2 + 1) = (3+ 2) + 1
3 * (2 * 1) = (3 * 2) * 1

Non-associative:

3 - (2 - 1) != (3 - 2) - 1
(4/2)/2 != 4/(2/2)


Pure functions are functions with no side effects. In computers, idempotence means that applying an operation once or applying it multiple times has the same effect. For example

Idempotent operations

  • Multiplying a number by zero. No matter how many times you do it, the result is still zero.
  • Setting a boolean flag. No matter how many times you do it, the flag stays set.
  • Deleting a row from a database with a given ID. If you try it again, the row is still gone.
  • Removing an element from a collection.
In real life where you have concurrent operations going on, you may find that operations you thought were idempotent cease to be so. For example, another thread could unset the value of the boolean flag.

Labels: ,

Apr 29, 2014

When to use Java 8 functional programming, and where does it shine?

Q. What is the difference between imperative and declarative programming paradigms?
A. Imperative (or procedural) programming: is about defining the computation how to do something in terms of statements and state changes, and as a result what you want to happen will happen.

Declarative programming: is about declaratively telling what you would like to happen, and let the library or functions figure out how to do it. SQL, XSLT and regular expressions are declarative languages.

Q. Does functional programming use imperative or declarative approach?
A. Functional programming is a form of declarative programming, where functions are composed of other functions -- g(f(x)) where g and f are functions. An output of one function becomes the input for the composing function. A typical example of functional programming, which you may have used  is transforming an XML document using XSLT to other forms. The composable and isolated  XSL style sheets are used for transformation.


In imperative programming it makes sense to say x = x + 1, but in maths or functional programming it is not right to say x = x + 1, if x is 2 is it right to say 2 = 2 + 1 or 2 = 3 ?In functional programming f(x) -> x + 1, where  f is a function that takes an argument of x.

Q. What does functional programming shine in Java 8?
A.

Scenario 1: Here is an imperative program to extract odd numbers from a given list of numbers and then double each odd number and print each of them.



Imperative program with looping, statements, etc.


package com.java8.examples;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class NumberTest {

 public static void main(String[] args) {
  Integer[] numbers = {1,2,3,4,5,6};
 
   long start = System.nanoTime();
 
   //odd numbers
   List<Integer> oddNumbers = new ArrayList<>();
   for (Integer e : numbers) {
   if(e %2 != 0) {
    oddNumbers.add(e);
   }
   }
   
   //doubled odd numbers
   List<Integer> doubledOddNumbers = new ArrayList<>();
   for (Integer e : oddNumbers) {
         doubledOddNumbers.add(e * 2); 
   }
   
   
   //print each
   for (Integer e : doubledOddNumbers) {
     System.out.println(e);
   }
   
     
   System.out.println("Completed in " + (System.nanoTime() - start) + " nano second");
   
 }
}


Output:

2
6
10
Completed in 371880 nano second

Functional programming using the Java 8 lambda expressions.

Functional programming with good set of libraries can cut down lot of fluff and focus on just transformations. In other words, just tell what you would like to do.

package com.java8.examples;

import java.util.Arrays;

public class NumberTest {

 public static void main(String[] args) {
  Integer[] numbers = {1,2,3,4,5,6};
 
   long start = System.currentTimeMillis();
 
   //static methods are used for clarity
   Arrays.asList(numbers)
       .stream()
       .filter((e) -> (e % 2 != 0))
       .map((e) -> (e * 2))
       .forEach(System.out::println);
   
   
   System.out.println("Completed in " + (System.currentTimeMillis() - start) + " ms");
   
 }
  
}


Output:

2
6
10
Completed in 46 ms

Shining moment 1: The above code has increased readability and maintainability because each function is designed to accomplish a specific task for given arguments. Lesser moving parts than the imperative code. The above code can be further improved by extracting the cryptic lambda expressions like  (e) -> (e * 2) to static methods with meaningful names for re-usability and readability as shown below.

package com.java8.examples;

import java.util.concurrent.TimeUnit;
import java.util.Arrays;

class NumberTest {

 public static void main(String[] args) {
   Integer[] numbers = {1,2,3,4,5,6};
 
   long start = System.currentTimeMillis();
 
   //static methods are used for clarity
   Arrays.asList(numbers)
       .stream()
       .filter(NumberTest::isOddNumber)
       .map(NumberTest::doubleIt)
       .forEach(System.out::println);
   
   System.out.println("Completed in " + (System.currentTimeMillis() - start) + " ms");
   
 }

 private static boolean isOddNumber(int number){
  //simulate time to perform an operation
  delay();
  System.out.println("isOdd " + number);
  return number % 2 != 0;
 }
 
 private static int doubleIt(int number){
  //simulate time to perform an operation
  delay();
  System.out.println("doubleIt: " + number);
     return number * 2;
 }
 
 private static void delay() {
  //simulate time to perform an operation
  try {
   TimeUnit.SECONDS.sleep(1);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

Output:

isOdd 1
doubleIt: 1
2
isOdd 2
isOdd 3
doubleIt: 3
6
isOdd 4
isOdd 5
isOdd : 5
10
isOdd 6
Completed in 9454 ms

Shining moment 2: A time delay was added on purpose to demonstrate that a functional program can be easily made to run in parallel using the "fork and join" feature added in Java 7. To improve performance of the above code that took 9.5 seconds to run, all you have to do is use .parallelStream( )   instead of .stream( ).

   Arrays.asList(numbers)
       .parallelStream()      //use fork and join 
       .filter(NumberTest::isOddNumber)
       .map(NumberTest::doubleIt)
       .forEach(System.out::println);



The new output due to parallel processing will be:

isOdd 2
isOdd 4
isOdd 1
isOdd 6
isOdd 3
doubleIt: 1
isOdd 5
2
doubleIt: 3
6
doubleIt: 5
10
Completed in 3151 ms

Finished running in 3 seconds  with the performance gain. When parallelising tasks, you need to be

  • Ensuring that the computation is correct
  • Ensuring that parallelism actually brings performance gains
  • Using algorithms that are parallelisable


Shining moment 3: code is easier to refactor as shown below. If you want to switch the logic to double it first and then extract the odd numbers, all you have to do is swap the .filter call with .map call.

 Arrays.asList(numbers)
       .parallelStream()
       .map(NumberTest::doubleIt)
       .filter(NumberTest::isOddNumber)
       .forEach(System.out::println);

The output will have no odd numbers at all.

doubleIt: 4
doubleIt: 2
doubleIt: 1
doubleIt: 6
isOdd 4
isOdd 12
isOdd 2
isOdd 8
doubleIt: 5
doubleIt: 3
isOdd 10
isOdd 6
Completed in 4145 ms


Shining moment 4: Easier testing and debugging. Because pure functions can more easily be tested in isolation, you can write test code that calls the pure function with typical values, valid edge cases, and invalid edge cases. In the above example, I was using the Java 8 library that was well tested with confidence. I will only have to provide unit tests for the static functions boolean isOddNumber(int number)  and  int doubleIt(int number) that provide the logic.


Having said this, OO programming and functional programming can co-exist. In the next post I will discuss how to get accustomed to Function Oriented Programming (FOP) from Object Oriented Programming (OOP).

Labels: ,

Apr 9, 2014

Understanding Java 8 Streams and working with collections using Lambda expressions

Assumes that you have read and understand Java 8 Lambda Expressions and functional interface tutorials

A stream is an infinite sequence of consumable elements (i.e a data structure) for the consumption of an operation or iteration. Any Collection can be exposed as a stream. The operations you perform on a stream can either be
  • intermediate (map, filter, sorted, limit, skip,concat, substream, distinct, etc) producing another stream or 
  • terminal (forEach, reduce, collect, sum, max, count, matchAny, findFirst, findAny, etc) producing an object that is not a stream.
Basically, you are building a pipeline as in Unix

ls -l | grep "Dec" | Sort +4n | more


stream( ) is a default method added to the Collection interface in Java 8. The stream( ) returns a java.util.Stream interface with multiple abstract methods like filter, map, sorted, collect, etc.  DelegatingStream is implements these abstract methods.

Java 8 Example 1:


package com.java8.examples;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


public class EmployeeTest {
 
 private static List<Employee> employees = Arrays.asList(
  new Employee("Steve", BigDecimal.valueOf(35000), Employee.WorkType.PARTTIME), 
  new Employee("Peter", BigDecimal.valueOf(65000), Employee.WorkType.FULLTIME),
  new Employee("Sam", BigDecimal.valueOf(75000), Employee.WorkType.FULLTIME),
  new Employee("John", BigDecimal.valueOf(25000), Employee.WorkType.CASUAL));
        
 
  public static void main(String[] args) {
   
   //e is the parameter for Employee
   List<Employee> fullTimeEmployees = employees.stream()  //returns a stream (intermediate)
      .filter(e -> e.getWorkType() == Employee.WorkType.FULLTIME)//returns a stream (intermediate)
      .collect(Collectors.toList()); // returns a list (terminal)
   fullTimeEmployees.forEach(e -> System.out.println(e)); //Peter & Sam  
 }

}


The output is:

Employee [name=Peter, salary=65000, workType=FULLTIME]
Employee [name=Sam, salary=75000, workType=FULLTIME]


The above example creates a new list of full time employees. The operations .stream( ),  .filter( ) create the intermediate streams, hence they are chained, and the .collect is the terminal operation that returns the final List of full-time employees.

This is enabled in the Iterable interface, which is a functional interface with the forEach default method. A List and other collections implements the Iterable functional interface to allow lambda expressions.

The Employee class will look like

package com.java8.examples;
import java.math.BigDecimal;

public class Employee {
 
 public enum WorkType {FULLTIME, PARTTIME, CASUAL}
 
 private String name;
 private BigDecimal salary;
 private WorkType workType;
 
 public Employee(String name, BigDecimal salary, WorkType workType) {
  super();
  this.name = name;
  this.salary = salary;
  this.workType = workType;
 }
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public BigDecimal getSalary() {
  return salary;
 }
 public void setSalary(BigDecimal salary) {
  this.salary = salary;
 }
 public WorkType getWorkType() {
  return workType;
 }
 public void setWorkType(WorkType workType) {
  this.workType = workType;
 }

 @Override
 public String toString() {
  return "Employee [name=" + name + ", salary=" + salary + ", workType=" + workType + "]";
 }
}


Java 8 Example 2:

Now, in the same example, if you want to print all the employees who earn more than 25,000, sorted by WorkType,  in the format "<name> earns <salary>  on a <work type> basis.

//e is the parameter for Employee
employees.stream()  //returns a stream (intermediate)
 .filter(e -> e.getSalary().doubleValue() > 25000) // returns a stream (intermediate)
 .sorted((e1,e2) -> e1.getWorkType().compareTo(e2.getWorkType()))
 .map(e -> e.getName() + " earns " + e.getSalary() + " on a " + e.getWorkType() + " basis")
 .forEach(System.out::println); //terminal 
 

Isn't this cool? This is like writing the SQL where clause.

Output:

Peter earns 65000 on a FULLTIME basis
Sam earns 75000 on a FULLTIME basis
Steve earns 35000 on a PARTTIME basis


Java 8 Example 3:

Get a  comma separated  string of all employees earning more than 25,000.00 as salary.

//e is the parameter for Employee
String str = employees.stream()  //returns a stream (intermediate)
 .filter(e -> e.getSalary().doubleValue() > 25000) // returns a stream (intermediate)
 .map(e -> e.getName())// returns a stream (intermediate)
 .distinct()  //returns a stream (intermediate)
  //terminal returning a string 
 .reduce("Distinct first names earning > 25000:", (name1, name2) -> name1+ "," + name2 );
   
System.out.println("CSV: " + str);


Output:

CSV: Distinct first names earning > 25000:,Steve,Peter,Sam



Java 8 Example 4:

Aggregate the salary by WorkType.

//e is the parameter for Employee
employees.stream()  //returns a stream (intermediate)
 .collect(Collectors.groupingBy(Employee::getWorkType))
 .forEach((gr,le) -> {System.out.println(" Aggregated Salary for "  + gr + " is " +  
   + le.stream().mapToDouble(e -> e.getSalary().doubleValue()).sum());
 });


Output:

 Aggregated Salary for CASUAL is 25000.0
 Aggregated Salary for FULLTIME is 140000.0
 Aggregated Salary for PARTTIME is 35000.0


Java 8 Example 5:

Get the employee who earns the highest salary.

//e is the parameter for Employee
Employee maxSalaryEmployee = employees.stream()  //returns a stream (intermediate)
 .max((e1, e2) -> (e1.getSalary().compareTo(e2.getSalary())))
 .get();  
    
System.out.println(maxSalaryEmployee);


Output:

Employee [name=Sam, salary=75000, workType=FULLTIME]

Labels:

Apr 8, 2014

Understanding Java 8 Lambda expressions with working examples -- part 3



Example 4:  Runnable interface and Thread class to create new threads via Lambda expressions

The Java API Runnable interface in Java 8 has been annotated with @FunctionalInterface, which means you can only have 1 abstract method.


@FunctionalInterface
public interface Runnable {
    public abstract void run();
}


public class Thread implements Runnable {
   //..........skipped
}


Step 1: Here is Lambda expression in action to create new threads.

package com.java8.examples;

import java.util.concurrent.atomic.LongAdder;

public class ThreadTest {
 private static LongAdder counter = new LongAdder();

 public static void main(String[] args) {
  
  new Thread(() -> { counter.increment();
                     System.out.println(Thread.currentThread().getName() + " count -- " + counter.longValue());
                   }).start();
  
  Thread t2 = new Thread(() -> { counter.increment();
                     System.out.println(Thread.currentThread().getName() + " count -- " + counter.longValue());
                   });
  t2.start();
  
  
 }
}


The output:
 

Thread-0 count -- 1
Thread-1 count -- 2


Example 5: The free variables in lambda expressions are not thread-safe.

A lambda expression has 3 aspects:

  1. Parameters
  2. A block of code or body
  3. Values for the free variables. These are the variables that are not parameters, and not defined inside the closure.
The anonymous inner classes can only access variables defined outside if they are marked final. Otherwise you will get a compile error. The lambda expression has relaxed the requirement of variables being final, but the "free variables" that you use need to be either final or effectively final.  


package com.java8.examples;

import java.util.concurrent.atomic.LongAdder;

public class ThreadTest {
  private static LongAdder counter = new LongAdder();

  public static void main(String[] args) {
   
   int counterLocal = 0;  //local free variable
     
   
   new Thread(() -> { 
      counter.increment();
               
      //local variables referenced from a lambda expression must be final or effectively final
      counterLocal++; //Line A: illegal. compile-error
                
      System.out.println(counterLocal); // Line B: Ok, as counterLocal is not mutated
      int a = counterLocal; //Line C: Ok, as counterLocal is not mutated
                  
         System.out.println(Thread.currentThread().getName() + " count -- " + counter.longValue());
   }).start();
   
   
   }
}


The above code gives compile error due to Line A. If you comment out Line A, the above code will compile, and Line B and Line C are ok as  they use the variable counterLocal as read only and it is effectively final.

So, mutating free variables in a lambda expression is not thread-safe. The prohibition against mutation only holds true for local variables as explained above. You can still use an instance or static variable, but the compiler won't warn you, but you can have thread-safety issues.


Example 6: Understanding scope of "this" keyword

Will the toString( ) method invocation shown below invokes ThreadTest's toString( ) method or Thread class's toString( ) method?

package com.java8.examples;

import java.util.concurrent.atomic.LongAdder;

public class ThreadTest {

 public static void main(String[] args) {
       new  ThreadTest().execute();
 }
  
 public void execute() {
  new Thread(() -> {
         System.out.println(this.toString());
   }).start();
 }
 
 
 @Override
 public String toString() {
  return "ThreadTest class toString()";
 }
}


Output is:
ThreadTest class toString()

So, there is nothing special about using the "This" keyword in lambda expressions. The scope of lambda expression is nested inside the execute( ) method, and this has the same meaning anywhere inside the execute method.



More on Java 8 functional interfaces and Lambda expressions

Labels: ,

Apr 4, 2014

Understanding Java 8 Lambda expressions with working examples -- part 2

Extends Understanding Java 8 Lambda expressions with working examples -- part 1

Example 3: It is very common to loop through a collection of objects and perform certain tasks like setting a variable, etc. The  Iterable from which the other interfaces like Collection, List, etc has been annotated with @FunctionalInterface.


As shown in the diagram, the  Iterable also has a default  method  forEach(Consumer action)  implemented to loop through the collection.

Step 1: Create a Person POJO object with fields, getters, and setters.

package com.java8.examples;

public class Person {
 
 private String firstName;
 private String surname;
 
 public Person(String firstName) {
  this.firstName = firstName;
 }
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getSurname() {
  return surname;
 }
 public void setSurname(String surname) {
  this.surname = surname;
 }
 
 @Override
 public String toString() {
  return "Person [firstName=" + firstName + ", surname=" + surname + "]";
 }
}



Step 2: Create a collection of  Person objects, and forEach person, set the surname using the Lambda expression and anonymous method call. This is functional programming.

package com.java8.examples;

import java.util.ArrayList;
import java.util.List;

public class PersonCollectionTest {

 public static void main(String[] args) {
  List<Person> persons = new ArrayList<Person>();
  persons.add(new Person("John"));
  persons.add(new Person("Peter"));
  
  // Java 8: Lambda expression that sets surname for each person as "Smith"
  persons.forEach((p) -> {p.setSurname("Smith");});
  
  System.out.println(persons);

 }

}

The output will be

[Person [firstName=John, surname=Smith], Person [firstName=Peter, surname=Smith]]





More on Java 8 functional interfaces and Lambda expressions

Labels: ,

Understanding Java 8 Lambda expressions with working examples -- part 1

The function interfaces and Lambda expressions are going to make your code concise when coding with Java 8.  These are the most awaited features among Java developers. If you understand these 2 examples, you will find the other parts easier to understand.

Q. What is a Lambda expression?
A. Lambda expressions are anonymous methods which are intended to replace the bulkiness of anonymous inner classes with a much more compact mechanism. 

Q. What is a functional interface?
A. The annotation @FunctionalInterface is being introduced. This annotation acts similarly to @Override by signaling to the compiler that the interface is intended to be a functional interface. The compiler will then throw an error if the interface has multiple abstract methods.


Example 1:  writing your own functional interface and Lambda expressions

Step 1: Define  a functional interface Summable with one abstract method as it can only have 1 abstract method. You can declare default and static  methods too.


package com.java8.examples;

@FunctionalInterface
public interface Summable {
  abstract int sum(int input1, int input2);
}


Step 2:  Define the SumTest class and provide the Lambda expression to sum 2 numbers. You can think of it as method implementation of  sum(int input1, int input2) defined in the functional interface above.

package com.java8.examples;

public class SumTest  {

 public static void main(String[] args) {
  System.out.println("Sum = " +  new SumTest().sum(2, 3));
 }

 public int sum( int input1,  int input2) {
  //(argument) -> (body) or
  //(input) -> (result)
  
  Summable adder = (x, y) -> (x + y);

  //invoke anonymous method 
  return adder.sum(input1, input2);
 }  
}

The output will be:

 
Sum = 5



Example 2: Using the existing Java Comparator interface and implementing your own implementation to compare two numbers.

Step 1: Here is the class that implements the compare(T o1, T o2) via anonymous methods using the Lambda expression.

package com.java8.examples;

import java.util.Comparator;

public class CompareTest {

 public static void main(String[] args) {
  System.out.println(new CompareTest().compare(2, 3));
 }

 public int compare( int input1,  int input2) {
  //(argument) -> (body)
  //(input) -> (result)
  
  Comparator<Integer> cmp = (x, y) -> {
       return (x < y) ? -1 : ((x > y) ? 1 : 0);
  };
  
  //invoke anonymous method
  return cmp.compare(input1, input2);
    
 }
}

The output:
 
-1



Step: optional understanding: To understand this better, if you inspect the Comparator interface, it has been enhanced in Java 8 with

  •  @FunctionalInterface annotation
  • a number of default method implementations like reversed( ), thenComparing(Comparator other), etc.
  • a number of static utility methods like naturalOrder ( ), nullsLast(Comparator comparator), etc.


The simplified Comparator functional interface looks like

 
package java.util;

import java.io.Serializable;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.function.ToDoubleFunction;
import java.util.Comparators;

@FunctionalInterface
public interface Comparator<T> {

     int compare(T o1, T o2);
     boolean equals(Object obj);

  default Comparator<T> reversed() {
       return Collections.reverseOrder(this);
    }
 
    //...skipping some methods
 
 public static <T> Comparator<T> nullsLast(Comparator<? super T> comparator) {
        return new Comparators.NullComparator<>(false, comparator);
    }

}


More on Java 8 functional interfaces and Lambda expressions

Labels: ,