Powered By Blogger

Thursday, November 22, 2012

Comparable and Comparator example

Comparable

/* Source Code- Example */

/* ------------ Sorting thru Comparable Interface (Natural Sorting) ---------
 * Implements mandatory Comparable interface
 */
class Person implements Comparable<Object>{
   
    String firstname;
    String lastname;
    public Person(String firstname, String lastname) {
        super();
        this.firstname = firstname;
        this.lastname = lastname;
    }
   
    public String getFirstname() {
        return firstname;
    }
    public String getLastname() {
        return lastname;
    }
    /*
     * return -1 : If this object is lesser than the passed object       
        return  0 : If this object is same the passed object
       return  1 : If this object is greater than the person */

    public int compareTo(Object obj){
        Person person=(Person) obj;
        return this.firstname.compareTo(person.getFirstname());
    }
}

public class PersonComparable {
   
    public static void main(String[] args) {
       
        List<Person> person=new ArrayList<Person>();
       
        person.add(new Person("Rajiv","Srivastava"));
        person.add(new Person("Akshay","Kumar"));
        person.add(new Person("Prashant","Gupta"));
       
        /* Sorting- sort method will use compareTo(Object obj) override implementation for natural sorting
         */

        Collections.sort(person);
       
        for (Person p:person){
            System.out.println(p.getFirstname()+" "+p.getLastname());
        }
    }
}

/* Result:
Akshay Kumar
Prashant Gupta
Rajiv Srivastava
*/
--------------------------------------------------------------------------------------------
/* ------------ Sorting thru Comparator Interface (Custom Sorting)
 * Implements mandatory Comparator interface
 */

Comparator:

public class MyCustomComparator implements Comparator<Object> {

    public int compare(Object obj1, Object obj2){
        Empl p1=(Empl) obj1;
        Empl p2=(Empl) obj2;
       
        String p1name=p1.getFirstname()+" "+p1.getLastname();
        String p2name=p2.getFirstname()+" "+p2.getLastname();
       
        return p1name.compareTo(p2name);
    }

    public static void main(String[] args) {
         List <Empl> plist= new ArrayList<Empl>();
       
         plist.add(new Empl("Arvind","Upadhyay"));
         plist.add(new Empl("Arvind","Tendulkar"));
         plist.add(new Empl("Arvind","Kejriwal"));
       
         Collections.sort(plist, new MyCustomComparator());
       
         for(Empl p:plist){
             System.out.println(p.firstname+ " "+p.getLastname());
         }
    }
   
}

class Empl{
   
    String firstname;
    String lastname;
    public Empl(String firstname, String lastname) {
        super();
        this.firstname = firstname;
        this.lastname = lastname;
    }
   
    public String getFirstname() {
        return firstname;
    }
    public String getLastname() {
        return lastname;
    }
}

/* Output:
 * Arvind Kejriwal
    Arvind Tendulkar
    Arvind Tripathi */

Thursday, October 18, 2012

Everything about Singleton ...

Singleton design Pattern !!! Singleton Example
It's a design pattern where a single instance of a class to be available across the application or a single server.


Singleton Pattern ensures a class has only one instance and provides a global point of access to it.

The default constructor of the class is made private, which prevents the direct instantiation of the object by other classes.

A static modifier is applied to the instance method that returns the object as it then makes this method a class level method that can be accessed without creating an object.

You implement the pattern by creating a class with a method that creates a new instance of the class if one does not exist. If an instance of the class exists, it simply returns a reference to that object.

Here is a sample running code which covers most of the limitations of this patterns and their solutions. Please read comments carefully for detail description:

/*
 * @Author- Rajiv Srivastava, 2012
 */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
