Generics in Java


Generics are introduced in JDK 1.5 on-wards and one of the important and flexible feature in Java by enabling types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Its same as like other formal parameters by providing way of reusing code for different input types. Only the difference in inputs to formal parameters are values where as for inputs to type parameters are types.  
Generics in java

For developers to pass type or method to operate on objects of various types. Also it provides compile time type safety by making fully statically typed language. There are lot of advantage on Generics compared to non-Generic codes like,

  • Use of Multiple Bounds
  • Stronger type checks at compile time.
  • Elimination of casts.
  • Use of wildcards with extends or super to increase API flexibility
  • Enabling programmers to implement generic algorithms.

Now lets see few examples on using Generics in Java.


public class GenericsTest {

 public static void main(String[] args) {
  
  // Without Genric
  List list = new ArrayList();
  list.add("Hello Java Discover");
  // Here we need casting while we use non-generic code
  String val = (String) list.get(0);
  
  
  // With Genric
  List<String> list1 = new ArrayList<String>();
  list1.add("Hello Java Discover");
  // No need of casting while we use Generic
  String val1 = list1.get(0);  
 }
}


If we see in above we declared 2 List object without Generic type and 2nd with "String" type setting. When we get values from 1st List specifically we need to cast those values to corresponding type. But while we get values from 2nd list no need to casting to "String" as like 1st List. 


Next we write single method which will take multiple type inputs like integer, float, String etc.,


public class GenericsTest {

 public static void main(String args[]) {
  
  Integer[] iArray = new Integer[] { 10, 30, 50, 20, 60, 70 };
  System.out.print("Integer Array : ");
  genericMethod(iArray);
  
  Float[] fArray = new Float[]{ 4.41f, 5.23f, 2.23f, 99.41f };
  System.out.print("Float Array   : ");
  genericMethod(fArray);
  
  String[] sArray = new String[]{ "Hello", "Java", "Discover", "2013"};
  System.out.print("String Array  : ");
  genericMethod(sArray);  
 }

 public static <E> void genericMethod(E[] array) {
  for (E element : array) {
   System.out.print(element+", ");
  }
  System.out.println();
 }
}

OUTPUT:


Integer Array : 10, 30, 50, 20, 60, 70, 
Float Array   : 4.41, 5.23, 2.23, 99.41, 
String Array  : Hello, Java, Discover, 2013, 

In above program we have used genericMethod() function to print all 3 different types like integer, float and string. 

Next we will see about creating Generic class using Types.


public class MyGenericClass<T> {

 private T t;

 public MyGenericClass(T t) {
  this.t = t;
 }

 public T getValue() {
  return t;
 }
}


public class GenericsTest {

 public static void main(String args[]) {

  MyGenericClass<Integer> iValue = new MyGenericClass<Integer>(100);
  MyGenericClass<String> sValue = new MyGenericClass<String>("Hello Java Discover");
  MyGenericClass<Double> dValue = new MyGenericClass<Double>(434.23);

  System.out.println("Integer Value : " + iValue.getValue());
  System.out.println("String Value  : " + sValue.getValue());
  System.out.println("Double Value  : " + dValue.getValue());
 }
}

OUTPUT:


Integer Value : 100
String Value  : Hello Java Discover
Double Value  : 434.23

In above example we have created Generic class called "MyGenericClass" which will take different type constructor parameters. 


Iterator Design Pattern in Java

Iterator Design Pattern in Java

Iterator pattern is a behavioral object design pattern. Iterator pattern allows for the traversal through the elements in a grouping of objects via a standardized interface defines the actions or methods that can be performed. These actions or methods able to traverse the objects, remove or add Object according to project needs. So keeping in mind about the pattern just we need to apply on top of our business logic's. 

If we look at Java widely used Iterator interface which used to iterate through elements in various Java collections. We can write our own iterator by implementing java.util.Iterator. This interface features the hasNext(), next(), and remove() methods. Lets take simple example of book stall which contains list of books with these few following information's like,

Book Name
Author
Price

Based on above example lets create Book class which holds the book details


public class Book {

 private String name;
 private String author;
 private int price;
 
 public Book(String name, String author, int price) {
  this.name = name;
  this.author = author;
  this.price = price;
 }
 public String getName() {
  return name;
 }
 public String getAuthor() {
  return author;
 }
 public int getPrice() {
  return price;
 }

 @Override
 public String toString() {
  return "----------\n\nBook Name : "+name+" \nAuthor    : "+author+"\nPrice     : Rs."+price; 
 } 
}




Next lets create Store class which contains list of various books and list actions like add books, removing, listing etc., can be performed. 


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

public class Store {
 
 List<Book> bookList = new ArrayList<Book>();
 
 public void addBook(Book item) {
  bookList.add(item);
 }

