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);
    }
}

Friday, December 9, 2016

Internal resources in Eclipse

Files can be opened from storage devices, but they need a specific path and drive letter, sometimes.  If you are planning to create a runnable jar file created from your project, it is better to access the resources internally from an internal resource path and include them in the runnable jar file.

This simple example demonstrates the process.

1. Create two images with 600x400 dimensions and name them one.jpg and two.jpg.  Store them on your C drive's temp directory for now.
2. Follow the image below to create a new resource folder (1-8) in your project.
3. Import (9) the two image files into the newly created res resource folder.



import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


@SuppressWarnings("serial")
public class FirstGuiApp extends JPanel{
BufferedImage img;

//First try - load images from your hard drive
//String img1 = "c:\\temp\\one.jpg";
//String img2 = "c:\\temp\\two.jpg";

//Second try - load images from internal resource, comment out first step

/*Add project folder res ( add res path to project properties->Build Path->Source)
 * Then, import two jpg images 600x400 named one.jpg and two.jpg
 * */

String img1 = "one.jpg";
String img2 = "two.jpg";
boolean evenClick = false;

public FirstGuiApp(){
setSize(600,400);
setVisible(true);
loadImage(img1);

this.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent me){
if(evenClick){
    loadImage(img1);
    evenClick=false;
    }
else{
    loadImage(img2);
    evenClick=true;
    }
updateUI();
}

});
}//end of FirstGuiApp

private void loadImage(String str){
try{
       //img=ImageIO.read(FirstGuiApp.class.getResource(str)); //one way to load internal resoure
       img=ImageIO.read(getClass().getResource(str)); //preferred way of loading internal resource
       //img=ImageIO.read(new File(str)); //use this with first step to load image from hard drive
     }
catch(IOException e){   e.printStackTrace();  }
}//end of loadImage method

protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(img, 0, 0, 600, 400, this);

}//end of paintComponent

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
              public void run(){
                         JFrame frm = new JFrame();
                         frm.setSize(620,465);
                         frm.setVisible(true);
                         frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                         frm.add(new FirstGuiApp());
                         frm.setTitle("My GUI Application");
                         }//end of run
              }//end of runnable
          );
     }//end of main
}//end of class

Run the program.  The program window should show your image one.jpg and when you click on the image the image two.jpg is loaded alternating between the images. If it does not work, uncomment

//String img1 = "c:\\temp\\one.jpg";
//String img2 = "c:\\temp\\two.jpg";


and 

//img=ImageIO.read(new File(str)); //use this with first step to load image from hard drive

and comment out the following lines to load the images from your hard drive directly for trouble shooting.

String img1 = "one.jpg";
String img2 = "two.jpg";

img=ImageIO.read(getClass().getResource(str)); //preferred way of loading internal resource
 
After you have tested your application, you can then create the runnable jar file.


Speed Test Array Processing By - Column vs. Row

At small array elements, processing arrays by row vs. by column might not suggest any difference in speed, but as elements increase, the difference will show its face.

Most people see arrays like this:

... but arrays are stored as a linear structure of consecutive cells.  Arrays look like this in memory and visualizing them might help better understand their performance difference.

What values do the consistent difference show up?  Try it, test it, document it, share your results!!!



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

int[][] array2D=new int[Dim.R.val][Dim.C.val];
long milis = System.currentTimeMillis();
processByRow(array2D);
System.out.println("2D Array processed by row takes "+(System.currentTimeMillis() - milis)+" ms");

milis = System.currentTimeMillis();
processByColumn(array2D);
System.out.println("2D Array processed by column takes "+(System.currentTimeMillis() - milis)+" ms");

}

private static void processByRow(int[][] array2D){
    for(int row=0;row<Dim.R.val;row++){
        for(int column=0;column<Dim.C.val;column++){
            array2D[row][column]=5;
        }
    } 
}

private static void processByColumn(int[][] array2D){
    for(int column=0;column<Dim.C.val;column++){  
        for(int row=0;row<Dim.R.val;row++){
           array2D[row][column]=5;
        }
    }
}
private enum Dim{R(10),C(10);
        public final int val;
        Dim(int val){this.val=val;}
        public int getValue() { return val; }
}
}

Run msinfo32 on your system to gather basic info about your basic configuration.

OS Name    Microsoft Windows 8.1 Pro
System Type:x64-based PC
Processor:Intel(R) Core(TM) i7-4702HQ CPU @ 2.20GHz, 2201 Mhz, 4 Core(s), 8 Logical Processor(s)
Installed Physical Memory (RAM):16.0 GB
Total Physical Memory:15.9 GB
Available Physical Memory:6.78 GB
Total Virtual Memory:18.3 GB
Available Virtual Memory:8.72 GB
Page File Space:2.38 GB
10x10 Array Processed
2D Array processed by row takes 0 ms
2D Array processed by column takes 0 ms
100x100 Array Processed
2D Array processed by row takes 1 ms
2D Array processed by column takes 0 ms
1000x1000 Array Processed
2D Array processed by row takes 2 ms
2D Array processed by column takes 6 ms

1000x10000 Array Processed
2D Array processed by row takes 17 ms
2D Array processed by column takes 265 ms
10000x1000 Array Processed
2D Array processed by row takes 16 ms
2D Array processed by column takes 136 ms