Google

Jun 28, 2014

Working with Java BigDecimal class for monetary values

When you are working with monetary values in Java, you must use a BigDecimal data type. Many developers often have the following questions.

Q1. How to compare BigDecimal numerically?
This means 5.120 should be equal to 5.1200000. The default equals( ) implementation in BigDecimal class returns true only if two objects are numerically equivalent AND have the same scale(i.e. 5.120  is not equals( ) to 5.1200000).

Q2. How to check if an amount is zero, positive, or negative?
Q3. How to extract the decimal portion of the amount?
Q4. How to determine if it is an integer value?

Here is a utility class that answers the above questions


package com.writtentest10;

import java.math.BigDecimal;

public class BigDecimalUtils {

 private BigDecimalUtils() {

 }

 /**
  * The 'equals'  method in BigDecimal class returns true 
  * only if the two objects are numerically equivalent AND
  * have the same scale so (4.130 != 4.130000000)
  * 
  * This method returns true if the two values are numerically equivalent
  * 
  */
 public static boolean equals(BigDecimal value1, BigDecimal value2) {
  return (value1.compareTo(value2) == 0);
 }

 public static boolean isZero(BigDecimal value) {
  return (value.signum() == 0);
 }

 public static boolean isNonZero(BigDecimal value) {
  return (value.signum() != 0);
 }

 public static boolean isPositive(BigDecimal value) {
  return (value.signum() == 1);
 }

 public static boolean isNegative(BigDecimal value) {
  return (value.signum() == -1);
 }

 public static BigDecimal getExponent(BigDecimal value) {
  return BigDecimal.valueOf(value.longValue());
 }

 public static BigDecimal getMantissa(BigDecimal value) {
  if (isZero(value)) {
   return value;
  }

  BigDecimal result = value.abs();
  BigDecimal exponent = getExponent(result);

  if (isZero(exponent)) {
   return result;
  }

  return result.subtract(exponent);
 }

 public static boolean isInteger(BigDecimal value) {
  return isZero(value) ? false : isZero(getMantissa(value));
 }

}



The JUnit test class

package com.writtentest10;

import java.math.BigDecimal;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class BigDecimalUtilsTest {

 private boolean setUpIsDone = false;

 private BigDecimal positiveValue1;
 private BigDecimal positiveValue2;
 private BigDecimal negativeValue;

 @Before
 public void init() {

  if (setUpIsDone) {
   return;
  }

  positiveValue1 = BigDecimal.valueOf(25.12);
  positiveValue2 = BigDecimal.valueOf(25.1200);
  negativeValue = BigDecimal.valueOf(-25.12);

  setUpIsDone = true;
 }

 @Test
 public void testEqual() {
  Assert.assertTrue(BigDecimalUtils.equals(positiveValue1, positiveValue2));
  Assert.assertFalse(BigDecimalUtils.equals(positiveValue1, negativeValue));
 }
 
 
 @Test
 public void testPositiveNegativeAndZero() {
  Assert.assertTrue(BigDecimalUtils.isPositive(positiveValue1));
  Assert.assertTrue(BigDecimalUtils.isNegative(negativeValue));
  Assert.assertTrue(BigDecimalUtils.isZero(BigDecimal.ZERO));
  
  Assert.assertFalse(BigDecimalUtils.isPositive(negativeValue));
  Assert.assertFalse(BigDecimalUtils.isNegative(positiveValue1));
  Assert.assertFalse(BigDecimalUtils.isZero(positiveValue1));
 }
 
 
 
 @Test
 public void testGetMantissa() {
  Assert.assertEquals(BigDecimal.valueOf(0.12),BigDecimalUtils.getMantissa(positiveValue1));
  Assert.assertEquals(BigDecimal.valueOf(0.12),BigDecimalUtils.getMantissa(positiveValue2));
  Assert.assertEquals(BigDecimal.valueOf(0.12),BigDecimalUtils.getMantissa(negativeValue));
 }
 
 
 @Test
 public void testIsInteger() {
  Assert.assertFalse(BigDecimalUtils.isInteger(positiveValue1));
  Assert.assertFalse(BigDecimalUtils.isInteger(negativeValue));
  Assert.assertTrue(BigDecimalUtils.isInteger(BigDecimal.ONE));
  Assert.assertFalse(BigDecimalUtils.isInteger(BigDecimal.ZERO));
  Assert.assertTrue(BigDecimalUtils.isInteger(BigDecimal.valueOf(12.00)));
 }
}


Here is a real life example of using BigDecimal for monetary calculation with design patterns.

Labels: ,

Jun 16, 2014

Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 5

Q. Can you write a custom list class that supports following features?

1. Allows you to maintain a parent/child hierarchy of sub lists.
2. Allows you to create sublists from a given list and a predicate (i.e a condition)
3. If you add an item or element to a list, the addition must be propagated to its parent and child lists.
4. If you remove an element from a list, the removal must be propagated to its parent and child lists.

In the previous parts

In this part, you will see the complete code with an iterator implementation added as a subclass. The iterator method uses the iterator design pattern.


