Google

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 28, 2014

Core Java coding question to find 2 numbers from an array that add up to the target

Core Java Coding Questions and Answers for beginner to intermediate level

Q1 Q2 Q3 Q4 Q5 - Q8 Q9 Q10 Q11 Q12 - Q14 Q15

Q. Given an array of integers, find two numbers such that they add up to a specific target number?

For example,

Given numbers: {2, 3, 8, 7, 5}
Target number:  9
Result: 2 and 7

A. There are naive algorithms like using  a for loop within a  for loop with O(n^2) complexity. Let's look at more efficient solutions.

Solution 1: Store processed numbers in a set.



Here is the code

package com.java8.examples;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.management.RuntimeErrorException;

public class Sum2NumsToATargetNumberTest {
 
 public static int[] findNumsThatSumToTargetNum(int[] numbers, int target) {
  Set<Integer> processedNumbers = new HashSet<>();
  boolean foundSum = false;
  int[] result = new int[2];
  for (int i = 0; i < numbers.length; i++) {
   int reqNumber = target - numbers[i]; 
   System.out.println("current number="  + numbers[i] + " , requiredNumber = " + reqNumber);
   if(processedNumbers.contains(reqNumber)){
    result[0] = numbers[i];
    result[1] = reqNumber;
    foundSum = true;
    break;
   }
   else {
    processedNumbers.add(numbers[i]);
   }
  }
  
  if(!foundSum){
   throw new RuntimeException("Sum is not found !!");
  }
  
  return result; 
 }
}

The main method to test:

        public static void main(String[] args) {
  int[] numbers = {2, 3, 8, 7, 5};
  int target = 9;
  int[] result = findNumsThatSumToTargetNum(numbers, target);
  System.out.println("Two numbers that add up to " + target + " are " + result[0] + " and " + result[1]);
 }


Output:

current number=2 , requiredNumber = 7
current number=3 , requiredNumber = 6
current number=8 , requiredNumber = 1
current number=7 , requiredNumber = 2
Two numbers that add up to 9 are 7 and 2




Solution 2: Sort the numbers and use 2 pointers.



package com.java8.examples;

import java.util.Arrays;

public class Sum2NumsToATargetNumberTest2 {
 
 public static void main(String[] args) {
  int[] numbers = {2, 3, 8, 7, 5};
  int target = 9;
  int[] result = findNumsThatSumToTargetNum(numbers, target);
  System.out.println("Two numbers that add up to " + target + " are " + result[0] + " and " + result[1]);
 }
 
 // System.out.println("current number="  + numbers[i] + " , requiredNumber = " + reqNumber);
 static int[] findNumsThatSumToTargetNum(int[] numbers, int target) {
  int pointer1 = 0;
  int pointer2 = numbers.length -1;
  
  int[] result = new int[2];
  
  Arrays.sort(numbers); // sort the numbers
  
  while(pointer2 >= pointer1) {
   int sum = numbers[pointer1] + numbers[pointer2];
   if(sum == target) {
    result[0] = numbers[pointer1] ;
    result[1] = numbers[pointer2] ;
    break;
   }
   
   //if sum is greater than the target
   if(sum > target) {
    pointer2--; //move pointer2 to the left to reduce the sum
   }
   
   //if sum is less than the target
   if(sum < target) {
    pointer1++; //move pointer1 to the right to increase the sum
   }
  }
  
  
  
  return result;
  
 }
}


Output:

Two numbers that add up to 9 are 2 and 7

Labels: ,

Core Java coding question on palindrome

Core Java Coding Questions and Answers for beginner to intermediate level

Q1 Q2 Q3 Q4 Q5 - Q8 Q9 Q10 Q11 Q12 - Q14 Q15

Q. What is a palindrome?
A. A palindrome is a word or sentence that reads the same forward as it does backward. For example, the terms "racecar", "dad", "madam" and the name "Hannah". The longest palindromic substring of "bananas" is "anana" -- the left side of a palindrome is a mirror image of its right side.




  //loop from left to right  
    for (int i = 0; i < s.length() - 1; i++) {
  if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
   return false;
  }
 }
 
 return true;


"anana" is a palindrome.

i = 0 --> a != a : false
i = 1 --> n != n : false
i = 2 --> a != a : false
i = 3 --> n != n : false
i = 4 --> break the loop

Alternatively, the reversed string must match the original string.

      String reverse = "";

      //loop from right to left
      for ( int i = length - 1 ; i >= 0 ; i-- ) {
         reverse = reverse + s.charAt(i);
   }
 
      if (s.equals(reverse)) {
        return true;
   } 
   else {
        return false;
   }


We don't actually have to process all the characters, and can stop in the middle

package com.java8.examples;

public class PalindromeTest {

 public static void main(String[] args) {
  System.out.println("Is madam a Palindrome? " + isPalindrome("madam"));
 }

 public static boolean isPalindrome(String s) {
  boolean result = false;

  int i, begin, end, middle;

  begin = 0;
  end = s.length() - 1;
  middle = (begin + end) / 2;

  //process from left to middle
  for (i = begin; i <= middle; i++) {
   if (s.charAt(begin) == s.charAt(end)) {
    begin++;
    end--;
   } else {
    break;
   }
  }

  //if has gone past the middle
  if (i == middle + 1) {
   result = true;
  }

  return result;
 }
}


Q. How will you find the longest palindrome of a given string?
A. Algorithm: Have 2 center pointers, and move  one to the left and the other to the right. Cater for 2 scenarios where you have odd number of characters and even number of characters as shown below.