/*
 *  -----------------------Singleton Design Patterns --------------------------
 *  Implementing Cloneable,Serializable interfaces
 */
    class MySingleton implements Cloneable,Serializable {
    
    /*
     * Serialization version control: if you make any changes to the this class file after de-serialization, 
     * just ensure that same version ID is specified and all will be well. Default serial version id=1L
     * It can be generated using Eclipse or command >serialver MyClassName
     */
    private static final long serialVersionUID = 1L;
    private static MySingleton INSTANCE;
    private String name;
    
    /*
     * Empty private constructor to protect this class from instantiating new object
     */
    private MySingleton(){
     //Empty constructor
    }

    public static MySingleton getSingleton(){
        if(null==INSTANCE){ 
            synchronized(MySingleton.class){//Class level lock
              if(null==INSTANCE){ //Double-checked locking
                  // Lazy instantiation
                INSTANCE=new MySingleton(); //Create only one instance
              }
            }
        }
        return INSTANCE;
    }
    
    /*
     * To prevent shallow cloning
     * @see java.lang.Object#clone()
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("Can not be cloned !!! Ooops.. New object can not be created ");
    }
    
    /*
     * To prevent multiple instances during de-serialization
     */
    private Object readResolve() throws ObjectStreamException {
          /*
           * instead of the object we're on, return the class variable INSTANCE
           */
          return INSTANCE; 
         }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
    
 public class MainSingleton{   
     @SuppressWarnings("unused")
    public static void main(String[] args) throws IOException{
         FileOutputStream fout=null;
         ObjectOutputStream outobj = null;
         
         FileInputStream fin=null;
         ObjectInputStream inobj = null;
         
         MySingleton myclone;
         MySingleton instance=MySingleton.getSingleton(); //For serialization test

         MySingleton instance1=MySingleton.getSingleton();
         System.out.println("*************  Multiple Instance Test***********");
         instance1.setName("Rajiv Srivastava");
         System.out.println("Employee Name: "+instance1.getName());
         System.out.println("instance1: "+instance1);
         
         MySingleton instance2=MySingleton.getSingleton();
         System.out.println("instance2: "+instance2);
         System.out.println("Are both instances referring to same object ? Compare [instance1==instanc2]: "+(instance1==instance2));
         
         System.out.println("*************  Cloning Test***********");
            try {
                myclone = (MySingleton) instance2.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println(e.getMessage());
            }
            
         System.out.println("************* Serialization Test***********");
         /*
          * @Serialization, File- myfile.txt
          */
         
        try {
             fout= new FileOutputStream("myfile.txt");
             outobj=new ObjectOutputStream(fout);
             outobj.writeObject(instance);
             
             outobj.flush();
             fout.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
         finally{
            outobj.close();
            fout.close();
         }
         
         /*
          * De-serialization
          */
        try{
            fin=new FileInputStream("myfile.txt");
            inobj= new ObjectInputStream(fin);
            
            MySingleton sinstance=(MySingleton) inobj.readObject();
            System.out.println("Deseraized... Name:"+sinstance.getName());
            System.out.println(sinstance.toString());
            System.out.println("Is this deserialized object 'sinstance' referring to same object ? Compare [sinstance==instance]: "+(sinstance==instance));
            
        }
        catch(FileNotFoundException fnfe){
            fnfe.getMessage();
        }
        catch(IOException ioe){
            ioe.getMessage();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally{
            inobj.close();
            fin.close();
        }
    }
 }
 
/*
 * Singleton in Multi-threading environment without using synchronized mechanism.
 * Trick: Please create static inner class which will private member of singleton class and will be thread-safe. 
 
  private static class MyInnerClass{
  private static final MySingelton myobj= new MySingelton();        
}*/

----------

Limitations and solutions of Singleton design Pattern:

Double-checked locking:

public static MySingleton getSingleton(){
        if(null==INSTANCE){ //1
            synchronized(MySingleton.class){//Class level lock
              if(null==INSTANCE){ //Double-checked locking //2
                  // Lazy instantiation
                INSTANCE=new MySingleton(); //Create only one instance
              }
            }
        }
        return INSTANCE;
    }


Two threads can get inside of the if statement concurrently when instance is null. Then, one thread enters the synchronized block to initialize instance, while the other is blocked. When the first thread exits the synchronized block, the waiting thread enters and creates another Singleton object. Note that when the second thread enters the synchronized block, it does not check to see if instance is non-null.

To fix this issue, we need a second check of instance. Thus, the name "double-checked locking."

Consider the following sequence of events:



  1. Thread 1 enters the getSingleton() method.
  2. Thread 1 enters the synchronized block at //1 because instance is null.
  3. Thread 1 is preempted by thread 2.
  4. Thread 2 enters the getSingleton() method.
  5. Thread 2 attempts to acquire the lock at //1 because instance is still null. However, because thread 1 holds the lock, thread 2 blocks at //1.
  6. Thread 2 is preempted by thread 1.
  7. Thread 1 executes and because instance is still null at //2, creates a Singleton object and assigns its reference to instance.
  8. Thread 1 exits the synchronized block and returns instance from the getSingleton() method.
  9. Thread 1 is preempted by thread 2.
  10. Thread 2 acquires the lock at //1 and checks to see if instance is null.
  11. Because instance is non-null, a second Singleton object is not created and the one created by thread 1 is returned.


The problem with double-checked locking is that there is no guarantee it will work on single or multi-processor machines.
                                                
Risks for Multi-threaded applications:



It could happen that the getSingleton() may be called twice from two different classes at the same time and more than one object being created. This could violate the design patter principle.
In order to prevent the simultaneous invocation of the
getSingleton
() by two threads or classes simultaneously we put synchronized block on the new instantiation of object. This lock would apply on class level.




          synchronized(MySingleton.class){//Class level lock
              if(null==INSTANCE){ //Double-checked locking
                  // Lazy instantiation
                INSTANCE=new MySingleton(); //Create only one instance
              }

 How to prevent multiple instances during de-serialization:

        private Object readResolve() throws ObjectStreamException {
          /*
           * instead of the object we're on, return the class variable INSTANCE
           */
          return INSTANCE; 
         }



How to prevent cloning:


We will be able to create a copy of the Object by cloning it using the Object’s clone method.. To avoid this, you need to override the Object’s clone method, which throws a CloneNotSupportedException exception:


 protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("Can not be cloned !!! Ooops.. 
New object can not be created ");
    }

Important Note:
There's absolutely no reason to implement Cloneable and override Object#clone() just to throw CloneNotSupportedException. It's just for testing.
Object#clone() already does this when the Cloneable interface is absent. It is only required if your Singleton extends a class that is Cloneable then you need to override it.


Avoiding multiple instances due to Sub-classing:

We may want to make the Singleton class final to avoid sub classing of Singletons that may cause other problems.


When to Use:

We can use Singleton pattern while creating objects of thread pools, caches etc to avoid wasting resources. If you want to store global information like item price of products etc. It's now a anti-pattern and you should avoid it by different substitutes.

Important Note: It has now become Anti-design pattern and we should avaoid by using follwoing techniques:

1. Dependency Injection
2. Using Factory design Pattern
3. Using Enum class etc. (Introduced in Java 1.5)

// Enum singleton - the preferred approach public enum MySingleton{
    INSTANCE
;
 


I have found a very good article about clustered environment below:

Singleton in a clustered Environment


Singleton is a design pattern means allowing only one instance of the class. (Check out more on singleton’s here) Singleton works well till the point you have single JVM.

In a multiple JVM’s environment, each of them will have their own copy of the singleton object which can lead to multiple issues specially in a clustered environment where the access to the resource needs to be restricted and synchronized.

To achieve clustering across JVM’s, one can use multiple techniques (JMS, DB, Custom API, 3rd party tools), but each of them have an impact on the business logic. If the requirement for JVM clustering is realized later in the game, then change to business logic will be huge.

  • In case, the requirement to have singleton across JVM’s is realized later, then tools likeTerracotta, Oracle Coherence are good options. These work on the concept of providing an in memory replication of objects across JVMs in effect providing you singleton view  or making use of any of the cluster-aware cache provider’s like SwarmCache or JBoss TreeCache should work as cache entries are singletons and clustering is built in.
  • Also, there is product called JGroups – which uses multi-cast comm. (TCP/UDP).  It allows to form a group and Applications (JVM’s) can participate and JGroups will send messages to everyone in the group so that they can be in sync.
  • Application server’s also provide some level of custom API’s to circumvent this problem.


  1. JBoss has HASingleton Service ( based on MBeans) which is meant to solve this problem. Check here and here
  2. Weblogic has the concept of Singleton Service – where only instance runs within the cluster and all clients will look up to the same instance.
  3. WebSphere supports the concept of singleton across cluster in the WebSphere XD version of the application server as the partition facility – ObjectGrid

Please add your comment If I have missed anything and give your valuable feedback :)

Monday, October 1, 2012

How to work with Java 6′s NavigableSet and NavigableMap

How to work with Java 6′s NavigableSet and NavigableMap:

This is my first published article on  popular site - mkyong.com

URL-http://www.mkyong.com/java/how-to-work-with-java-6s-navigableset-and-navigablemap/

Also, writing same article on my blog. Hope it will be helpful for you- Rajiv.

You can use latest Java 6′s Collection API to navigate a set and Map collections. These API gives a lot of flexibility to find out required result from the collection.

1. NavigableMap Example

package com.example.collection;
 
import java.util.NavigableMap;
import java.util.TreeMap;
 
public class NavigableMapDemo {
 
  public static void main(String[] args) {
 
 NavigableMap<String,Integer> navigableMap=new TreeMap<String, Integer>();
 
 navigableMap.put("X", 500);
 navigableMap.put("B", 600);
 navigableMap.put("A", 700);
 navigableMap.put("T", 800);
 navigableMap.put("Y", 900);
 navigableMap.put("Z", 200);
 
 System.out.printf("Descending Set  : %s%n",navigableMap.descendingKeySet());
 
 System.out.printf("Floor Entry  : %s%n",navigableMap.floorEntry("L"));
 
 System.out.printf("First Entry  : %s%n",navigableMap.firstEntry());
 
 System.out.printf("Last Key : %s%n",navigableMap.lastKey());
 
 System.out.printf("First Key : %s%n",navigableMap.firstKey());
 
 System.out.printf("Original Map : %s%n",navigableMap);
 
 System.out.printf("Reverse Map : %s%n",navigableMap.descendingMap());
 
  }
 
}
Output
Descending Set  : [Z, Y, X, T, B, A]
Floor Entry  : B=600
First Entry  : A=700
Last Key : Z
First Key : A
Original Map : {A=700, B=600, T=800, X=500, Y=900, Z=200}
Reverse Map : {Z=200, Y=900, X=500, T=800, B=600, A=700}

2. NavigableSet Example

package com.example.collection;
 
import java.util.Arrays;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.TreeSet;
 
public class NavigableSetDemo {
 
  public static void main(String[] args) {
 
 NavigableSet<String> navigableSet = new TreeSet<String>(Arrays.asList(
   "X", "B", "A", "Z", "T"));
 
 Iterator<String> iterator = navigableSet.descendingIterator();
 
 System.out.println("Original Set :");
 while (iterator.hasNext()) {
  System.out.println(iterator.next());
 }
 
 iterator = navigableSet.iterator();
 
 System.out.println("Sorted Navigable Set :");
 
 while (iterator.hasNext()) {
  System.out.println(iterator.next());
 }
 
 System.out.printf("Head Set : %s.%n", navigableSet.headSet("X"));
 
 System.out.printf("Tail Set : %s.%n", navigableSet.tailSet("T", false));
 
 System.out.printf("Sub Set : %s.%n",
   navigableSet.subSet("B", true, "X", true));
 
 System.out.printf("Last Element : %s%n", navigableSet.last());
 
 System.out.printf("First Element : %s%n", navigableSet.first());
 
 System.out.printf("Reverse Set : %s%n", navigableSet.descendingSet());
 
 System.out.printf("Original Set : %s%n", navigableSet);
 
  }
 
}
Output
Original Set :
Z
X
T
B
A
Sorted Navigable Set :
A
B
T
X
Z
Head Set : [A, B, T].
Tail Set : [X, Z].
Sub Set : [B, T, X].
Last Element : Z
First Element : A
Reverse Set : [Z, X, T, B, A]
Original Set : [A, B, T, X, Z]