package test;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class CustomList<E> implements List<E> {

 private CustomList<E> parent = null; // parent
 protected List<E> list = null; // initial list
 private List<CustomList<E>> sublists = new ArrayList<CustomList<E>>(); // children
 private Predicate<E> predicate; // used to create sublists based on the
         // predicate

 /**
  * DEFINE THE CONSTRUCTORS
  */

 public CustomList(List<E> sourceList) {
  this.list = sourceList;
 }

 // default constructor with an empty list
 public CustomList() {
  this(new ArrayList<E>()); // invokes the above constructor by supplying
         // an empty list
 }

 /**
  * access modifier is protected to only invoke from within the package and
  * subclasses from the other packages. This protected constructor creates
  * sub lists from the source or parent lists based on the supplied predicate
  * 
  * @param sourceList
  * @param predicate
  */
 protected CustomList(List<E> sourceList, Predicate<E> predicate) {
  if (predicate == null) {
   throw new IllegalArgumentException("Expected to receive a non-null predicate on which to base the sublist!");
  }

  this.predicate = predicate;

  // Each CustomList decorates a concrete List...
  this.list = new ArrayList<E>(sourceList.size());

  // Evaluate each item in the source to create the sublist
  // not using for each loop as we have not defined the iterator method
  // currently iterator() is throwing UnSupportedOperationException
  //you can change to for each once the iterator is defined.
  for (int i = 0; i < sourceList.size(); i++) {
   E item = sourceList.get(i);
   if (predicate.evaluate(item)) {
    this.list.add(item);
   }
  }

 }

 /**
  * access modifier is protected to only invoke from within the package and
  * subclasses from the other packages
  * 
  * @param sourceList
  * @param predicate
  */
 protected CustomList(CustomList<E> parent, Predicate<E> predicate) {
  this((List<E>) parent, predicate); // creates the sublist
  this.parent = parent;
  // Add ourselves (i.e. the new sublist created by this predicate)
  // to the parent subList
  parent.sublists.add(this);
 }

 /**
  * CREATING SUB LISTS
  */

 public CustomList<E> subList(Predicate<E> subListPredicate) {
  return new CustomList<E>(this, subListPredicate);
 }

 /**
  * Methods that need to be implemented for the List<E> interface to satisfy
  * the List interface contract
  */

 @Override
 public int size() {
  return this.list.size();
 }

 @Override
 public boolean isEmpty() {
  return this.list.isEmpty();
 }

 @Override
 public boolean contains(Object o) {
  return this.list.contains(o);
 }

 @Override
 public Iterator<E> iterator() {
  return new CustomListIterator(this.list.iterator());
 }

 @Override
 public Object[] toArray() {
  return this.list.toArray();
 }

 @Override
 public <T> T[] toArray(T[] a) {
  return this.list.toArray(a);
 }

 @Override
 public boolean add(E e) {
  return add(e, null);
 }

 @SuppressWarnings("unchecked")
 @Override
 public boolean remove(Object o) {
  return remove((E)o, null);
 }

 @Override
 public boolean containsAll(Collection<?> c) {
  return this.list.containsAll(c);
 }

 @Override
 public boolean addAll(Collection<? extends E> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean addAll(int index, Collection<? extends E> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean removeAll(Collection<?> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean retainAll(Collection<?> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public void clear() {
  // TODO Auto-generated method stub

 }

 @Override
 public E get(int index) {
  return this.list.get(index);
 }

 @Override
 public E set(int index, E element) {
  throw new UnsupportedOperationException();
 }

 @Override
 public void add(int index, E element) {
  throw new UnsupportedOperationException();
 }

 @Override
 public E remove(int index) {
   E item = this.list.get(index);
      return (item != null && remove(item)) ? item : null;
 }

 @Override
 public int indexOf(Object o) {
  return this.list.indexOf(o);
 }

 @Override
 public int lastIndexOf(Object o) {
  return this.list.lastIndexOf(o);
 }

 @Override
 public ListIterator<E> listIterator() {
  throw new UnsupportedOperationException();
 }

 @Override
 public ListIterator<E> listIterator(int index) {
  throw new UnsupportedOperationException();
 }

 @Override
 public List<E> subList(int fromIndex, int toIndex) {
  throw new UnsupportedOperationException();
 }

 /**
  * add to the parent and children if the predicate is satisfied Recursion is
  * used to add if the condition (i.e. predicate) is met
  */

 protected boolean add(E e, CustomList<E> givenList) {

  // check if the predicate (i.e. condition is met)
  if (!evaluate(e)) {
   return false;
  }

  boolean hasAdded = true;

  // if parent exists, add to the parent
  if (parent != null && parent != givenList) {
   // Recursive method call. The parent takes care of siblings...
   hasAdded = parent.add(e, this);
  }

  // if addition fails, return false
  if (!hasAdded) {
   return false;
  }

  hasAdded = this.list.add(e);

  if (!hasAdded) {
   if (parent != null) {
    throw new IllegalStateException("Failed to add !!");
   } else {
    return false;
   }
  }

  // Add to the sublists
  for (CustomList<E> sublist : sublists) {
   if (sublist != givenList) {
    // recursive method call
    sublist.add(e, this);
   }
  }

  return true;
 }

 
 /**
  * remove from the parent and children if the predicate is satisfied
  */

 protected boolean remove(E e, CustomList<E> givenList) {

  // First evaluate whether or not the item is likely to be in this
  // list...
  if (!evaluate(e)) {
   return false;
  }

  boolean hasRemoved = true;

  // if parent exists, remove from the parent
  if (parent != null && parent != givenList) {
   // Recursive method call. The parent takes care of siblings...
   hasRemoved = parent.remove(e, this);
  }

  // if removal fails, return false
  if (!hasRemoved) {
   return false;
  }

  // Remove from this
  if (givenList != this) {
   hasRemoved = this.list.remove(e);
  }

  if (!hasRemoved) {
   if (parent != null) {
    throw new IllegalStateException("Failed to remove !!");
   } else {
    return false;
   }
  }

  // Remove from the sublists
  for (CustomList<E> sublist : sublists) {
   if (sublist != givenList) {
    sublist.remove(e, this);
   }
  }

  return true;
 }

 
 private boolean evaluate(E e) {
  return (this.predicate != null) ? this.predicate.evaluate(e) : true;
 }

 /**
  * advanced toString() method
  */
 @Override
 public String toString() {
  StringBuilder sb = new StringBuilder();

  Deque<CustomList<Integer>> allParents = getAllParents();

  while (!allParents.isEmpty()) {
   CustomList<Integer> parent = allParents.pop();
   sb.append("parent: " + parent.list.toString() + "\n");
  }

  sb.append("list: " + list.toString() + "\n");

  Deque<CustomList<Integer>> allChildren = getAllChildren();
  while (!allChildren.isEmpty()) {
   CustomList<Integer> child = allChildren.remove();
   sb.append("child: " + child.list.toString() + "\n");
  }
  return sb.toString();
 }

 @SuppressWarnings("unchecked")
 private Deque<CustomList<Integer>> getAllParents() {
  Deque<CustomList<Integer>> queue = new ArrayDeque<CustomList<Integer>>();
  CustomList<Integer> currentCs = (CustomList<Integer>) this;

  // push each parent to the stack
  while (currentCs != null && currentCs.parent != null) {
   queue.push(currentCs.parent);
   currentCs = currentCs.parent;
  }

  return queue;
 }

 @SuppressWarnings("unchecked")
 private Deque<CustomList<Integer>> getAllChildren() {
  Deque<CustomList<Integer>> queue = new ArrayDeque<CustomList<Integer>>(); // for
                     // processing
                     // iteratively
  Deque<CustomList<Integer>> queueResult = new ArrayDeque<CustomList<Integer>>(); // for
                      // holding
                      // the
                      // results

  if (this != null) {
   queue.push((CustomList<Integer>) this);
  }

  while (!queue.isEmpty()) {
   CustomList<Integer> cl = queue.pop();
   if (cl.sublists != null) {
    for (CustomList<Integer> child : cl.sublists) {
     queue.push(child);
     queueResult.add(child);
    }
   }

  }

  return queueResult;
 }

 protected class CustomListIterator implements Iterator<E> {

  private Iterator<E> delegate;
  private E current;

  public CustomListIterator(Iterator<E> delegate) {
   this.delegate = delegate;
  }

  @Override
  public boolean hasNext() {
   return this.delegate.hasNext();
  }

  @Override
  public E next() {
   this.current = this.delegate.next();
   return current;
  }

  @Override
  public void remove() {
   this.delegate.remove();
            //propagate the removal to parent and children
            CustomList.this.remove(current, CustomList.this);

  }

 }

}


The class with the main method to run.

package test;

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

public class CustomListTest {

 public static void main(String[] args) {
  /**
   * Arrays.asList returns a List wrapper around an array. This wrapper
   * has a fixed size and is directly backed by the array, and as such
   * calls to set will modify the array, and any other method that
   * modifies the list will throw an UnsupportedOperationException.
   * hence creating a new ArrayList(...) instance
   */
  List<Integer> initialList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  CustomList<Integer> customList = new CustomList<Integer>(initialList);
  System.out.println("customList: " + customList);

  Predicate<Integer> oddNumberPredicate = new OddNumberPredicate<Integer>();
  CustomList<Integer> oddNumbersSubList = customList.subList(oddNumberPredicate);
  System.out.println("oddNumbersSubList: " + oddNumbersSubList);

  Predicate<Integer> factorOf5Predicate = new FactorOf5Predicate<Integer>();
  CustomList<Integer> factorOf5SubList = customList.subList(factorOf5Predicate);
  System.out.println("factorOf5SubList: " + factorOf5SubList);

  Predicate<Integer> factorOf3Predicate = new FactorOf3Predicate<Integer>();
  CustomList<Integer> factorOf3SubList = oddNumbersSubList.subList(factorOf3Predicate);
  System.out.println("factorOf3SubList : " + factorOf3SubList);

  System.out.println("Demonstrate printing customList again");
  System.out.println("customList : " + customList);

  // add an item or element
  customList.add(11); // this should be added to customList and
       // oddNumbersSubList
  customList.add(15); // this should be added to all four lists.

  System.out.println("After adding 11 & 15: ");
  System.out.println("customList : " + customList);
  
  customList.remove(new Integer(15)); 
  
  System.out.println("After removing 15: ");
  System.out.println("customList : " + customList);

 }

}


The output is:

customList: list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]



oddNumbersSubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [1, 3, 5, 7, 9]



factorOf5SubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [5, 10]



factorOf3SubList : parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

parent: [1, 3, 5, 7, 9]

list: [3, 9]



Demonstrate printing customList again

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

child: [1, 3, 5, 7, 9]

child: [5, 10]

child: [3, 9]



After adding 11 & 15:

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15]

child: [1, 3, 5, 7, 9, 11, 15]

child: [5, 10, 15]

child: [3, 9, 15]



After removing 15:

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

child: [1, 3, 5, 7, 9, 11]

child: [5, 10]

child: [3, 9]

Labels:

Jun 7, 2014

Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 4

Q. Can you write a custom list class that supports following features?

1. Allows you to maintain a parent/child hierarchy of sub lists.
2. Allows you to create sublists from a given list and a predicate (i.e a condition)
3. If you add an item or element to a list, the addition must be propagated to its parent and child lists.
4. If you remove an element from a list, the removal must be propagated to its parent and child lists.

In the previous parts


In this part, you will be adding a remove(...) method to remove an item from the hierarchical list.

Step 1: Remove the UnsupportedOperationException with the following recursive method call. It can be done with iterative calls with a Deque as shown in part 2 for the toString( ) method.

//....removed methods

public class CustomList<E> implements List<E> {

    //...removed constructors & methos  

 
 @SuppressWarnings("unchecked")
 @Override
 //remove the given item
 public boolean remove(Object o) {
  return remove((E)o, null);
 }
 
 @Override
 //remove by index
 public E remove(int index) {
   E item = this.list.get(index);
      return (item != null && remove(item)) ? item : null;
 }
 
 /**
  * remove from the parent and children if the predicate is satisfied
  * protected method
  */

 protected boolean remove(E e, CustomList<E> givenList) {

  // First evaluate whether or not the item is likely to be in this
  // list...
  if (!evaluate(e)) {
   return false;
  }

  boolean hasRemoved = true;

  // if parent exists, remove from the parent
  if (parent != null && parent != givenList) {
   // Recursive method call. The parent takes care of siblings...
   hasRemoved = parent.remove(e, this);
  }

  // if removal fails, return false
  if (!hasRemoved) {
   return false;
  }

  // Remove from this
  if (givenList != this) {
   hasRemoved = this.list.remove(e);
  }

  if (!hasRemoved) {
   if (parent != null) {
    throw new IllegalStateException("Failed to remove !!");
   } else {
    return false;
   }
  }

  // Remove from the sublists
  for (CustomList<E> sublist : sublists) {
   if (sublist != givenList) {
       //recursive call
       sublist.remove(e, this);
   }
  }

  return true;
 }


 private boolean evaluate(E e) {
  return (this.predicate != null) ? this.predicate.evaluate(e) : true;
 }
 
 
 //...removed some methods 

}

Step 2: The CustomListTest class with the main method to run.




package test;

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

public class CustomListTest {

 public static void main(String[] args) {
  /**
   * Arrays.asList returns a List wrapper around an array. This wrapper
   * has a fixed size and is directly backed by the array, and as such
   * calls to set will modify the array, and any other method that
   * modifies the list will throw an UnsupportedOperationException.
   * hence creating a new ArrayList(...) instance
   */
  List<Integer> initialList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  CustomList<Integer> customList = new CustomList<Integer>(initialList);
  System.out.println("customList: " + customList);

  Predicate<Integer> oddNumberPredicate = new OddNumberPredicate<Integer>();
  CustomList<Integer> oddNumbersSubList = customList.subList(oddNumberPredicate);
  System.out.println("oddNumbersSubList: " + oddNumbersSubList);

  Predicate<Integer> factorOf5Predicate = new FactorOf5Predicate<Integer>();
  CustomList<Integer> factorOf5SubList = customList.subList(factorOf5Predicate);
  System.out.println("factorOf5SubList: " + factorOf5SubList);

  Predicate<Integer> factorOf3Predicate = new FactorOf3Predicate<Integer>();
  CustomList<Integer> factorOf3SubList = oddNumbersSubList.subList(factorOf3Predicate);
  System.out.println("factorOf3SubList : " + factorOf3SubList);

  System.out.println("Demonstrate printing customList again");
  System.out.println("customList : " + customList);

  // add an item or element
  customList.add(11); // this should be added to customList and
       // oddNumbersSubList
  customList.add(15); // this should be added to all four lists.

  System.out.println("After adding 11 & 15: ");
  System.out.println("customList : " + customList);
  
  customList.remove(new Integer(15)); 
  
  System.out.println("After removing 15: ");
  System.out.println("customList : " + customList);

 }

}

The output is:

customList: list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]



oddNumbersSubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [1, 3, 5, 7, 9]



factorOf5SubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [5, 10]



factorOf3SubList : parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

parent: [1, 3, 5, 7, 9]

list: [3, 9]



Demonstrate printing customList again

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

child: [1, 3, 5, 7, 9]

child: [5, 10]

child: [3, 9]



After adding 11 & 15:

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15]