package com.java8.examples;

public class PalindromeLongestSubstring {
 
  private static String findLongestPalindrome(String s){
  if(s == null || s.length() == 1){
   return s;
  }
  
  String longest = s.substring(0,1);
  
  for (int i = 0; i < s.length(); i++) {
   //one center. odd number of characters (e.g 12321)
   String result = findPalindromeForGivenCenter(s, i, i);
   longest = result.length() > longest.length()? result : longest;
   
   //two centers. even number of characters (e.g 123321)
   result = findPalindromeForGivenCenter(s, i, i+1);
   longest = result.length() > longest.length()? result : longest;
  }
  
  return longest;
 }
 
 
 
 // Given either same left and right center (e.g.12321) or 
 // 2 left and right centers  (e.g. 123321) find the longest palindrome
 private static String findPalindromeForGivenCenter (final String s, int leftCenter, int rightCenter) {
  int length = s.length();
  
  while (leftCenter >= 0 && rightCenter <= length -1 && s.charAt(leftCenter) == s.charAt(rightCenter)) {
   leftCenter--;  //move from center to left
   rightCenter++; //move from center to right 
  }
  
  //leftCenter+1 because the index would have moved left before exiting the above loop
  return s.substring(leftCenter+1,rightCenter);
 }

}


Test the output for different inputs

        public static void main(String[] args) {
  String s1 = "12321", s2= "123321", s3 = "71233218", s4="1234", s5="88123217";
  System.out.println(s1  + " = " + findLongestPalindrome(s1));
  System.out.println(s2  + " = " + findLongestPalindrome(s2));
  System.out.println(s3  + " = " + findLongestPalindrome(s3));
  System.out.println(s4  + " = " + findLongestPalindrome(s4));
  System.out.println(s5  + " = " + findLongestPalindrome(s5));
  
  String s6 = "HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE";
  System.out.println(s6  + " = " + findLongestPalindrome(s6));
  
 }



Output:

12321 = 12321
123321 = 123321
71233218 = 123321
1234 = 1
88123217 = 12321
HYTBCABADEFGHABCDEDCBAGHTFYW12345678987654321ZWETYGDE = 12345678987654321

Labels: ,

Apr 27, 2014

Core Java coding interview question and answer on Reverse Polish Notation (RPN)