 public Iterator<Book> iterator() {
  return new BooksIterator();
 }

 class BooksIterator implements Iterator<Book> {
  int bookId = 0;

  @Override
  public boolean hasNext() {
   if (bookId >= bookList.size()) {
    return false;
   } else {
    return true;
   }
  }

  @Override
  public Book next() {
   return bookList.get(bookId++);
  }

  @Override
  public void remove() {
   bookList.remove(--bookId);
  }
 } 
}


Next lets implement the main class which feeds list of books into Store and iterates. For sample lets add 4 books and will test.


import java.util.Iterator;

public class BookStore {
 
 public static void main(String[] args) {
  Book b1 = new Book("Lightning", "Dean Koontz", 500);
  Book b2 = new Book("Roma: The Novel of Ancient Rome", "Steven Saylor", 452);
  Book b3 = new Book("Humility", "Andrew Murray", 334);
  Book b4 = new Book("Meditations", "Marcus Aurelius, Martin Hammond", 635);
  
  Store store = new Store();
  store.addBook(b1);
  store.addBook(b2);
  store.addBook(b3);
  store.addBook(b4);
  
  System.out.println("Display list of books in store");
  Iterator<Book> iterator = store.iterator();
  while (iterator.hasNext()) {
   Book item = iterator.next();
   System.out.println(item.toString());
   
   //Removing "Humility" from the book store list
   if(item.getName().equals("Humility")){
    iterator.remove();
   }
  }
  
  System.out.println("\n\n\nDisplay list of books in store after removing 'Humility' book");
  iterator = store.iterator();
  while (iterator.hasNext()) {
   Book item = iterator.next();
   System.out.println(item.toString());
  }
 }
}


OUTPUT:


Display list of books in store
----------

Book Name : Lightning 
Author    : Dean Koontz
Price     : Rs.500
----------

Book Name : Roma: The Novel of Ancient Rome 
Author    : Steven Saylor
Price     : Rs.452
----------

Book Name : Humility 
Author    : Andrew Murray
Price     : Rs.334
----------

Book Name : Meditations 
Author    : Marcus Aurelius, Martin Hammond
Price     : Rs.635



Display list of books in store after removing 'Humility' book
----------

Book Name : Lightning 
Author    : Dean Koontz
Price     : Rs.500
----------

Book Name : Roma: The Novel of Ancient Rome 
Author    : Steven Saylor
Price     : Rs.452
----------

Book Name : Meditations 
Author    : Marcus Aurelius, Martin Hammond
Price     : Rs.635

Java Scanner class

Scanner class in Java

Scanner class does same work as like String Tokenizer and Split() used to parse a string, pulling out data of different types. But its limit in usage and can't get array of strings delimited by a particular expression like in Split(). 

If we see about Scanner and BufferedReader classes used to read stream contents, Scanner class mainly used to parsing tokens from the contents of the stream. But BufferedReader just reads the stream and does not do any special parsing like Scanner. For parsing we can pass those BufferedReader objects to a scanner as the source of characters or string to parse. 

The other difference is BufferedReader is synchronized and Scanner is non-synchronized. Also from JDK 6 we have got 1 KB of character buffer for Scanner and 8 KB of character buffer for BufferedReader . 

Use Scanner if need to parse the file or use BufferedReader just to read the file. 

Next we will see simple example of parsing CSV file using Scanner class.

training.csv


1,Java Basics,4 weeks,INR 3000,
2,Oracle,5 weeks,INR 4500,
3,ASP.NET,6 weeks,INR 5000,
4,EJP,3 weeks,INR 4000,
5,Hibernate,4 weeks,INR 2000,
6,Spring,8 weeks,INR 6000,


TrainingBean.java


public class TrainingBean {

 private int id;
 private String course;
 private String duration;
 private String fees;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getCourse() {
  return course;
 }
 public void setCourse(String course) {
  this.course = course;
 }
 public String getDuration() {
  return duration;
 }
 public void setDuration(String duration) {
  this.duration = duration;
 }
 public String getFees() {
  return fees;
 }
 public void setFees(String fees) {
  this.fees = fees;
 }
 
 @Override
 public String toString() {
  return "ID:"+id+"\t Course:"+course+"\t Duration:"+duration+"\t Fees:"+fees;
 }
}


ScannerTest.java


public class ScannerTest {

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

  ArrayList<TrainingBean> trainingList = parseTrainingDetails("D://training.csv");