child: [1, 3, 5, 7, 9, 11, 15]

child: [5, 10, 15]

child: [3, 9, 15]



After removing 15:

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

child: [1, 3, 5, 7, 9, 11]

child: [5, 10]

child: [3, 9]





Q. What is a composite design pattern?
A. Composite pattern allows creation of a tree structure in which individual nodes are accessed uniformly whether they are leaf nodes or branch (composite) nodes.

Labels:

May 28, 2014

Top 17 Java Coding Tips for job interviews and pre-interview coding tests

Tip #1: If you are asked to write a function or code, make sure that your code fails fast. Check for pre-conditions and post conditions. For, example, if you are writing a function to "apply given interest rate to given balance"

Pre-condition: Balance is a positive number and greater than zero. Interest rate is not a percentage and can't be > 1.
Post-condition: new balance is a positive number by applying the interest rate.

 
public BigDecimal updateBalance(BigDecimal balance, BigDecimal rate) {
//pre-condition check if(balance == null || rate == null) { throw new IllegalArgumentException("balance or interestRate cannot be null"); } if(!isGretaerThanZero(balance)) { throw new IllegalArgumentException("balance must be a +ve number > zero "); } if(isInputPercentage(rate) || !isGretaerThanZero(rate)){ throw new IllegalArgumentException("rate is not valid"); } BigDecimal newBalance = balance.multiply(BigDecimal.ONE.add(rate)); //postcondition checks -- wrong calculation if(!isGretaerThanZero(balance)) { throw new CalculationException("balance must be a +ve number > zero."); } if(newBalance.compareTo(balance) <= 0){ throw new CalculationException("new balance cannot be less or same as old balance "); } return newBalance;  
}
 