Q.  Can you explain Reverse Polish Notation (RPN)?
A.  You have already heard about the following from your elementary schooling:

  • "Please Excuse My Dear Aunt Sally" (meaning Parentheses, Exponentiation (roots and powers), Multiplication, Division, Addition, and Subtraction
  • BODMAS, tells us to attend to Brackets, Of, Division, Multiplication, Addition, and Subtraction

This means:

(1+2)*3 = 9 using BODMAS or  "Please Excuse My Dear Aunt Sally

Polish Notation was invented in the 1920's by Polish mathematician Jan Lukasiewicz, who showed that by writing operators in front of their operands, instead of between them, brackets were made unnecessary


3 2 1 + x = 9  using Reverse Polish Notion (RPN).



In programming, the RPN is evaluated using a stack, which is a LIFO (Last In First Out) data structure.

The algorithm for RPN is: 

Keep pushing the numbers into a stack, and when it is an operator, pop two numbers from the stack, do the calculation, and push back the result.




Q. Can you write code that demonstrates RPN?
A. It can be coded in Java 7, as shown below. Java 7 supports string in switch statements.



package com.java8.examples;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Stack;

public class ReversePolishNotationTest {

 public static void main(String[] args) {
  
  String[] tokens = new String[] { "3", "2", "1", "+", "*" };
        System.out.println(evalRPN(tokens));
 }
 
 
 
 public static int evalRPN(String[] tokens){
  int result = 0;
  String operators = "+-*/";
  
  //Double ended queue can be used as a stack LIFO(push/pop) or queue FIFO (offer/poll).
  Deque<String> stack = new ArrayDeque<String>();
  
  for (String string : tokens) {
   //keep pushing the numbers
   if (!operators.contains(string)) {
    stack.push(string);
   } else { //for operators
    int a = Integer.valueOf(stack.pop());
    int b = Integer.valueOf(stack.pop());
    switch (string) {
    case "+":
     stack.push(String.valueOf(a + b));
     break;
    case "-":
     stack.push(String.valueOf(b - a));
     break;
    case "*":
     stack.push(String.valueOf(a * b));
     break;
    case "/":
     stack.push(String.valueOf(b / a));
     break;
    }
   }
  }
  
  //get the value left in th stack
  result = Integer.valueOf(stack.pop());
  
  return result;
 }

}




Things to remember:

1. Algorithm: Keep pushing the numbers into a stack, and when it is an operator, pop two numbers from the stack, do the calculation, and push back the result.

2. Use a stack, which is a LIFO data structure.

3. In Java, Deque is a linear collection that supports element insertion and removal at both ends. The name deque is short for "double ended queue" and is usually pronounced "deck".

Labels: ,

Apr 26, 2014

Creating a simple Java Web project with Maven tutorial -- Part 3 with eclipse

The part-1 and part-2 built the simpleWeb war  file outside eclipse using Maven. In this post, let's cover how eclipse interacts with Maven.

Step 1: start up your eclipse and verify if it has m2e (Maven to Eclipseplugin. Click on Help --> About Eclipse


Step 2:  Eclipse needs to know where your Maven settings.xml file is so that it can access your local repository.  Click on Window --> Preferences --> Maven --> User Settings.



Step 3: You can import any Maven artifact into eclipse. That is with a pom.xml file.  Click on File --> Import, and select "Existing Maven Projects" from within Maven.

Step 4: Browse and select your simpleWeb project.


Step 5: You can now work within eclipse.


Step 6:  Go to your DOS command prompt, and then run mvn eclipse:eclipse from the simpleWeb folder.

Step 7: Now come back to eclipse and select simpleWeb and press F5 to refresh the project. You should now see the referenced libraries read from your pom.xml file.



Step 8:  You can now run within eclipse by right-clicking on simpleWeb and then selecting RunAs  and then Maven clean, Maven install, Maven  test, etc. Alternatively, select "Maven build" and eneter a goal to execute like "package".




Labels: ,

Apr 23, 2014

Understanding Java generics with the help of scenarios -- part 2

Extends Understanding Java generics with the help of scenarios -- part 1

Scenario 2: A custom generic class GenericMultipleTypesScenario class that handles Integer and Double types.



import java.util.List;

public class GenericMultipleTypesScenario<Number> {

 public void readOnly(List<? extends Number> numbers) {
   for (Number number : numbers) {
   System.out.println("readOnly: " + number);
  }
 }

 public void witeOnly(List<? super Number> numbers, Number aNumber) {
  numbers.add(aNumber);
 }

 public void witeAndRead(List<Number> numbers, Number aNumber) {
  numbers.add(aNumber);
  for (Number number : numbers) {
   System.out.println("readAndWrite: " + number);
  }

 }
}


The test class

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

public class GenericMultipleTypesScenarioTest {
 
 public static void main(String[] args) {
     //Integer
  GenericMultipleTypesScenario<Integer> integerType = new GenericMultipleTypesScenario<Integer>();
  List<Integer> numbers = new ArrayList<Integer>();
  numbers.add(1); //autoboxes 1 to type Integer
  
  integerType.readOnly(numbers);
  integerType.witeOnly(numbers, 6);  //autoboxes 6 to type Integer
  integerType.witeAndRead(numbers, Integer.valueOf(9));
  
  //Double
  GenericMultipleTypesScenario<Double> doubleType = new GenericMultipleTypesScenario<Double>();
  List<Double> numbersDouble = new ArrayList<Double>();
  numbersDouble.add(1.5); //autoboxes 1.5 to type Double
  
  doubleType.readOnly(numbersDouble);
  doubleType.witeOnly(numbersDouble, 6.5);  //autoboxes 6.5 to type Double
  doubleType.witeAndRead(numbersDouble, Double.valueOf(9.5));
  
 }
}



Output:

readOnly: 1
readAndWrite: 1
readAndWrite: 6
readAndWrite: 9
readOnly: 1.5
readAndWrite: 1.5
readAndWrite: 6.5
readAndWrite: 9.5


Scenario 3: A custom generic class GenericAnyTypesScenario class that handles any type like Integer, Double, String, etc. The any type is defined in this example as letter T. It can be any letter.



import java.util.List;

public class GenericAnyTypesScenario<T> {

 public void readOnly(List<? extends T> values) {
   for (T value : values) {
   System.out.println("readOnly: " + value);
  }
 }

 public void witeOnly(List<? super T> values, T aValue) {
  values.add(aValue);
 }

 public void witeAndRead(List<T> values, T aValue) {
  values.add(aValue);
  for (T value : values) {
   System.out.println("readAndWrite: " + value);
  }

 }
}


Test class





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

public class GenericAnyTypesScenarioTest {
 
 public static void main(String[] args) {
  //integer type
  GenericAnyTypesScenario<Integer> integerType = new GenericAnyTypesScenario<Integer>();
  List<Integer> valuesIntegers = new ArrayList<Integer>();
  valuesIntegers.add(1); //autoboxes 1 to type Integer
  
  integerType.readOnly(valuesIntegers);
  integerType.witeOnly(valuesIntegers, 6);  //autoboxes 6 to type Integer
  integerType.witeAndRead(valuesIntegers, Integer.valueOf(9));
  
  
  //double type
  GenericAnyTypesScenario<Double> doubleType = new GenericAnyTypesScenario<Double>();
  List<Double> valuesDouble = new ArrayList<Double>();
  valuesDouble.add(1.5); //autoboxes 1.5 to type Double
  
  doubleType.readOnly(valuesDouble);
  doubleType.witeOnly(valuesDouble, 6.5);  //autoboxes 6.5 to type Double
  doubleType.witeAndRead(valuesDouble, Double.valueOf(9.5));
  
  
  //string type
  GenericAnyTypesScenario<String> stringType = new GenericAnyTypesScenario<String>();
  List<String> valuesString = new ArrayList<String>();
  valuesString.add("apple");
  
  stringType.readOnly(valuesString);
  stringType.witeOnly(valuesString, "orange");
  stringType.witeAndRead(valuesString, "mango");
  
 }
}



Output:

readOnly: 1
readAndWrite: 1
readAndWrite: 6
readAndWrite: 9
readOnly: 1.5
readAndWrite: 1.5
readAndWrite: 6.5
readAndWrite: 9.5
readOnly: apple
readAndWrite: apple
readAndWrite: orange
readAndWrite: mango


Labels:

Apr 22, 2014

Understanding Java generics with the help of scenarios and working examples -- part 1

Q1. If java.lang.Object is the super type for java.lang.Number and, Number is the super type for java.lang.Integer, am I correct in saying that List<Object> is the super type for List<number> and, List<Number> is the super type for List<Integer>.



A1. No. List<Object> is not the the super type of List<Number>. If that were the case, then you could add objects of any type, and it defeats the purpose of Generics.

/* Compile Error: Type mismatch. Cannot convert from ArrayList<Integer> to List<Number>*/
List<Number> numbers2 = new ArrayList<Integer>();


//Compiles
List<Integer> numbers3 = new ArrayList<Integer>();


/*Compile Error: Cannot instantiate the type ArrayList<? super Integer>*/
List<? super Integer> numbers6 = new ArrayList<? super Integer>();


//Compiles
List<? super Integer> numbers7 = new ArrayList<Integer>();
numbers7.add(Integer.valueOf(5)); //ok


//Compiles
List<? extends Number> numbers5 = new ArrayList<Number>();
//Compile error:  Read only.Can't add
numbers5.add(Integer.valueOf(5));


In Generics, wildcards (i.e. ?), makes it possible to work with super classes and sub classes.

Q2. How will you go about deciding which of the following to use?
  • <Number>
  • <? extends Number>
  • <? super Number>

A2. Here is the guide:

1. Use the ? extends wildcard if you need to retrieve object from a data structure. That is read only. You can't add elements to the collection.
2. Use the ? super wildcard if you need to put objects in a data structure.
3. If you need to do both things (read and add elements), don’t use any wildcard.


Let's take 3 scenarios to explain this.


Scenario 1: A custom generic class GenericSingleTypeScenario class that handles only Integer types.


import java.util.List;

public class GenericSingleTypeScenario<Integer> {

 public void readOnly(List<? extends Number> numbers) {
  for (Number number : numbers) {
   System.out.println("readOnly: " + number);
  }
 }

 public void witeOnly(List<? super Integer> numbers, Integer aNumber) {
  numbers.add(aNumber);
 }

 public void witeAndRead(List<Integer> numbers, Integer aNumber) {
  numbers.add(aNumber);
  for (Integer integer : numbers) {
   System.out.println("readAndWrite: " + integer);
  }

 }
}


Add a test class with a main method to test the above class

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

public class GenericSingleTypeScenarioTest {
  
 public static void main(String[] args) {
  GenericSingleTypeScenario<Integer> singleType = new GenericSingleTypeScenario<Integer>();
  List<Integer> numbers = new ArrayList<Integer>();
  numbers.add(1); //autoboxes 1 to type Integer
  
  singleType.readOnly(numbers);
  singleType.witeOnly(numbers, 6);  //autoboxes 6 to type Integer
  singleType.witeAndRead(numbers, Integer.valueOf(9));
  
 }
}


Output:

readOnly: 1
readAndWrite: 1
readAndWrite: 6
readAndWrite: 9


Generics scenarios 2 and 3.

Labels:

Apr 17, 2014

Understanding Java custom annotation with a practical example

In real life Java applications, you need to provide service retries on failures. For example, retry 3 times at the interval of 3 seconds, etc. Here is a custom Java annotation example.

Step 1: Define the Retry run-time annotation to be applied to the declared fields.


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface Retry {

 int attempts() default 3;
 int delayInSeconds() default 1; // default 1 second

}


Step 2:  Use the above custom run-time annotation in the PrinterServiceUtil, so that it will retry the service (e.g. DummyService) that it wraps.

public class PrintServiceTest {

 @Retry(attempts = 3, delayInSeconds = 3) //retry 3 times @ 3 seconds interval
 private PrintServiceUtil printService;

 public static void main(String[] args) {

  PrintServiceUtil printService = new PrintServiceUtil();
  printService.print("Hello");
 }
}


Step 3PrinterServiceUtil  class that uses the annotation to decide, if retry is required, and if required, what retry count and retry values to use by extracting them from the annotation.

import java.lang.reflect.Field;

/**
 * A bit convoluted method to demonstrate custom annotation to keep it simple without
 * AOP and Dependency injection frameworks, which are more suited.
 * 
 */

public class PrintServiceUtil {

 private DummyService service;

 public void print(String message) {

  //if PrintServiceUtil invoking this is annotated with retry
  //use dynamic proxy design pattern to retry if the service is down
  Field[] fields = getCallerClassName().getDeclaredFields();
  boolean serviceCreated = false;

  for (Field field : fields) {
   Retry annotation = field.getAnnotation(Retry.class);
   if (annotation != null && field.getType() == PrintServiceUtil.class) {
    service = (DummyService) RetryProxy.newInstance(new DummyServiceImpl(), annotation.attempts(),
      annotation.delayInSeconds());
    serviceCreated = true;
   }
  }

  //if not annotated, retry is not required
  if (!serviceCreated) {
   service = new DummyServiceImpl();
  }

  service.execute(message); //execute the service
 }

 
 
 /**
  * gets the calling class from the stack trace
  * @return
  */
 private Class getCallerClassName() {
  String callerClassName = null;

  try {
   callerClassName = new Exception().getStackTrace()[2].getClassName();
   return Class.forName(callerClassName);
  } catch (Exception ex) {}

  throw new RuntimeException("Error getting caller class");
 }
}


Step 4: The DummyService interface and implementations are similar to the dynamic proxy tutorial -- retry example.

public interface DummyService {
     abstract void execute(String message);
}


public class DummyServiceImpl implements DummyService {
 
 private int count = 0 ;
 
 public void execute(String message) {
  count++;
  if(count % 3 == 0){
   System.out.println (message);
  }
  else {
   throw new RuntimeException("Service Cannot be accessed ..... ");
  }
 }

}



Step 5: The dynamic proxy class that performs the actual retry.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

public class RetryProxy<T> implements InvocationHandler {

 final T delegate; // underlying object
 int retryCount;
 long delay;

 //create a proxy
 public static Object newInstance(Object obj, int retryCount, long delay) {
  return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
    obj.getClass().getInterfaces(), new RetryProxy(obj, retryCount, delay));
 }

 private RetryProxy(T underlying, int retryCount, long delay) {
  this.delegate = underlying;
  this.retryCount = retryCount;
  this.delay = delay;
 }

 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  int retries = 0;
  boolean completed = false;
  Object ret = null;

  while (!completed) {
   try {
    ret = method.invoke(delegate, args);
    completed = true;
   } catch (Exception e) {
    retries++;
    if (retries > retryCount) {
     completed = true;
     throw e;
    }
    
    TimeUnit.SECONDS.sleep(delay);
    System.out.println("Retrying the service. Retry count " + retries);
   }
  }

  return ret;

 }
}


