Google

Nov 17, 2013

Java coding question on recursion and generics

Q. Can you write Java code to compute a collection of numbers supplied to it? The computation could be addition, subtraction, etc. Use recursion to compute the numbers. Here are some requirements to take into considerations.

1. It should be flexible enough to convert from Recursion to iteration if required.
2. Computation will initially be "addition", but should be extendable to multiplication, subtraction, etc.
3. Should handle integers and floating point numbers.
4. Make use of generics.

Here is a sample test class.


 
package recursiontoiteration;

import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class RecursionTest
{
    public static void main(String[] args)
    {
        Queue<Integer> q = new ArrayBlockingQueue<Integer>(5);
        q.add(5);
        q.add(10);
        q.add(12);
        
        Compute<Double, Integer> compute = new Recursion<Double, Integer>();
        Double result = compute.compute(null, q, new Multiply<Double, Integer>());
        System.out.println(result);
    }
}

A. Firstly, define the "Compute" interface and the "Recursion" implementation.

 
package recursiontoiteration;

import java.util.Queue;

public interface Compute<R, N>
{
    R compute(R r, Queue<N> q, Function<R, N> function);
}

R and N are generic types meaning say Result and Number respectively. In the above example, they will be  inferred at compile time as Double and Integer types respectively. Here is the Recursion implementation.

package recursiontoiteration;

import java.util.Queue;

public class Recursion<R, N> implements Compute<R, N>
{
    public R compute(R r, Queue<N> q, Function<R, N> function)
    {
        //recursion exit condition - no items in the queue to process
        if (q.size() == 0)
        {
            return r;
        }
        
        r = compute(function.apply(r, q.poll()), q, function);
        
        return r;
        
    }
}

Let's define the Function interface to represent mathematical operations like Sum, Multiply, Divide, etc.

package recursiontoiteration;

public interface Function<R, N>
{
    R apply(R r, N n);
}

The implementation Sum will be:

package recursiontoiteration;

import java.math.BigDecimal;

public class Sum<R, N> implements Function<R, N>
{
    
    //add two numbers
    @SuppressWarnings("unchecked")
    @Override
    public R apply(R r, N n)
    {
        Number result = Double.valueOf(0);
        Number number = Double.valueOf(0);
        if (r != null)
        {
            result = (Double) r;
        }
        
        if (n != null)
        {
            number = (Number) n;
        }
        
        //big decimal is better for rounding values
        BigDecimal addedValue = new BigDecimal(result.doubleValue()).add(new BigDecimal(number.doubleValue()));
        
        return (R) (Number) Double.valueOf(addedValue.toPlainString());
    }
}

Multiply will be implemented as shown below.

package recursiontoiteration;

import java.math.BigDecimal;

public class Multiply<R, N> implements Function<R, N>
{
    
    @SuppressWarnings("unchecked")
    @Override
    public R apply(R r, N n)
    {
        Number result = Double.valueOf(1);
        Number number = Double.valueOf(1);
        if (r != null)
        {
            result = (Double) r;
        }
        
        if (n != null)
        {
            number = (Number) n;
        }
        
        //big decimal is better for rounding values
        BigDecimal multipliedValue = new BigDecimal(result.doubleValue())
                .multiply(new BigDecimal(number.doubleValue()));
        
        return (R) (Number) Double.valueOf(multipliedValue.toPlainString());
    }
}

Even though it is a trivial example, many beginner to intermediate level developers struggle with --> recursion, generics, and writing extendable programs with proper interfaces.

In the next blog post, we will find how to convert recursion to iteration.

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home