boolean isGretaerThanZero(BigDecimal input){
  return input.compareTo(BigDecimal.ZERO) > 0 ;
}
 
 
boolean isInputPercentage(BigDecimal input){
  return input.compareTo(BigDecimal.ONE) > 0 ;
}


Tip #2: Don't write big functions, and divide them into smaller meaningful functions as shown above with isGreaterThanZero, isInputPercentage, etc.  Favor meaningful function names as opposed to cluttering your code with comments. The function names must be self explanatory as to what you are doing.


Tip #3: Write JUnit tests to test your function or code. Test for both the positive and negative scenarios. You need junit-xxx.jar for the example below.

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

public class BalanceCalcTest {
  
 BalanceCalc calc;

 @Before
 public void init() {
  calc = new BalanceCalc();
 }
 
 @Test
 public void testUpdateBalance() {
  BigDecimal updatedBalance = 
    calc.updateBalance(new BigDecimal("100.00"), (new BigDecimal("0.10")));
  Assert.assertTrue(new BigDecimal("110.0").compareTo(updatedBalance) == 0);
 }
 
 
 @Test(expected = java.lang.IllegalArgumentException.class)
 public void negativeTestUpdateBalance() {
  BigDecimal updatedBalance = 
       calc.updateBalance(new BigDecimal("-100.00"), (new BigDecimal("0.10")));
  
 }
}


Tip #4If you are asked to write iterative version of function then you may be drilled  to write recursive version or vice-versa. When writing loops, don't use i or j as index variables. Use meaningful names. Also avoid nested loops where possible.

Reverse a given string input : iteration

public static String reverse(String input) {
        StringBuilder strBuilder = new StringBuilder();
        char[] strChars = input.toCharArray();

        for (int charIndex = strChars.length - 1; charIndex >= 0; charIndex--) {
            strBuilder.append(strChars[charIndex]);
        }

        return strBuilder.toString();
}

Reverse a given string input : recursion

public static String reverseRecursion(String input) {

        //exit condition. otherwise endless loop
        if (input.length() < 2) {
            return input;
       }

       return reverseRecursion(input.substring(1)) + input.charAt(0);

}

Note: You may be quizzed on tail recursion

Tip #5:  Familiarize yourself with order of complexity with the Big O notation to answer any follow up question like -- What is the order of complexity of the above function you wrote?


Tip #6: Code to interface. Initialize your collection with appropriate capacity. Don't return a null collection, instead return an empty collection like  Collections.<String>emptyList( );.

Don't do:

   HashMap<String, String> keyValues = new HashMap()<String, String>();
   ArrayList<String>  myList = new ArrayList<String>();

Do:


   Map<String, String> keyValues = new HashMap()<String, String>(20);
   List<String>  myList = new ArrayList<String>(100);

Tip #7: Favor composition over interface

Tip #8: Use generics where required. Recursion with Generics tutorial. Understanding generics with scenarios.

Tip #9: Reduce the accessibility, and make your objects immutable where appropriate. For example, a custom key class that is used to store objects in a map. How to make a Java class immutable tutorial.

Tip #10: Don't forget to override Object class's methods that are meant to be overridden like equals(...), hashCode( ), and toString( ).



Tip #11: When you have large if/else or switch statements, see if the Open/Closed design principle can be applied.

Tip #12: Don't assume that your objects and classes are going to be accessed by a single-thread. Safeguard your objects and classes against multi-threading. Java multi-threading questions and answers.

Tip #13: Use the right data types. For example, use either BigDecimal to represent monetary values in dollars and cents or long to represent them in their lowest units as just cents (400 cents for $4.0). Beware of max and minimum values for data types. If you want values larger than long, use BigInteger, which has no theoretical limit. The BigInteger class allocates as much memory as it needs to hold all the bits of data it is asked to hold

byte (-128 to 127) -->  short (2 bytes,  -32,768 to 32,767) --> char(2 bytes, 65,535) --> int (4 bytes, -2^31 to 2^31-1) --> long(8 bytes,  -2^63 to 2^63-1) --> float (4 bytes) --> double (8 bytes). boolean (true or false)

Also, never compare floating point variables to exact amount like

double amount = 12.05;
if(amount == 12.05) { //don't
    //...do something
}


Tip #14: Handle and propagate exceptions properly. Have a consistent usage of checked and unchecked exceptions.


Exception is swept under the carpet.

try {
   //do something
}
catch(Exception ex){
    //do nothing
}


CustomCheckedException is never reached as exceptions are polymorphic in nature. CustomCheckedException must be declared first above Exception.

try {
   //do something
}
catch(Exception ex){
    //do something
}

catch(CustomCheckedException ex){
    //do nothing
}


Tip #15: Write pseudo code for more difficult coding questions. At times drawing diagrams help you solve the solving problem.


Tip #16: Keep in mind some of the design principles like  SOLID design principles, Don't Repeat Yourself (DRY), and Keep It Simple ans Stupid (KISS). Also, think about the OO concepts -- A PIE.   Abstraction, Polymorphism, Inheritance, and Encapsulation. These principles and concepts are all about accomplishing

  • Low coupling: Coupling in software development is defined as the degree to which a module, class, or other construct, is tied directly to others. You can reduce coupling by defining intermediate components (e.g. a factory class or an IoC container like Spring) and interfaces between two pieces of a system. Favoring composition over inheritance can also reduce coupling. 
  • High cohesion: Cohesion is the extent to which two or more parts of a system are related and how they work together to create something more valuable than the individual parts. You don't want a single class to perform all the functions (or concerns) like being a domain object, data access object, validator, and a service class with business logic. To create a more cohesive system from the higher and lower level perspectives, you need to break out the various needs into separate classes.  


Tip #17: If you are coding in front of the interviewer, think out loud. It is not always possible to solve problems in an interview when you are nervous, but how you will go about solving a coding problem is equally important even if you don't solve it. So, let the interviewer know that you know how to approach a problem. Solve the problem first, and then find ways to optimize it in terms of performance and memory allocation.


Practice!, practice!!, practice!!!....Write  code!!, more code!!!, more code!!!!.  That is the only way. Any more tips or corrections folks?

Labels:

May 24, 2014

Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 3

Q. Can you write a custom list class that supports following features?

1. Allows you to maintain a parent/child hierachy of sub lists.
2. Allows you to create sublists from a given list and a predicate (i.e a condition)
3. If you add an item or element to a list, the addition must be propagated to its parent and child lists.
4. If you remove an element from a list, the removal must be propagated to its parent and child lists.

In the previous parts
In this part, you will be adding an add(...) method to add an item to the hierarchical list.


Step 1: Remove the UnsupportedOperationException with the following recursive method call. Recursion is used to add to the parent and children.

//....removed methods

public class CustomList<E> implements List<E> {

    //...removed constructors & methos  

 @Override
 public boolean add(E e) {
  return add(e, null);
 }
 