Output:

Retrying the service. Retry count 1
Retrying the service. Retry count 2
Hello

Change the annotation properties and test it.

Labels:

Apr 16, 2014

How to create immutable objects more elegantly in Java?

It is a best practice to create immutable objects where possible because they are inherently thread-safe as you cannot modify them once created, and makes your code easier to debug.

Here is an approach to create immutable objects in Java with the builder design pattern.

The Driver POJO with the Builder as the static inner class.


package com.java8.examples;

public class Driver {
 enum SEX {
  MALE, FEMALE
 }

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

 private Driver(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.sex = builder.sex;
 }

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

 //builder design pattern
 public static class Builder {
  private String name;
  private int age;
  private SEX sex;

  public Builder name(String name) {
   this.name = name;
   return this;
  }

  public Builder age(int age) {
   this.age = age;
   return this;
  }

  public Builder sex(SEX sex) {
   this.sex = sex;
   return this;
  }

  public Driver build() {
   return new Driver(this);
  }
 }
}


Now, here is how you elegantly construct the Driver object


package com.java8.examples;

public class DriverTest {
 
 public static void main(String[] args) {
  
   //immutable driver1 as Driver class has not setter methods
   Driver driver1 = new Driver.Builder()
             .name("John")
             .age(18)
             .sex(Driver.SEX.MALE)
             .build();
      
   System.out.println(driver1);
   
 }

}