  displayTrainingDetails(trainingList);
 }

 public static ArrayList<TrainingBean> parseTrainingDetails(String file) {
  ArrayList<TrainingBean> list = new ArrayList<TrainingBean>();
  try {
   Scanner scan = new Scanner(new File(file));
   scan.useDelimiter(",");
   int i = 1;
   TrainingBean bean = new TrainingBean();
   while (scan.hasNext()) {
    String value = scan.next().trim();
    if (value.length() == 0)
     break;
    if (i == 1) {
     bean.setId(Integer.parseInt(value));
    } else if (i == 2) {
     bean.setCourse(value);
    } else if (i == 3) {
     bean.setDuration(value);
    } else if (i == 4) {
     bean.setFees(value);
     i = 0;
     list.add(bean);
     bean = new TrainingBean();
    }
    i++;
   }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  }
  return list;
 }

 public static void displayTrainingDetails(ArrayList<TrainingBean> list) {
  for (TrainingBean trainingBean : list) {
   System.out.println(trainingBean.toString());
  }
 }
}



OUTPUT:


ID:1  Course:Java Basics Duration:4 weeks  Fees:INR 3000
ID:2  Course:Oracle  Duration:5 weeks  Fees:INR 4500
ID:3  Course:ASP.NET  Duration:6 weeks  Fees:INR 5000
ID:4  Course:EJP  Duration:3 weeks  Fees:INR 4000
ID:5  Course:Hibernate Duration:4 weeks  Fees:INR 2000
ID:6  Course:Spring  Duration:8 weeks  Fees:INR 6000




Avoid direct JSP access from client browser

 
Any files inside direct context folder can be accessible through client browser, but if same files if we place under WEB-INF folder then we can't access those files from client browser. So this way we can avoid direct call or access to specific JSP files from client browser. 
To access those JSP files we need configuration in web.xml (deployment descriptor) as similar to servlet. Lets see simple deployment descriptor for configuring JSP files along with sample JSP file.

JSP File (jspinside.jsp)


<html>
 <head>
  <title>Java Discover</title>
 </head>
 <body>
  <h1>Hello Java Discover :-)</h1>
 </body>
</html>




Deployment Descriptor (web.xml)


<web-app>
 <servlet>
   <servlet-name>JSPTest</servlet-name>
   <jsp-file>/WEB-INF/jspinside.jsp</jsp-file>   
 </servlet>
  
 <servlet-mapping>
   <servlet-name>JSPTest</servlet-name>
   <url-pattern>/jsptest.do</url-pattern>
 </servlet-mapping>
</web-app>




Folder Structure:


<context_name>
      -><WEB-INF>
             -><classes>
             -><lib>
             ->jspinside.jsp
             ->web.xml


Once complete deploy and test with below url

URL : http://localhost:8080/jsptest/jsptest.do


OUTPUT:



Insertion sort in Java

As like earlier tutorial Bubble sort, in this tutorial we will see about Insertion sort in Java with simple example. Unlike the other sorting algorithm insertion sort passes through the array only once.
Basically insertion sort iterates, consuming one input element each repetition, and growing a sorted output list. Each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there. It repeats until no input elements remain. Below sample image will explain about how Insertion sort algorithm works.
Insertion sort example in Java
Now lets see simple insertion sort in java.


public class InsertionSort {

 public static void main(String[] args) {

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

  System.out.print("\nBefore sort : ");
  printArray(values);

  insertionSort(values);

  System.out.print("\nAfter sort : ");
  printArray(values);
 }

 private static void insertionSort(int[] array) {
  int i;
  for (int j = 1; j < array.length; j++) {
   int key = array[j];
   for (i = j - 1; (i >= 0) && (array[i] > key); i--) {
    array[i + 1] = array[i];
   }
   array[i + 1] = key;
  }
 }

 private static void printArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
   System.out.print(array[i] + ", ");
  }
 }
}

OUTPUT:

Before sort : 5, 4, 8, 6, 9, 1, 7, 3, 2, 
After sort : 1, 2, 3, 4, 5, 6, 7, 8, 9, 




Bubble sort in Java

Bubble sort in java

Bubble sort is the simple sorting algorithm and same time has worst-case and average complexity. Bubble sort iterating down from first element to the last element in the array by comparing each pair of elements and switching elements if they meets our sorting condition. So lets see simple example in Java by using Bubble sort algorithm.



public class BubbleSort {

 public static void main(String[] args) {

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

  System.out.print("\nBefore sort : ");
  printArray(values);

  bubbleSort(values);

  System.out.print("\nAfter sort : ");
  printArray(values);
 }

 private static void bubbleSort(int[] array) {
  for (int i = 0; i < array.length - 1; i++) {
   for (int j = i + 1; j < array.length; j++) {
    if (array[i] > array[j]) {
     int tmp = array[i];
     array[i] = array[j];
     array[j] = tmp;
    }
   }
  }
 }

 private static void printArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
   System.out.print(array[i] + ", ");
  }
 }
}


OUTPUT:


Before sort : 5, 4, 8, 6, 9, 1, 7, 3, 2, 
After sort : 1, 2, 3, 4, 5, 6, 7, 8, 9,