 protected boolean add(E e, CustomList<E> givenList) {

  // check if the predicate (i.e. condition) is met
  if (!evaluate(e)) {
   return false;
  }

  boolean hasAdded = true;

  // if parent exists, add to the parent
  if (parent != null && parent != givenList) {
   // Recursive method call. The parent takes care of siblings...
   hasAdded = parent.add(e, this);
  }

  // if addition fails, return false
  if (!hasAdded) {
   return false;
  }

  //add it to the actual list
  hasAdded = this.list.add(e);

  if (!hasAdded) {
   if (parent != null) {
    throw new IllegalStateException("Failed to add !!");
   } else {
    return false;
   }
  }

  // Add to the sublists
  for (CustomList<E> sublist : sublists) {
   if (sublist != givenList) {
    // recursive method call
    sublist.add(e, this);
   }
  }

  return true;
 }

 private boolean evaluate(E e) {
  return (this.predicate != null) ? this.predicate.evaluate(e) : true;
 }
 
 
 //...removed some methods 
}





Step 2: The CustomListTest that adds items to the CustomList. Note that the initial list creation was slightly modified to make "initialList" mutable, so that new items can be added.

package test;

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

public class CustomListTest {

 public static void main(String[] args) {
  /**
   * Arrays.asList returns a List wrapper around an array. This wrapper
   * has a fixed size and is directly backed by the array, and as such
   * calls to set will modify the array, and any other method that
   * modifies the list will throw an UnsupportedOperationException.
   * hence creating a new ArrayList(...) instance
   */
  List<Integer> initialList = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

  CustomList<Integer> customList = new CustomList<Integer>(initialList);
  System.out.println("customList: " + customList);

  Predicate<Integer> oddNumberPredicate = new OddNumberPredicate<Integer>();
  CustomList<Integer> oddNumbersSubList = customList.subList(oddNumberPredicate);
  System.out.println("oddNumbersSubList: " + oddNumbersSubList);

  Predicate<Integer> factorOf5Predicate = new FactorOf5Predicate<Integer>();
  CustomList<Integer> factorOf5SubList = customList.subList(factorOf5Predicate);
  System.out.println("factorOf5SubList: " + factorOf5SubList);

  Predicate<Integer> factorOf3Predicate = new FactorOf3Predicate<Integer>();
  CustomList<Integer> factorOf3SubList = oddNumbersSubList.subList(factorOf3Predicate);
  System.out.println("factorOf3SubList : " + factorOf3SubList);

  System.out.println("Demonstrate printing customList again");
  System.out.println("customList : " + customList);

  // add an item or element
  customList.add(11); // this should be added to customList and
       // oddNumbersSubList
  customList.add(15); // this should be added to all four lists.

  System.out.println("After adding 11 & 15: ");
  System.out.println("customList : " + customList);
 }
}

The output is:

customList: list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

oddNumbersSubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list: [1, 3, 5, 7, 9]

factorOf5SubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list: [5, 10]

factorOf3SubList : parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
parent: [1, 3, 5, 7, 9]
list: [3, 9]

Demonstrate printing customList again
customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
child: [1, 3, 5, 7, 9]
child: [5, 10]
child: [3, 9]

After adding 11 & 15: 
customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15]
child: [1, 3, 5, 7, 9, 11, 15]
child: [5, 10, 15]
child: [3, 9, 15]

Labels:

May 23, 2014

Recursion Vs Tail Recursion Java example to reversing a given string

Reversing a given string input is a popular Java interview question. Let's look at reversing a String with recursion and tail recursion. If you want to better understand recursion with a diagram, read Java coding questions frequently asked in technical tests and job interviews -- iteration Vs recursion.

Input: Peter
Output: reteP

Recursion

public static String reverseRecursion(String input) {

        //exit condition. otherwise endless loop
        if (input.length() < 2) {
            return input;
        }

        return reverseRecursion(input.substring(1)) + input.charAt(0);
}

The processing happens as shown below

reverseRecursion("Peter")
reverseRecursion("eter") + 'P'
(reverseRecursion("ter") + 'e') + 'P'
((reverseRecursion("er") + t) + 'e') + 'P'
(((reverseRecursion("r") + e) + t) + 'e') + 'P'
((("r" + 'e') + 't') + 'e') + 'P'
(("re" + 't') + 'e' ) + 'P'
("ret" + 'e') + 'P'
"rete" + 'P'
"reteP"


Tail Recursion


public static String reverseTailRecursion(String input, String output ) {

        if (input.length() == 0) {
            return output;
        }

        return reverseTailRecursion(input.substring(1), input.charAt(0) + output);
}


The processing happens as shown below

reverseTailRecursion("Peter", "")
reverseTailRecursion("eter", "P")
reverseTailRecursion("ter", "eP")
reverseTailRecursion("er", "teP")
reverseTailRecursion("r", "eteP")
reverseTailRecursion("", "reteP")
"reteP"



Why use tail recursion?

In tail recursion the last call in the recursion is a call to the function and there is nothing left to do when the recursive call returns. This means in tail recursion the compilerdrop the growing stack, hence less likely to run out of stack space.

Labels:

May 20, 2014

Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 2

This is an extension to Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 1, which answers the following question.

Q. Can you write a custom list class that supports following features?

1. Allows you to maintain a parent/child hierarchy of sub lists.
2. Allows you to create sublists from a given list and a predicate (i.e a condition)
3. If you add an item or element to a list, the addition must be propagated to its parent and child lists.
4. If you remove an element from a list, the removal must be propagated to its parent and child lists.


This part extends the very simple toString( ) method to print the list hierarchy including both parent and child. It is not easy to work with hierarchical structures, and that is why interviewers love to ask these questions. Here, I am using an iterative approach as opposed to recursion. Search this blog for recursion, and see if you can solve this with recursion. Also, pay attention to Generics.

Here is the revised CustomList class only showing the toString( ) and its dependent private methods.



package test;

//... removed for brevity

public class CustomList<E> implements List<E> {

 private CustomList<E> parent = null; // parent
 protected List<E> list = null; // initial list
 private List<CustomList<E>> sublists = new ArrayList<CustomList<E>>(); // children
 private Predicate<E> predicate; // used to create sublists based on the
         // predicate

 
 //.... removed for brevity
 
 
 /**
  * advanced toString() method
  */
 @Override
 public String toString() {
  StringBuilder sb = new StringBuilder();

  Deque<CustomList<Integer>> allParents = getAllParents();

  while (!allParents.isEmpty()) {
   CustomList<Integer> parent = allParents.pop();
   sb.append("parent: " + parent.list.toString() + "\n");
  }

  sb.append("list: " + list.toString() + "\n");

  Deque<CustomList<Integer>> allChildren = getAllChildren();
  while (!allChildren.isEmpty()) {
   CustomList<Integer> child = allChildren.remove();
   sb.append("child: " + child.list.toString() + "\n");
  }
  return sb.toString();
 }

 @SuppressWarnings("unchecked")
 private Deque<CustomList<Integer>> getAllParents() {
  Deque<CustomList<Integer>> queue = new ArrayDeque<CustomList<Integer>>();
  CustomList<Integer> currentCs = (CustomList<Integer>) this;

  // push each parent to the stack
  while (currentCs != null && currentCs.parent != null) {
   queue.push(currentCs.parent);
   currentCs = currentCs.parent;
  }

  return queue;
 }