Another example to create a list of drivers

package com.java8.examples;

import java.util.Arrays;
import java.util.List;

public class DriverTest {
 
 public static void main(String[] args) {
  List<driver> drivers = Arrays.asList (
  
   new Driver.Builder()
             .name("John")
             .age(18)
             .sex(Driver.SEX.MALE)
             .build(),
             
   new Driver.Builder()
             .name("Jessica")
             .age(24)
             .sex(Driver.SEX.FEMALE)
             .build(),
             
   new Driver.Builder()
             .name("Samantha")
             .age(36)
             .sex(Driver.SEX.FEMALE)
             .build()
                
   );   
    
 }

}



Another good practical example is Performing financial calculations with BigDecimal and Builder design pattern.

Labels:

Apr 15, 2014

Understanding dynamic proxies in Java with a practical example -- Service retry example

We earlier looked at  Java dynamic proxy class example --  Performance testing your Java application.

Design pattern: If you are asked to describe or talk about a design pattern, you could mention this dynamic proxy class as a proxy design pattern. Many pick either singleton or factory design pattern. It would be nicer to pick something other than these two common patterns. Some interviewers specifically ask you to pick anything except factory and singleton design pattern.

In real life applications, you need to retry services that fail. Let's us this retry service scenario to demonstrate dynamic proxy design pattern in Java.

Step 1: Create a dummy service to emulate an internal or external service with outage.


public interface DummyService {
     abstract void execute();
}


Step 2: The dummy service implementation that emulates failure every time except every 3rd call.

public class DummyServiceImpl implements DummyService {
 
 private int count = 0 ;
 
 public void execute() {
  count++;
  if(count % 3 == 0){
   System.out.println ("Executing service ............. ");
  }
  else {
   throw new RuntimeException("Service Cannot be accessed ..... ");
  }
 }

}




Step 3: Write a Retry service class using the dynamic proxy pattern, which acts as a proxy to retry services on its delegate i.e. DummyService. The service  invoker can specify the retry count.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class RetryProxy<T> implements InvocationHandler {

 final T delegate; // underlying object
 int retryCount;

 //create a proxy
 public static Object newInstance(Object obj, int retryCount) {
  return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
    obj.getClass().getInterfaces(), new RetryProxy(obj, retryCount));
 }

 private RetryProxy(T underlying, int retryCount) {
  this.delegate = underlying;
  this.retryCount = retryCount;
 }

 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  int retries = 0;
  boolean completed = false;
  Object ret = null;

  while (!completed) {
   try {
    ret = method.invoke(delegate, args);
    completed = true;
   } catch (Exception e) {
    retries++;
    if (retries > retryCount) {
     completed = true;
     throw e;
    }
    System.out.println("Retrying the service. Retry count " + retries);
   }
  }

  return ret;

 }
}



Step 4: The test class to invoke the DummyService via its proxy.

public class DummyServiceInvocationTest {

 public static void main(String[] args) {
  DummyServiceInvocationTest test = new DummyServiceInvocationTest();
  test.method1();
 }

