Saturday, March 25, 2017

Generic - Getting Started

Generic classes can be a challenge to learn for the beginning programmer, so in this post I'll try to help you get started with the concept.

Start with a simple program like every language's favorite first project, "Hello World".

Now, think about the concept of displaying something simple from a class based on a parameter like:
Hello World
Hello 2017
Hello 2017.03
Hello W

As you can see we just need to do something simple and only one part of the output is modified from String to int, float, and finally char data types.  Thus, we would need to write 4 different classes for each data type.  But what if we could create a generic class that would adjust to data type based on the type we'll send to the constructor.  That is exactly why generics are so valuable in programming.

So, Let's get started with a simple object oriented implementation of Hello World.

public class Hello{
    private String message;
    public Hello(String message){
           super();
           this.message=message;
    }
    public String getMessage(){
           return message;
    }
}

public class HelloGeneric{
    public static void main(String[] args){
               Hello myMessage = new Hello("World");
               //imagine it this way, Hello myMessage = new Hello(new String("World"));
               System.out.println("Hello "+myMessage.getMessage());
    }

}

Now, that you have a simple class, you can see that by changing the data type for message will all we need to do in  order to create the same class for the other types.

Integer based class would become:
public class Hello{
     private int message;
     public Hello(int message){
           super();
           this.message=message;
     }
     public int getMessage(){
           return message;
     }
}

Floating point base class would become:

public class Hello{
       private float message;
       public Hello(float message){
           super();
           this.message=message;
      }
      public float getMessage(){
           return message;
      }
}

and Character based class would become:

public class Hello{
      private char message;
      public Hello(char message){
           super();
           this.message=message;
      }
      public char getMessage(){
           return message;
      }
 }

Therefore, we should use a Generic class instead to implement this application.  You just have to think about the primitives as objects, so you will be using their wrapper classes when instantiating.  For int, use Integer; for float use Float, and for char use Character.



/** Generic class 
public class Hello<T>{
     private T message;
    public Hello(T message){
           super();
           this.message=message;
    }
    public  T getMessage(){
           return message;
    }
}


The driver for the Generic class looks like this.  Notice the object instantiations when invoking the constructor with parameter.

public class HelloGeneric{
    public static void main(String[] args){

        System.out.println("Hello "+new Hello<String>("World").getMessage());
        System.out.println("Hello "+new Hello<Integer>(2017).getMessage());
        System.out.println("Hello "+new Hello<Float>(2017.03f).getMessage());
        System.out.println("Hello "+new Hello<Character>('W').getMessage());
    }
}


As you can see, we replaces the data type specific keywords with an element "T" representation instead.

By convention, type parameter names are single, uppercase letters. This stands in sharp contrast to the variable naming conventions that you already know about, and with good reason: Without this convention, it would be difficult to tell the difference between a type variable and an ordinary class or interface name.
    The most commonly used type parameter names are:
      *    E - Element (used extensively by the Java Collections Framework)
      *    N - Number
      *    T - Type ( As you can see, all occurrences of Object are replaced by T.
            A type variable can be any non-primitive type you specify: any class type,
            any interface type, any array type, or even another type variable. )
      *    V - Value
      *    S,U,V etc. - 2nd, 3rd, 4th types

Many developers use the terms "type parameter" and "type argument" interchangeably, but these terms are not the same. When coding, one provides type arguments in order to create a parameterized type. Therefore, the T in Foo<T> is a type parameter and the String in Foo<String> f is a type argument.

So, play with the above code until you can create it without looking at my code and you understand this simple, but powerful concept.

Now, here is another simple, but more involved example to help you with your journey of learning. et's start with the UML of the example so you can see the basic design concepts.

So, this way, you can see an example that uses generic methods, interface, inheritance, and instantiation of these classes.  I hope, this will help.  Here is the source code.

/**
 * Generic version of Zoltan class.
 * @param <T> the type of value being boxed
 */

public class Zoltan<T> {

    private T value; // T stands for "Type"         
 /**
  * Zoltan class's setter method
  * @param value Is the data type that was invoked when the object was instantiated
  */

    public void set(T value) {
        this.value = value;
    }
 /**
  * Zoltan class's getter method
  * @return Data type is the same that was used when the object was instantiated.
  */

    public T get() {
        return this.value;
    }
}


public class Inherited<K,V> extends OrderedPair<K,V>{
    // instance variables - replace the example below with your own
    private int myValue;
    /**
     * Constructor for objects of class Inherited
     */

    public Inherited(K key,V value){
        super(key,value);
        // initialise instance variables
        myValue = 0;
    }
    public int getMyValue(){
        return myValue;
    }
}


public class OrderedPair<K, V> implements Pair<K, V> {
    protected K key;
    protected V value;
    public OrderedPair(K key, V value) {
    this.key = key;
    this.value = value;
    }
    public K getKey()    { return key; }
    public V getValue() { return value; }
}


 public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}