 @SuppressWarnings("unchecked")
 private Deque<CustomList<Integer>> getAllChildren() {
  Deque<CustomList<Integer>> queue = new ArrayDeque<CustomList<Integer>> ();    //for processing iteratively
  Deque<CustomList<Integer>> queueResult = new ArrayDeque<CustomList<Integer>> (); //for holding the results

  if (this != null) {
   queue.push((CustomList<Integer>) this);
  }

  while (!queue.isEmpty()) {
   CustomList<Integer> cl = queue.pop();
   if (cl.sublists != null) {
    for (CustomList<Integer> child: cl.sublists) {
     queue.push(child);
     queueResult.add(child);
    }
   }

  }

  return queueResult;
 }

}


Repeating the main test class from the  Creating a custom hierarchical List in Java -- Part 1.


package test;

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

public class CustomListTest {
 
 
 public static void main(String[] args) {
  List<Integer> initialList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
 
  CustomList<Integer> customList = new CustomList<Integer>(initialList);
  System.out.println("customList: " + customList);
  
  Predicate<Integer> oddNumberPredicate = new OddNumberPredicate<Integer>();
  CustomList<Integer> oddNumbersSubList = customList.subList(oddNumberPredicate);
  System.out.println("oddNumbersSubList: " + oddNumbersSubList);
  
  Predicate<Integer> factorOf5Predicate = new FactorOf5Predicate<Integer>();
  CustomList<Integer> factorOf5SubList = customList.subList(factorOf5Predicate);
  System.out.println("factorOf5SubList: " + factorOf5SubList);
  
  
  Predicate<Integer> factorOf3Predicate = new FactorOf3Predicate<Integer>();
  CustomList<Integer> factorOf3SubList = oddNumbersSubList.subList(factorOf3Predicate);
  System.out.println("factorOf3SubList : " + factorOf3SubList);
  
  
  System.out.println("Demonstrate printing customList again");
  System.out.println("customList : " + customList);
  
 }

}





Now the revised output will have parent child hierarchical information as shown below.

customList: list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]



oddNumbersSubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [1, 3, 5, 7, 9]



factorOf5SubList: parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list: [5, 10]



factorOf3SubList : parent: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

parent: [1, 3, 5, 7, 9]

list: [3, 9]



Demonstrate printing customList again

customList : list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

child: [1, 3, 5, 7, 9]

child: [5, 10]

child: [3, 9]

Labels: ,

May 3, 2014

Find the second highest number in an array

Core Java Coding Questions and Answers for beginner to intermediate level

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

Q. Can you find the second highest number in a given number?

For example: 

Input:  { 3, 5, 9, 7, 6, 8 };
Result: 8

A. A naive approach is to sort the array in descending order and then get the second element from the array. Sorting impacts performance, and  a better approach would be to

1) Have two variables to store highest & second highest numbers, and initialize them to minimum value.
2) Loop through each number in the array
3) If the "current number" > highest, make the current highest to second highest, and make the current value the highest.
4) else If the "current number < highest", but greater than the second highest then make "current number" the second highest.

public class SecondHighestNumber {

 public static void main(String[] args) {
  int[] numberArray = {3, 5, 9, 7, 6, 8};
        System.out.println(findSecondHighest(numberArray));
 }

 static int findSecondHighest(int[] numbers) {
  // initialize to the smallest value possible
  int highest = Integer.MIN_VALUE;
  int secondHighest = Integer.MIN_VALUE;

  for (int i = 0; i < numbers.length; i++) {

   //if highest number is found
   if (numbers[i] > highest) {
    secondHighest = highest; //make current highest to 2nd highest
    highest = numbers[i];    //make current value to highest
   } else if (numbers[i] > secondHighest)
    // replace the second highest
    secondHighest = numbers[i];
  }
  
  return secondHighest;
 }

}

Output:

8




Q. Is there anything wrong with the above code? What if you have duplicate numbers?

For example: int[] numberArray = {3, 5, 9, 7, 9, 8}; out put will be 9. If that is the expected behavior then it is fine. What if you want it to return 8 instead of 9?

A. Here is the slight revised solution that Ignores the equally highest numbers.

public class SecondHighestNumber {

 public static void main(String[] args) {
  int[] numberArray =  {3, 5, 9, 7, 9, 8};
        System.out.println(findSecondHighest(numberArray));
 }

 static int findSecondHighest(int[] numbers) {
  // initialize to the smallest value possible
  int highest = Integer.MIN_VALUE;
  int secondHighest = Integer.MIN_VALUE;

  for (int i = 0; i < numbers.length; i++) {
   
   //if highest or equally highest number is found
   //ignore the equally highest
   if (numbers[i] >= highest) {
    if(numbers[i] > highest) {
      secondHighest = highest; //make current highest to 2nd highest
      highest = numbers[i];    //make current value to highest
    }
   } else if (numbers[i] > secondHighest)
    // replace the second highest
    secondHighest = numbers[i];
  }
  
  return secondHighest;
 }

}

Output:

8

Labels: ,

May 1, 2014

Core Java Coding Questions: Creating a custom hierarchical List in Java -- Part 1

Core Java Coding Questions and Answers for beginner to intermediate level

Q1 Q2 Q3 Q4 Q5 Q6

Q. Can you write a custom list class that supports the following features?

1. Allows you to maintain a parent/child hierarchy of sub lists.
2. Allows you to create sublists from a given list and a predicate (i.e a condition)
3. If you add an item or element to a list, the addition must be propagated to its parent and child lists.
4. If you remove an element from a list, the removal must be propagated to its parent and child lists.
For example:

If you have a list of numbers say 1,2,3,4,5,6,7,8,9,10 in a list
  1. the customList.subList(oddNumberPredicate) should create a subList of 1,3,5,7,9 and the parent being the numbers 1 to 10.
  2. the customList.subList(factorOf5) should create a subList of 5,10 and the parent being the numbers 1 to 10.
  3. the oddNumberSubList.subList(factorOf3) should create a subList of 3,9 and the parent being 1,3,5,7,9 


A. To make it easier, I will build it up step by step. This post concentrates on getting the subList(...) function working and expand on this to build the add(...) and remove(...) functions.

Step 1: Define the interface for the predicates. Refer to filtering a list with a predicate to get some background.


package test;

public interface Predicate<E> {
 boolean evaluate(E object);
}

Step 2: Define different implementations of the predicate

OddNumberPredicate:


package test;

public class OddNumberPredicate<E> implements Predicate<Integer> {

 @Override
 public boolean evaluate(Integer number) {
  return (number != null && number % 2 > 0) ? true : false;
 }

}

FactorOf5Predicate:


package test;

public class FactorOf5Predicate<E> implements Predicate<Integer> {

 @Override
 public boolean evaluate(Integer number) {
  return (number != null && number % 5 == 0) ? true : false;
 }
}

FactorOf3Predicate:

package test;

public class FactorOf3Predicate<E> implements Predicate<Integer> {

 @Override
 public boolean evaluate(Integer number) {
  return (number != null && number % 3 == 0) ? true : false;
 }
}