 public void method1() {
  DummyService service = (DummyService) RetryProxy.newInstance(new DummyServiceImpl(), 1);
  service.execute();
 }

}


Output:

Retrying the service. Retry count 1
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
 at com.sun.proxy.$Proxy0.execute(Unknown Source)
 at DummyServiceInvocationTest.method1(DummyServiceInvocationTest.java:13)
 at DummyServiceInvocationTest.main(DummyServiceInvocationTest.java:8)
Caused by: java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:491)
 at RetryProxy.invoke(RetryProxy.java:28)
 ... 3 more
Caused by: java.lang.RuntimeException: Service Cannot be accessed ..... 
 at DummyServiceImpl.execute(DummyServiceImpl.java:12)
 ... 8 more


Increase the number of recounts to 3

 public void method1() {
  DummyService service = (DummyService) RetryProxy.newInstance(new DummyServiceImpl(), 3);
  service.execute();
 }



Output:


Retrying the service. Retry count 1
Retrying the service. Retry count 2
Executing service ............. 

Labels:

Apr 14, 2014

Understanding Big O notations through Java examples

Q. Have you seen job advertisements requiring Java candidates to work in real-time or high volume transaction processing systems?

If you are applying for such jobs, you can be quizzed on Big O notation. Here are some basics to brush up on.

Big-O gives you the upper bound. For example, if you need to search an element in an array and you expect the array to be large, you might just say that you opt for a binary search instead of a sequential scan because the former has O(log n) complexity wheres the latter has O(n) complexity.

Big-O Description/Example If n=10, and c=2 If n=20, and c=2
O(1)

Constant
Running time is constant.

Determining if a String is equal to a given value


if(str.equals("java"))
{
    return true;
}
else {
    return false;
}

A Map look up by key -- map.get(key);
1 1
O(log n)

Logarithmic
Running time increases logarithmically in proportion to the input size.

Finding an item in a sorted array with a binary search

For example, search for 2 in a list of numbers 1,2,3,4,5,6,7

  • Step 1: Sort the data set in ascending order as binary search works on sorted data.
  • Step 2: Get the middle element (e.g. 4) of the data set and compare it against the search item (e.g. 2), and if it is equal return that element
  • Step 3: If search item value is lower, discard the second half of the data set and use the first half (e.g. 1,2,3). If the search item value is higher, then discard the first half and use the second half (e.g. 5,6,7)
  • Step 4: Repeat steps 2 and 3 until the search item is found or the last element is reached and search item is not found.


So, it is iteratively reducing the number of elements it process.
log 10 = 1 log 20 = 1.301
O(n) 

Linear
Running time increases in direct proportion to the input size

Finding an item in an unsorted array or list.

for(int i = 0; i < strings.Length; i++) {
  if(strings[i].equals("java"))
    {
   return true;
    }
    else {
   return false;
    }
}
10 20
O(n log n) 

Super linear
Running time is midway between a linear algorithm and a polynomial algorithm

Collections.sort is an optimized merge sort which actually guarantees O(n log n). A quicksort is generally considered to be faster than a merge sort (i.e. n log n) but isn't stable and doesn't guarantee n log(n) performance. For Merge sort worst case is O(n*log(n)), for Quick sort: O(n^2).
10 log 10 = 10 20 log 20 = 26.02
O(n^c) 

Polynomial
Running time grows quickly based on the size of the input.

O(n^2) Quadratic -- bubble Sort (worst case or naive implementation)

for(int i = 0; i < strings.Length; i++){
  for(int j = 0; j < strings.Length; j++)
      if(i == j) // Don't compare with self
   {
  continue;
   }
   
     if(strings[i].equals(strings[j]))
     {
     return true;
     }
     else {
    return false;
    }
}

10^2 = 100 20^2 = 400
O(c^n) 

Exponential
Running time grows even faster than a polynomial algorithm.

Recursive computation of Fibonacci numbers is a good example of O(2^n) algorithm

public int fib(int n) {
    if (n <= 1) return n;
    else return fib(n - 2) + fib(n - 1);
}
2^10 = 1,024 2^20 = 1,048,576
O(n!) Factorial Running time grows the fastest and becomes quickly unusable for even small values of n.

Recursive computation of factorial

