Object sorting using Comparator and Comparable Interface in Java

Today we will discuss about how to sort Object using Comparator and Comparable interface in Java. 

       How to sort Object using Comparator and Comparable Interface in Java is a frequent question in most of the Core Java interview questions. It can be just theory question or even some interviewer may ask to write sample code for both. In that case one has to be prepared for both to explain the different and importance of both Interface in Java and also to write a sample code. 

       Lets see some important different between these two Interface's in Java. 

  • Comparator Interface is from java.util package and Comparable Interface is from java.lang package.
  • For using Comparator Interface we need to import java.util.Comparator, where as Comparable is by default. 
  • If we implement Comparator Interface then we need to implement method called public int compare(Object obj1, Object obj2) and for Comparable Interface we need to implement method called public int compareTo(Objectobj)
  • If we see Comparator Interface it will be used to Compare 2 objects different Objects of a class and where Comparable Interface will be used to Compare same class local member variables with the Object provided to CompareTo method. 

          
     Example:

       Below example Employee Class which will implement both Comparator and Comparable Interface and also has the method implementation for compare() and compareTo() methods. 
       compare() method has 2 input parameters of Employee class object and used to sort based on Employee Name (empName). 
       comapreTo() method has single Employee class object and sorted based Employee Address (empAddress)     


Employee.java

public class Employee implements Comparator<Employee>, Comparable<Employee> {

 private String empName;
 private String empAddress;

 public Employee() {
 }

 public Employee(String empName, String empAddress) {
  this.empAddress = empAddress;
  this.empName = empName;
 }

 public String getEmpName() {
  return empName;
 }

 public void setEmpName(String empName) {
  this.empName = empName;
 }

 public String getEmpAddress() {
  return empAddress;
 }

 public void setEmpAddress(String empAddress) {
  this.empAddress = empAddress;
 }

 public int compare(Employee o1, Employee o2) {
  String o1Name = o1.getEmpName();
  String o2Name = o2.getEmpName();
  if (o1Name.compareTo(o2Name) > 0) {
   return 1;
  } else if (o1Name.compareTo(o2Name) < 0) {
   return -1;
  } else {
   return 0;
  }
 }

 public int compareTo(Employee obj) {
  return this.empAddress.compareTo(obj.empAddress);
 }
}

       

CompratorComparableTest.java

public class CompratorComparableTest {
 public static void main(String[] args) {
  
  List<Employee> arr = new ArrayList<Employee>();
  arr.add(new Employee("jobs", "delhi"));
  arr.add(new Employee("mike", "bangalore"));
  arr.add(new Employee("vera", "madras"));
  arr.add(new Employee("raja", "chennai"));
  arr.add(new Employee("mani", "rorkee"));
  arr.add(new Employee("khan", "mumbai"));
  
  // Object sort using comprator
  Collections.sort(arr, new Employee());  
  Iterator<Employee> itr = arr.iterator();
  System.out.println("Object sort using comparator - sort by Name");
  while (itr.hasNext()) {
   Employee emp = (Employee) itr.next();
   System.out.println(emp.getEmpName()+" \t\t "+emp.getEmpAddress());
  }
  
  System.out.println("\n\n");
  
  //Object sort using comprable
  Collections.sort(arr);
  Iterator<Employee> itr1 = arr.iterator();
  System.out.println("Object sort using comprable - sort by Address");
  while (itr1.hasNext()) {
   Employee empobj = (Employee) itr1.next();
   System.out.println(empobj.getEmpName()+" \t\t "+empobj.getEmpAddress());
  }
 }
}




OUTPUT:


Object sort using comparator - sort by Name
jobs    delhi
khan    mumbai
mani    rorkee
mike    bangalore
raja    chennai
vera    madras



Object sort using comprable - sort by Address
mike    bangalore
raja    chennai
jobs    delhi
vera    madras
khan    mumbai
mani    rorkee


Hope you are clear on using Comparator and Comparable Interface in Java. Please drop your comments.  




 

How to create fully Singleton design pattern class in Java

Today we will discuss about how to create fully Singleton class in Java. Before jumping to creation of Singleton class, lets list down some of the key features and usage of creating Singleton class in Java. 

What is Singleton design pattern class?

         In simple words Singleton class is nothing but having a single object or Instance of a class for entire lifetime of the application. 

       Singleton pattern is a common pattern we use in our day today code and projects in various places like reading a property file values, DB Connections etc.Restricting multiple Object or Instance creation on Class. Main property of singleton class is restricting the class Instance creation from outside Singleton class. This can be achieved by keeping private constructors. 

       Even by keeping private constructors other programmers can break singleton pattern and they can create instance outside class by other Java features like clone() and serialization. To avoid these loop hols we need to @Override clone() and readResolve() methods in our Singleton class.

       We can achieve this in 2 ways like Lazy initialization and Eager initialization in the class. Below are the small example which will explain about the Fully Singleton implementation by using Lazy initialization.


import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Random;

import javax.management.InstanceAlreadyExistsException;

class MySingleton implements Serializable  {
    
 private static MySingleton obj = null;
    private int val;
    
    private MySingleton() throws InstanceAlreadyExistsException{
     if(obj != null){
      System.out.println("\nObject already created....");
      throw new InstanceAlreadyExistsException();
     }
 
     System.out.println("Inside Constructor..");
        val = new Random().nextInt();
    }

    public static MySingleton getInstance() throws InstanceAlreadyExistsException{
        if(obj == null){
            synchronized (MySingleton.class) {
                if(obj == null){
                    obj = new MySingleton();
                }
            }
        }
        return obj;
    }
    public int getVal(){
        return val;
    }
    public void setVal(int val){
     this.val = val;
    }
    