public class ZoltanDemo {
    public static <U> void addZoltan(U u, java.util.List<Zoltan<U>> boxes) {

        Zoltan<U> box = new Zoltan<>();  //this is allowed now
        box.set(u);
        boxes.add(box);
  }
       public static <U> void outputZoltans(java.util.List<Zoltan<U>> boxes) {
       int counter = 0;
       for (Zoltan<U> box: boxes) {
             U boxContents = box.get();
       System.out.println("Zoltan #" + counter + " contains [" + boxContents.toString() + "]");
       counter++;
    }
  }
      public static void main(String[] args) {
              java.util.ArrayList<Zoltan<Integer>> listOfIntegerZoltans = new java.util.ArrayList<>();
              ZoltanDemo.<Integer>addZoltan(Integer.valueOf(10), listOfIntegerZoltans);
             ZoltanDemo.addZoltan(Integer.valueOf(20), listOfIntegerZoltans);
            ZoltanDemo.addZoltan(Integer.valueOf(30), listOfIntegerZoltans);
            ZoltanDemo.outputZoltans(listOfIntegerZoltans);
            OrderedPair<String,Zoltan<Integer>> p=new OrderedPair<>("primes",new Zoltan<Integer>());
           p.getValue().set(2017);
           System.out.println(p.getKey()+" and "+p.getValue().get());
           Inherited testInherit=new Inherited<String,Integer>("Zoltan",2017);
           System.out.println(testInherit.getKey()+" and "+testInherit.getValue());
  }
}



Friday, March 24, 2017

Start Performance Testing - Array vs. ArrayList

What is you observation after running this code?  Post your results including Operating System, Hardware info, and Java version that you've used.


public class Array_PerformanceTest{
    public static void main(String args[])throws java.io.FileNotFoundException,InterruptedException{
        final int arraySize=Integer.parseInt(args[0]);
        int testArray[]=new int[arraySize];
        System.out.printf("All arrays use size: %,d",arraySize);
        System.out.println("                                hr: m: s:  ms");
        long time=System.currentTimeMillis();
        for(int index=0;index<arraySize;index++)
             testArray[index]=index;
        System.out.printf("Initializing array time: %20s\n",(getTime(System.currentTimeMillis()-time)));    
        time=System.currentTimeMillis();
        int result=sequentialSearch(testArray,arraySize-1);
        System.out.printf(" Sequential search time: %20s\n",(getTime(System.currentTimeMillis()-time)));
       

        time=System.currentTimeMillis();
        binarySearch(testArray,arraySize-1);
        System.out.printf("     Binary search time: %20s\n",(getTime(System.currentTimeMillis()-time)));
       
        java.util.Random rand=new java.util.Random();
       
        for(int index=0;index<arraySize;index++)
             testArray[index]=rand.nextInt(arraySize);
       
        time=System.currentTimeMillis();
        selectionSort(testArray);
        System.out.printf("    Selection sort time: %20s\n",(getTime(System.currentTimeMillis()-time)));
       
        java.util.ArrayList<String> list = new java.util.ArrayList<String>(arraySize);
        time=System.currentTimeMillis();
        for(int index=0;index<arraySize;index++)
               list.add(0, "Mary"+rand.nextInt(arraySize));
        System.out.printf("    Arraylist fill time: %20s\n",(getTime(System.currentTimeMillis()-time)));
       
        System.out.println();   

    }

    private static int sequentialSearch(int[] array, int value){
        int index,element;
        boolean found;  // Flag indicating search results
        index = 0;
        element = -1;
        found = false;
        while (!found && index < array.length) {
            if (array[index] == value) {
                found = true;     // Indicate the value is found.
                element = index;  // Save the subscript of the value.
            }
            index++;
        }
        return element;
    }

    private static void selectionSort(int[] array){
        int startScan, index, minIndex, minValue;
        for (startScan = 0; startScan < (array.length-1); startScan++) {
            minIndex = startScan;
            minValue = array[startScan];
            for(index = startScan + 1; index < array.length; index++) {
                if (array[index] < minValue) {
                    minValue = array[index];
                    minIndex = index;
                }
            }
            array[minIndex] = array[startScan];
            array[startScan] = minValue;
        }
    }

    private static int binarySearch(int[] array, int value){
        int first,last,middle,position;
        boolean found;   // Flag
        first = 0;
        last = array.length - 1;
        position = -1;
        found = false;

        while (!found && first <= last) {
            middle = (first + last) / 2;    // Calculate mid point
            if (array[middle] == value) {
                found = true;
                position = middle;
            }
            else if (array[middle] > value) // If value is in lower half
                last = middle - 1;
            else
                first = middle + 1;          // If value is in upper half
        }
        return position;
    }
   
    private static String getTime(long millis){
            long second = (millis / 1000) % 60;
            long minute = (millis / (1000 * 60)) % 60;
            long hour = (millis / (1000 * 60 * 60)) % 24;
            return String.format("%02d:%02d:%02d:%04d", hour, minute, second, millis);
    }
}