public void nFactorial(int n) {
  for(int i=0; i<n; i=n-1) {
    nfactorial(i);
  } 
10! = 10*9*8*7*6*5*4*3*2*1= 3,628,800 20!= 2432902008176640000


Labels: ,

Apr 12, 2014

Top 8 new features in Java 7 with examples -- part 2

Extends Top 8 new features in Java 7 with examples -- part 1.


#5 Multi-catch to avoid code duplication

public class Java7Feature4 {

 public static void main(String[] args) {

  //pre Java 7
  try {
   someMethod();
  } catch (CustomException1 ex1) {
   ex1.printStackTrace();
  } catch (CustomException2 ex2) {
   ex2.printStackTrace();
  }
  
  
  //Java 7 -- 5 lines as opposed to 7 lines.
  //no code duplication
  try {
   someMethod();
  } catch (CustomException1|CustomException2 ex) {
   ex.printStackTrace();
  }
 }

 public static void someMethod() throws CustomException1, CustomException2 {

 }

 public static class CustomException1 extends Exception {
  private static final long serialVersionUID = 1L;
 }

 public static class CustomException2 extends Exception {
  private static final long serialVersionUID = 1L;
 }

}

Note that the pipe ‘|’ character is used as the delimiter.

#6 Improved type inference for generic instance creation

This is only a small change that makes generics declaration a little less verbose. As shown below, you can just use empty diamond "<>" in Java 7 on the RHS.

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Java7Feature4 {

 public static void main(String[] args) {
        //Pre Java 7
  getEmployeesWithManagersOld("a102");
  //Java 7
  getEmployeesWithManagersNew("a102");
 }

 
 public static Map<String, List<Employee>>  getEmployeesWithManagersOld(String empCode){
   if(empCode == null){
      return Collections.emptyMap();
   }
   
   //gives type safety warning. You need to add <String, List<Employee>> again on the RHS
   Map<String, List<Employee>> mapEmployees = new HashMap();
   
   
   return mapEmployees;
 }

 
 //Java 7
 public static Map<String, List<Employee>>  getEmployeesWithManagersNew(String empCode){
   if(empCode == null){
      return Collections.emptyMap();
   }
   
   //no duplication of generic inference
   Map<String, List<Employee>> mapEmployees = new HashMap<>();
   //do something with mapEmployees
   
   return mapEmployees;
 }

  
 static class Employee {}
}


#7: More new I/O APIs for the Java platform (NIO - 2.0)

Those who worked with Java IO may still remember the headaches that framework caused. It was never easy to work seamlessly across operating systems or multi-file systems. The NIO 2.0 has come forward with many enhancements. It’s also introduced new classes to ease the life of a developer when working with multiple file systems with classes and interfaces such as Path, Paths, FileSystem, FileSystems and others.

Another very handy feature is the WatchService for file change notifications. It can monitor a directory for changes as demonstrated below.

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class Java7Feature7 {

 public static void main(String[] args) throws IOException, InterruptedException {
  
  // Java 7
  Path path = Paths.get("c:\\Temp\\simple.txt");
  System.out.println(path.getFileName());
  System.out.println(path.getRoot());
  System.out.println(path.getParent());

  // Java 7 file change watch service
  WatchService watchService = FileSystems.getDefault().newWatchService();
  
  //register Temp folder with the watch service for addition of new file, modification of a file name, and deletion of a file
  path.getParent().register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
    StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE);

  //wait for incoming events
  while (true) {
   final WatchKey key = watchService.take();
   for (WatchEvent<?> watchEvent : key.pollEvents()) {
    final Kind<?> kind = watchEvent.kind();
    // Overflow event
    if (StandardWatchEventKinds.OVERFLOW == kind) {
     continue; // loop
    } else if (StandardWatchEventKinds.ENTRY_CREATE == kind || StandardWatchEventKinds.ENTRY_MODIFY == kind
      || StandardWatchEventKinds.ENTRY_DELETE == kind) {
     @SuppressWarnings("unchecked")
     final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
     final Path entry = watchEventPath.context();

     System.out.println(kind + "-->" + entry);

    }

   }

   if (!key.reset()) {
    break;
   }
  }

  // deleting a file is as easy as.
  Files.deleteIfExists(path); // Java 7 feature as well.
 }

}


The output will be something like:

simple.txt
c:\
c:\Temp
ENTRY_CREATE-->New Text Document.txt
ENTRY_DELETE-->New Text Document.txt
ENTRY_CREATE-->File1.txt
ENTRY_MODIFY-->File1.txt


#8: Fork and Join

Java 7 has incorporated the feature that would distribute the work across multiple cores and then join them to return the result set as a Fork and Join framework. he effective use of parallel cores in a Java program has always been a challenge. It’s a divide-and-conquer algorithm where Fork-Join breaks the task at hand into mini-tasks until the mini-task is simple enough that it can be solved without further breakups. One important concept to note in this framework is that ideally no worker thread is idle. They implement a work-stealing algorithm in that idle workers “steal” the work from those workers who are busy.

The example below demonstrates this with a simple task of summing up 10 numbers. If the count of numbers to be added are greater than 5, it is forked into chunks of 5 to be processed by separate thread, and the forked sum are then joined to give the overall total of 10 numbers from 1 to 10, which is 55.  The total of numbers 1 to 5 is 15, and 6 to 10 is 40.

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class Java7Feature8 {

 static int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

 public static void main(String[] args) throws IOException, InterruptedException {
     int numberOfCpuCores = Runtime.getRuntime().availableProcessors();
     ForkJoinPool forkJoinPool = new ForkJoinPool(numberOfCpuCores);
     int sum = forkJoinPool.invoke(new ChunkingTask(numbers));
     System.out.println(sum);
 }

 //inner class
 static class SumCalculatorTask extends RecursiveTask<Integer> {
  int[] numbers;

  SumCalculatorTask(int[] numbers) {
   this.numbers = numbers;
  }

  @Override
  protected Integer compute() {
   int sum = 0;
   for (int i : numbers) {
    sum += i;
   }
   
   System.out.println(Thread.currentThread().getName() + " sum = " + sum);

   return sum;
  }
 }

 
 //inner class
 
 /**
  * 
  *chunking size is 5
  */
 static class ChunkingTask extends RecursiveTask<Integer> {

  private static final int CHUNK_SIZE = 5;
  int[] numbers;

  ChunkingTask(int[] numbers) {
   this.numbers = numbers;
  }

  @Override
  protected Integer compute() {
   int sum = 0;
   List<RecursiveTask<Integer>> forks = new ArrayList<>();
   
   //if the numbers size is > CHUNK_SIZE fork them
   if (numbers.length > CHUNK_SIZE) {
    ChunkingTask chunk1 = new ChunkingTask(Arrays.copyOfRange(numbers, 0, numbers.length / 2));
    ChunkingTask chunk2 = new ChunkingTask(Arrays.copyOfRange(numbers, numbers.length / 2, numbers.length));
    forks.add(chunk1);
    forks.add(chunk2);
    chunk1.fork();
    chunk2.fork();
   //size is less than or equal to CHUNK_SIZE start summing them 
   } else {
    SumCalculatorTask sumCalculatorTask = new SumCalculatorTask(numbers);
    forks.add(sumCalculatorTask);
    sumCalculatorTask.fork();
   }

   // Combine the result from all the tasks
   //join 
   for (RecursiveTask<Integer> task : forks) {
    sum += task.join();
   }

   return sum;
  }

 }

}