    @Override
    protected MySingleton clone() throws CloneNotSupportedException {
     // If user tries to clone the object then we are sending same class object
        try {
   return MySingleton.getInstance();
  } catch (InstanceAlreadyExistsException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return null; 
    }
    
    private Object readResolve() throws ObjectStreamException, InstanceAlreadyExistsException {
     // We are blocking deserilizing object and sending same class object
      return MySingleton.getInstance();
  }
}


Above MySingleton class contains private constructor, getter, setter, @Override clone method, readResolve method and static method to get the class instance. Apart from that we have class member variables like MySingleton (obj) and val. In constructor just we have assigned some random value to val just for identifying multiple instance has created are we are using same instance throughout the application and next we are throwing exception called InstanceAlreadyExistsException if already class instance created. Here we are blocking other user to create instance using java.lang.reflect.Constructor class to satisfy fully singleton pattern.

          In static method we are using double to identify class has already initialized or not. If already initialized then method we will return Object (obj) else condition will go inside synchronized block. Here we are using synchronized block to avoid multiple object creation under multi-threading.


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

public class SingletonPattern {

    public static void main(String[] args)  {
     try{
         MySingleton obj1 = MySingleton.getInstance();
         MySingleton obj2 = obj1.clone();
        
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\singleton.ser")); 
         oos.writeObject(obj1); 
         oos.close(); 
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\singleton.ser")); 
         MySingleton obj3 = (MySingleton) ois.readObject(); 
         ois.close(); 
        
         System.out.println("First Object      :: "+obj1.getVal());
         System.out.println("Clone Object      :: "+obj2.getVal());
         System.out.println("Serialized Object :: "+obj3.getVal()+"\n\n");
         
         // Changing value in Object 3
         obj3.setVal(100);
         
         System.out.println("First Object      :: "+obj1.getVal());
         System.out.println("Clone Object      :: "+obj2.getVal());
         System.out.println("Serialized Object :: "+obj3.getVal()+"\n\n");
         
         // Changing value in Object 3
         obj2.setVal(1234);
         
         System.out.println("First Object      :: "+obj1.getVal());
         System.out.println("Clone Object      :: "+obj2.getVal());
         System.out.println("Serialized Object :: "+obj3.getVal());
         
         Constructor constructor = MySingleton.class.getDeclaredConstructor();
         constructor.setAccessible(true);
         MySingleton newInstance = (MySingleton) constructor.newInstance();
         
         System.out.println("NEW INSTANCE : "+newInstance.getVal());

     }catch (Exception e) {
   System.out.println(e.getCause());
  }
    }
}


In above class we created the Object (obj1) by calling static getInstance() method. 
         
         Next we have cloned the same Object (obj1) to other Object (obj2), since we have @Overrided clone() method in our first class it will return same Instance which have initialized at first time and we are blocking the cloning the Object here.

         Next we have serialized the Object (Obj1) into a file and then again we have deserialized the Object to (ob3). 

         Next we are changing the "val" value of Object (obj3) where we can see value changed in all 3 Objects in the Output and we can confirm that user can't create new Object through serializing. 

         Next we are changing the "val" value of Object (obj2) where same way value has changed in all 3 Objects in the Output and we can confirm that even by cloning user will same Object instead of new Object.

         Last we have testing whether are able to create instance using java.lang.reflect.Constructor class. In that case we will get exception called InstanceAlreadyExistsException and new instance can't be created. 

OUTPUT: 


Inside Constructor..
First Object      :: 739385266
Clone Object      :: 739385266
Serialized Object :: 739385266


First Object      :: 100
Clone Object      :: 100
Serialized Object :: 100


First Object      :: 1234
Clone Object      :: 1234
Serialized Object :: 1234

Object already created....
javax.management.InstanceAlreadyExistsException



Hope you are clear now how to create fully Singleton class. Please drop your comments below.



 

Fetch unique object values from ArrayList without looping

Today we will discuss on simple Java Collection interview question as how to fetch unique object values from ArrayList without looping through ArrayList. We can achieve by @Overriding hascode() and equals() method in our class.

Example:
 
       Lets assume we have box full of pencils with various colors like (red, green, blue, yellow etc.,) around 2000 pencils. We need to find total no. of colors in the box. 


       Lets assume box is the ArrayList and Pencil is the class with member variable called color. Below sample code is the one of the way we can fetch unique color of pencils in the ArrayList without looping.




 
 
 
public class Pencil{
 private String color;
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public Pencil(String color){
        this.color = color;
    }
    @Override
    public int hashCode() {
     return 0;
    }     
    @Override
    public boolean equals(Object obj) {
        return ((Pencil)obj).color == this.color;
    }
}


       Above Pencil class contains color member variable, constructor, getter and setter method. Along with these methods we do have @Override method implementation for hascode() and equals() which will be used to find the color of each object stored in ArrayList and while storing in HashSet will elimate duplicate value from below code.



 public class PencilColors {
 public static void main(String[] args) {
  ArrayList<Pencil> box = new ArrayList<Pencil>();
        box.add(new Pencil("red"));
        box.add(new Pencil("green"));
        box.add(new Pencil("blue"));
        box.add(new Pencil("red"));
        box.add(new Pencil("blue"));
        Set<Pencil> list = new HashSet<Pencil>(box);
        Iterator<Pencil> itr = list.iterator();
        while(itr.hasNext()){
            Pencil pencil = itr.next();
            System.out.println(pencil.getColor());
        }
    }
}



OUTPUT:

blue
green
red


Hope you are clear now how to fetch unique values from ArrayList without looping just by using Java Collections. Please drop your comments below.