Step 3: Create the CustomList class with proper generics (i.e. E to denote Elements). The class implements the interface List from the Java Collection, hence the CustomList class needs to implement the relevant methods. If you don't want to support a particular method, throw an exception named UnsupportedOperationException. The following code only shows the class to get subList method going with the relevant constructors. Refer to the comments in the code for further explanation. Also pay attention to things like

  1. Declaring the variables as private so that cannot be accessed from outside the class.
  2. Declaring the constructors as protected to be used within the same package or sub classes of other packages
  3. Declaring the Generics so that the CustomList can support different data types like Number, String, User, Person, Employee, etc.
  4. Throwing UnsupportedOperationException from the addAll(int index, Collection c), addAll(Collection c), etc. We will these methods later on as we see fit
  5. In an entry to a public method that takes parameters, perform pre condition check and fail fast by throwing exceptions early.
  6. toString(  method is added to print the items when the CustomList class is referenced in a System.out.println(...);


package test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class CustomList<E> implements List<E> {

 private CustomList<E> parent = null; //parent
 protected List<E> list = null; //initial list
 private List<CustomList<E>> sublists = new ArrayList<CustomList<E>>(); //children
 private Predicate<E> predicate; //used to create sublists based on the
               //predicate

 /**
  * DEFINE THE CONSTRUCTORS
  */

 public CustomList(List<E> sourceList) {
  this.list = sourceList;
 }

 // default constructor with an empty list
 public CustomList() {
  this(new ArrayList<E>()); // invokes the above constructor by supplying
                // an empty list
 }

 /**
  * access modifier is protected to only invoke from within the package and
  * subclasses from the other packages. This protected constructor creates
  * sub lists from the source or parent lists based on the supplied predicate
  * 
  * @param sourceList
  * @param predicate
  */
 protected CustomList(List<E> sourceList, Predicate<E> predicate) {
  if (predicate == null) {
   throw new IllegalArgumentException("Expected to receive a non-null predicate on which to base the sublist!");
  }

  this.predicate = predicate;

  // Each CustomList decorates a concrete List...
  this.list = new ArrayList<E>(sourceList.size());

  // Evaluate each item in the source to create the sublist
  // not using for each loop as we have not defined the iterator method
  // currently iterator() is throwing UnSupportedOperationException
  for (int i = 0; i < sourceList.size(); i++) {
   E item = sourceList.get(i);
   if (predicate.evaluate(item)) {
    this.list.add(item);
   }
  }

 }

 /**
  * access modifier is protected to only invoke from within the package and
  * subclasses from the other packages
  * 
  * @param sourceList
  * @param predicate
  */
 protected CustomList(CustomList<E> parent, Predicate<E> predicate) {
  this((List<E>) parent, predicate); // creates the sublist
  this.parent = parent;
  // Add ourselves (i.e. the new sublist created by this predicate)
  // to the parent subList
  parent.sublists.add(this);
 }

 /**
  * CREATING SUB LISTS
  */

 public CustomList<E> subList(Predicate<E> subListPredicate) {
  return new CustomList<E>(this, subListPredicate);
 }

 /**
  * Methods that need to be implemented for the List<E> interface to satisfy
  * the List interface contract
  */

 @Override
 public int size() {
  return this.list.size();
 }

 @Override
 public boolean isEmpty() {
  return this.list.isEmpty();
 }

 @Override
 public boolean contains(Object o) {
  return this.list.contains(o);
 }

 @Override
 public Iterator<E> iterator() {
  throw new UnsupportedOperationException();
 }

 @Override
 public Object[] toArray() {
  return this.list.toArray();
 }

 @Override
 public <T> T[] toArray(T[] a) {
  return this.list.toArray(a);
 }

 @Override
 public boolean add(E e) {
  throw new UnsupportedOperationException();
 }

 @SuppressWarnings("unchecked")
 @Override
 public boolean remove(Object o) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean containsAll(Collection<?> c) {
  return this.list.containsAll(c);
 }

 @Override
 public boolean addAll(Collection<? extends E> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean addAll(int index, Collection<? extends E> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean removeAll(Collection<?> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public boolean retainAll(Collection<?> c) {
  throw new UnsupportedOperationException();
 }

 @Override
 public void clear() {
  // TODO Auto-generated method stub

 }

 @Override
 public E get(int index) {
  return this.list.get(index);
 }

 @Override
 public E set(int index, E element) {
  throw new UnsupportedOperationException();
 }

 @Override
 public void add(int index, E element) {
  throw new UnsupportedOperationException();
 }

 @Override
 public E remove(int index) {
  throw new UnsupportedOperationException();
 }

 @Override
 public int indexOf(Object o) {
  return this.list.indexOf(o);
 }

 @Override
 public int lastIndexOf(Object o) {
  return this.list.lastIndexOf(o);
 }

 @Override
 public ListIterator<E> listIterator() {
  throw new UnsupportedOperationException();
 }

 @Override
 public ListIterator<E> listIterator(int index) {
  throw new UnsupportedOperationException();
 }

 @Override
 public List<E> subList(int fromIndex, int toIndex) {
  throw new UnsupportedOperationException();
 }

 /**
  * very basic toString() method
  */
 @Override
 public String toString() {
  return list.toString();
 }

}






Step 4: Finally, the test class with the main method to demonstrate how to use the CustomList and invoke subList method to create derived sub list classes.

package test;

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

public class CustomListTest {
 
 
 public static void main(String[] args) {
  List<Integer> initialList = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
 
  CustomList<Integer> customList = new CustomList<Integer>(initialList);
  System.out.println("customList: " + customList);
  
  Predicate<Integer> oddNumberPredicate = new OddNumberPredicate<Integer>();
  CustomList<Integer> oddNumbersSubList = customList.subList(oddNumberPredicate);
  System.out.println("oddNumbersSubList: " + oddNumbersSubList);
  
  Predicate<Integer> factorOf5Predicate = new FactorOf5Predicate<Integer>();
  CustomList<Integer> factorOf5SubList = customList.subList(factorOf5Predicate);
  System.out.println("factorOf5SubList: " + factorOf5SubList);
  
  
  Predicate<Integer> factorOf3Predicate = new FactorOf3Predicate<Integer>();
  CustomList<Integer> factorOf3SubList = oddNumbersSubList.subList(factorOf3Predicate);
  System.out.println("factorOf3SubList : " + factorOf3SubList);
  
  
  System.out.println("Demonstrate printing customList again");
  System.out.println("customList : " + customList);
  
 }

}


The output of the above test run

customList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

oddNumbersSubList: [1, 3, 5, 7, 9]

factorOf5SubList: [5, 10]

factorOf3SubList : [3, 9]

Demonstrate printing customList again

customList : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Stay tuned, in the next part I will expand the toString( ) method to print the tree hierarchy iteratively, which can be a bit tricky for some to understand. Practice these Java coding questions by coding.




In part 2, flattening the hierarchy iteratively in the toString( ) method to output the tree details.

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

Jan 23, 2014

Java ExecutorService for multi-threading -- coding question and tutorial

Q. Can you code in Java for the following scenario?

Write a multi-threaded SumEngine, which takes  SumRequest with 2 operands (or input numbers to add) as shown below:

package com.mycompany.metrics;

import java.util.UUID;

public class SumRequest {
 
 private String id = UUID.randomUUID().toString();
 private int operand1;
 private int operand2;
 
 protected int getOperand1() {
  return operand1;
 }
 protected void setOperand1(int operand1) {
  this.operand1 = operand1;
 }
 protected int getOperand2() {
  return operand2;
 }
 protected void setOperand2(int operand2) {
  this.operand2 = operand2;
 }
 protected String getId() {
  return id;
 }
 
 @Override
 public String toString() {
  return "SumRequest [id=" + id + ", operand1=" + operand1 + ", operand2=" + operand2 + "]";
 } 
}

and returns a  SumResponse with a result.

package com.mycompany.metrics;

public class SumResponse {
 
 private String requestId;
 private int result;
 
 protected String getRequestId() {
  return requestId;
 }
 protected void setRequestId(String requestId) {
  this.requestId = requestId;
 }
 protected int getResult() {
  return result;
 }
 protected void setResult(int result) {
  this.result = result;
 }
 
 @Override
 public String toString() {
  return "SumResponse [requestId=" + requestId + ", result=" + result + "]";
 }
}

A. Processing a request and returning a response is a very common programming task. Here is a basic sample code to get started.This interface can take any type of object as request and response.

package com.mycompany.metrics;

/**
 * R -- Generic request type, S -- Generic response type 
 */
public interface SumProcessor<R,S> {
 
    abstract S sum(R request);
}

Step 1: Define the interface that performs the sum operation. Take note that generics is used .

package com.mycompany.metrics;

/**
 * R -- Generic request type, S -- Generic response type 
 */
public interface SumProcessor<R,S> {
 
    abstract S sum(R request);
}

Step 2: Define the implementation for the above interface. Takes SumRequest and returns SumResponse. 

package com.mycompany.metrics;

public class SumProcessorImpl<R,S> implements SumProcessor<SumRequest, SumResponse> {

 @Override
 public SumResponse sum(SumRequest request) {
  System.out.println(Thread.currentThread().getName() + " processing request .... " + request);
  SumResponse resp= new SumResponse();
  resp.setRequestId(request.getId());
  resp.setResult(request.getOperand1() + request.getOperand2());
  return resp;
 }
}

Step 3: Write the multi-threaded  SumEngine. The entry point is the public method execute(SumRequest... request ) that takes 1 or more SumRequest as input via varargs. ExecutorService is the thread pool and closure of Callable interface is the executable task that can be submitted to the pool to be executed by the available thread.


package com.mycompany.metrics;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

public class SumEngine {

private final AtomicInteger requestsCount = new AtomicInteger();

 ExecutorService executionService = null;

 //executes requests to sum
 public void execute(SumRequest... request) {
  executionService = Executors.newFixedThreadPool(5); //create a thread pool
  List<Callable<SumResponse>> tasks = createExecuteTasks(request);
  List<Future<SumResponse>> results = execute(tasks);
  for (Future<SumResponse> result : results) {

   try {
    System.out.println(Thread.currentThread().getName() + ": Response = " + result.get());
   } catch (InterruptedException e) {
    e.printStackTrace();
   } catch (ExecutionException e) {
    e.printStackTrace();
   }
  }
                 
   //initiates an orderly shutdown of thread pool
   executionService.shutdown();
 }

 //create tasks
 private List<Callable<SumResponse>> createExecuteTasks(SumRequest[] requests) {
  List<Callable<SumResponse>> tasks = new LinkedList<Callable<SumResponse>>();
  executingRequests(requests.length);
  for (SumRequest req : requests) {
   Callable<SumResponse> task = createTask(req);
   tasks.add(task);
  }

  return tasks;
 }

 //increment the requests counter
 private void executingRequests(int count) {
  requestsCount.addAndGet(count);
 }

 //creates callable (i.e executable or runnable tasks) 
 private Callable<SumResponse> createTask(final SumRequest request) {
  // anonymous implementation of Callable.
  // Pre Java 8's way of creating closures
  Callable<SumResponse> task = new Callable<SumResponse>() {

   @Override
   public SumResponse call() throws Exception {
    System.out.println(Thread.currentThread().getName() + ": Request = " + request);
    SumProcessor<SumRequest, SumResponse> processor = new SumProcessorImpl<>();
    SumResponse result = processor.sum(request);
    return result;
   }

  };

  return task;
 }

 //executes the tasks
 private <T> List<Future<T>> execute(List<Callable<T>> tasks) {

  List<Future<T>> result = null;
  try {
   //invokes the sum(sumRequest) method by executing the closure call() inside createTask
   result = executionService.invokeAll(tasks);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }

  return result;

 }
 
 public int getRequestsCount(){
  return requestsCount.get();
 }
}

Step 4: Write the SumEngineTest to run the engine with the main method. Loops through numbers 1 to 5 and adds each consecutive numbers like 1+2=3, 2+3=5, 3+4=7, 4+5=9, and 5+6 = 11.

package com.mycompany.metrics;

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

public class SumEngineTest {

 public static void main(String[] args) throws Exception {

  SumEngine se = new SumEngine();
  
  List<SumRequest> list = new ArrayList<>();

  // sums 1+2, 2+3, 3+4, etc
  for (int i = 1; i <= 5; i++) {
   SumRequest req = new SumRequest();
   req.setOperand1(i);
   req.setOperand2(i + 1);
   list.add(req);
  }

  SumRequest[] req = new SumRequest[list.size()];
  se.execute((SumRequest[]) list.toArray(req));

 }
}

The output is:

pool-1-thread-2: Request = SumRequest [id=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, operand1=2, operand2=3]
pool-1-thread-4: Request = SumRequest [id=36d95b35-09f0-4e93-99e4-715ea7cb33c9, operand1=4, operand2=5]
pool-1-thread-3: Request = SumRequest [id=31ccd137-349a-4b7a-93b1-e51f62c11ba9, operand1=3, operand2=4]
pool-1-thread-1: Request = SumRequest [id=4bfa782a-c695-4de6-9593-cbfd357c3535, operand1=1, operand2=2]
pool-1-thread-5: Request = SumRequest [id=c653f469-6a6f-45b6-99f2-ed58620fd144, operand1=5, operand2=6]
pool-1-thread-4 processing request .... SumRequest [id=36d95b35-09f0-4e93-99e4-715ea7cb33c9, operand1=4, operand2=5]
pool-1-thread-2 processing request .... SumRequest [id=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, operand1=2, operand2=3]
pool-1-thread-1 processing request .... SumRequest [id=4bfa782a-c695-4de6-9593-cbfd357c3535, operand1=1, operand2=2]
pool-1-thread-3 processing request .... SumRequest [id=31ccd137-349a-4b7a-93b1-e51f62c11ba9, operand1=3, operand2=4]
pool-1-thread-5 processing request .... SumRequest [id=c653f469-6a6f-45b6-99f2-ed58620fd144, operand1=5, operand2=6]
main: Response = SumResponse [requestId=4bfa782a-c695-4de6-9593-cbfd357c3535, result=3]
main: Response = SumResponse [requestId=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, result=5]
main: Response = SumResponse [requestId=31ccd137-349a-4b7a-93b1-e51f62c11ba9, result=7]
main: Response = SumResponse [requestId=36d95b35-09f0-4e93-99e4-715ea7cb33c9, result=9]
main: Response = SumResponse [requestId=c653f469-6a6f-45b6-99f2-ed58620fd144, result=11]

Labels: ,