Output is:

ForkJoinPool-1-worker-2 sum = 15
ForkJoinPool-1-worker-2 sum = 40
55

Java 8's Arrays.parallelSort( ... ) make use of this fork and join feature to sort an array in parallel.

Labels:

Apr 11, 2014

Top 8 new features in Java 7 with examples

There are several small new features and enhancements in Java 7. The major features and enhancements coming in Java 8. Let's look at the Java 7 new features.

#1: string in switch statement:

public class Java7Feature1 {

 private static String color = "BLUE";

 private enum Color {
  RED, GREEN
 };

 public static void main(String[] args) {

  // Pre Java 5
  if (color.equals("RED")) {
   System.out.println("Color is Red");
  } else if (color.equals("GREEN")) {
   System.out.println("Color is Green");
  } else {
   System.out.println("Color not found");
  }

  // Java 5 enum. try/catch is required for colours other than RED and GREEN 
  try {
   switch (Color.valueOf(color)) {
   case RED:
    System.out.println("Color is Red");
    break;
   case GREEN:
    System.out.println("Color is Green");
   }
  } catch (IllegalArgumentException e) {
   System.out.println("Color not found");
  }

  // Java 7 String in switch statement for simplicity & better readability
  //JDK 7 switch performs better than if-else
  //using types with enums is only useful when it serves a meaningful purpose
  //the value for color could come from database, and string in switch is handy for this
  switch (color) {
  case "RED":
   System.out.println("Color is Red");
   break;
  case "GREEN":
   System.out.println("Color is Green");
   break;
  default:
   System.out.println("Color not found");
  }
 }

}



Output is:

Color not found
Color not found
Color not found


#2 Binary integral literals

public class Java7Feature2 {

 public static void main(String[] args) {
  // Pre Java 7
  int n = Integer.parseInt("10000000", 2);
  System.out.println(n);

  n = 1 << 7;
  System.out.println(n);

  // Java 7
  n = 0b10000000; // 128 = 2^7
  System.out.println(n);
 }
}


Output:

128
128
128


#3: Underscores for better readability in numeric literals

public class Java7Feature3 {

 public static void main(String[] args) {
         //pre Java 7
   int million = 1000000;
   System.out.println(million);
   
   //Java 7. More readable
   million = 1_000_000;
   System.out.println(million);
      
   //consecutive underscores are allowed
   int ten_million = 10__000_000;
   System.out.println(ten_million);
      
   //underscores can be used in other numeric types
   double million_dollars_5_cents = 1_000_000.0_5d;
   System.out.println(million_dollars_5_cents);
   
   //illegal to have underscores 
   //1. start or end a literal with an underscore _10.00, 10.00_
   //2. have underscores before or after a decimal point 10_.00, 10._00
 }
}

Output:

1000000
1000000
10000000
1000000.05



#4: AutoCloseable interface. 

Java 5 introduced the Closeable interface and Java 7 has introduced the AutoCloseable interface to avoid the unsightly try/catch/finally(within finally try/catch) blocks to close a resource. It also prevents potential resource leaks due to not properly closing a resource. The java.io.InputStream and java.io.OutputStream now implements the AutoCloseable interface.



try-with-resources is one of the most useful additions in Java 7.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Java7Feature4 {

 public static void main(String[] args) {
  // pre Java 7
  BufferedReader br = null;

  try {
   File f = new File("c://temp/simple.txt");
   InputStream is = new FileInputStream(f);
   InputStreamReader isr = new InputStreamReader(is);
   br = new BufferedReader(isr);

   String read;

   while ((read = br.readLine()) != null) {
    System.out.println(read);
   }
  } catch (IOException ioe) {
   ioe.printStackTrace();
  } finally {
   try {
    if (br != null)
     br.close();
   } catch (IOException ex) {
    ex.printStackTrace();
   }
  }

  
  // Java 7 -- more concise 11 lines as opposed to 20 lines
  try (InputStream is = new FileInputStream(new File("c://temp/simple.txt"));
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br2 = new BufferedReader(isr);) {

   String read;

   while ((read = br2.readLine()) != null) {
    System.out.println(read);
   }

  }
  catch (IOException ioe) {
   ioe.printStackTrace();
  }

 }

}

The output is:

Big
brown fox
jumped over the fence
Big
brown fox
jumped over the fence


try can now have multiple statements in the parenthesis and each statement should create an object which implements the new java.lang.AutoCloseable interface. The AutoCloseable interface consists of just one method. void close () throws Exception {}. Each AutoClosable resource created in the try statement will be automatically closed! If an exception is thrown in the try block and another Exception is thrown while closing the resource, the first Exception is the one eventually thrown to the caller.

Think of the close( ) method as implicitly being called as the last line in the try block.


Features 5 to 8 are covered in Java 8 new features in Java 7 with examples -- part 2

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?
AThe 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: ,