Friday, November 3, 2017

Core java Preparation 2 + HashSet Works + Exception + Garbage Collection



package com.journaldev.java;
  public class DataKey 
  private String name;
  private int id; // 
getter and setter methods 
  @Override
public String toString() 
return "DataKey [name=" + name + ", id=" + id + "]";
 } 
 }

What is Hash Collision

In very simple terms, Java Hash table implementations uses following logic for get and put operations.

  1. First identify the “Bucket” to use using the “key” hash code.
  2. If there are no objects present in the bucket with same hash code, then add the object for put operation and return null for get operation.
  3. If there are other objects in the bucket with same hash code, then “key” equals method comes into play.
    • If equals() return true and it’s a put operation, then object value is overridden.
    • If equals() return false and it’s a put operation, then new entry is added to the bucket.
    • If equals() return true and it’s a get operation, then object value is returned.
    • If equals() return false and it’s a get operation, then null is returned.

Below image shows a bucket items of HashMap and how their equals() and hashCode() are related.

java hashmap, how hashmap works in java

The phenomenon when two keys have same hash code is called hash collision. If hashCode() method is not implemented properly, there will be higher number of hash collision and map entries will not be properly distributed causing slowness in the get and put operations. This is the reason for prime number usage in generating hash code so that map entries are properly distributed across all the buckets.

What if we don’t implement both hashCode() and equals()?

We have already seen above that if hashCode() is not implemented, we won’t be able to retrieve the value because HashMap use hash code to find the bucket to look for the entry.

If we only use hashCode() and don’t implement equals() then also value will be not retrieved because equals() method will return false.

Best Practices for implementing equals() and hashCode() method

  • Use same properties in both equals() and hashCode() method implementations, so that their contract doesn’t violate when any properties is updated.
  • It’s better to use immutable objects as Hash table key so that we can cache the hash code rather than calculating it on every call. That’s why String is a good candidate for Hash table key because it’s immutable and cache the hash code value.
  • Implement hashCode() method so that least number of hash collision occurs and entries are evenly distributed across all the buckets
HashSet works internally

Whenever you insert an element into HashSet using add() method, it actually creates an entry in theinternally backing HashMap object with element you have specified as it's key and constant called “PRESENT” as it's value. This “PRESENT” is defined in the HashSet class as below.

HashSet uses HashMap internally to store it’s objects. Whenever you create a HashSet object, oneHashMapobject associated with it is also created. This HashMap object is used to store the elements you enter in the HashSet. The elements you add into HashSet are stored as keys of this HashMap object. The value associated with those keys will be a constant.

Every constructor of HashSet class internally creates one HashMap object. You can check this in the source code of HashSet class in JDK installation directory. Below is the some sample code of the constructors of HashSet class.

privatetransientHashMap<E,Object> map;

//Constructor - 1

publicHashSet()
{
        map = newHashMap<>();          //Creating internally backing HashMap object
}

//Constructor - 2

publicHashSet(Collection<? extendsE> c)
{
        map = newHashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));     //Creating internally backing HashMap object
        addAll(c);
}

//Constructor - 3

publicHashSet(intinitialCapacity, floatloadFactor)
{
        map = newHashMap<>(initialCapacity, loadFactor);        //Creating internally backing HashMap object
}

//Constructor - 4

publicHashSet(intinitialCapacity)
{
        map = newHashMap<>(initialCapacity);          //Creating internally backing HashMap object
}


Q:-1->         How HashSet Works Internally In Java?

Whenever you insert an element into HashSet using add() method, it actually creates an entry in the internally backing HashMap object with element you have specified as it’s key and constant called “PRESENT” as it’s value. This “PRESENT” is defined in the HashSet class as below.
privatestaticfinalObject PRESENT = newObject();

Let’s have a look at add() method of HashSet class.






publicbooleanadd(E e)
{
        returnmap.put(e, PRESENT)==null;
}

You can notice that, add() method of HashSet class internally calls put() method of backing HashMap object by passing the element you have specified as a key and constant “PRESENT” as it’s value.
remove() method also works in the same manner.
?


1
2
3
4
publicbooleanremove(Object o)
{
returnmap.remove(o)==PRESENT;
}


Let’s see one example of HashSet and how it maintains HashMap internally.
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class HashSetExample
{
public static void main(String[] args)
{
//Creating One HashSet object
HashSet<String> set = newHashSet<String>();

//Adding elements to HashSet

set.add("RED");

set.add("GREEN");

set.add("BLUE");

set.add("PINK");

//Removing "RED" from HashSet

set.remove("RED");
}
}
See the below picture how above program works internally.
You can observe that internal HashMap object contains elements 
of HashSet as keys and constant “PRESENT” as their value.



In the same manner, all methods of HashSet class process internally backing
HashMap object to get the desired result. 
If you know how HashMap works, it will be easy for you to understand 
how HashSet works. You go through the source code of HashSet class once,
you will get a clear picture about how HashSet works internally in Java.


MAP
Q23) What is identity HashMap?
Ans) The IdentityHashMap uses == for equality checking instead of equals().
This can be used for both performance reasons, 
if you know that two different elements will never be equals and for preventing spoofing, 
where an object tries to imitate another.




Q24) What is WeakHashMap?
Ans) A hashtable-based Map implementation with weak keys. 
An entry in a WeakHashMap will automatically be removed
when its key is no longer in ordinary use. 
More precisely, the presence of a mapping for a given key will not prevent the key 
from being discarded by the garbage collector, that is, 
made finalizable, finalized, and then reclaimed. When a key has been



Q19) What is ConcurrentHashMap ?
Ans) A concurrentHashMap is thread-safe implementation of Map interface. 
In this class put and remove method are synchronized but not get method. 
This class is different from Hashtable in terms of locking; 
it means that hashtable use object level lock but this class uses bucket level
lock thus having better performance.




Differences

11) What is the difference between Collection and Collections?
Collection is an interface whereas Collections is a class. 
Collection interface provides normal functionality of data structure to List, Set and Queue.
 But, Collections class is to sort and synchronize collection elements.

5) What is the difference between List and Set?
List can contain duplicate elements whereas Set contains only unique elements.
7) What is the difference between Set and Map?
Set contains values only whereas Map contains key and values both.
Q4) What is difference between HashMap and HashTable?
Ans) Both collections implements Map. Both collections store value as key-value pairs. 
The key differences between the two are
  1. Hashmap is not synchronized in nature but hashtable is.
      2. Another difference is that iterator in the HashMap is fail-safe while the enumerator for           the Hashtable isn't. Fail-safe -if the Hashtable is structurally modified at any time after
          the iterator is created, in any way except through the iterator's own remove method,
          the iterator will throw a ConcurrentModificationException?

HashMap permits null values and only one null key, while Hashtable doesn't allow key or value as null.

8) What is the difference between HashSet and HashMap?
HashSet contains only values whereas HashMap contains entry(key, value). HashSet can be iterated but HashMap need to convert into Set to be iterated.
10) What is the difference between HashMap and Hashtable?

No.
HashMap
Hashtable
1)
HashMap is not synchronized.
Hashtable is synchronized.
2)
HashMap can contain one null key and multiple null values.
Hashtable cannot contain any
null key or null value.

6) What is the difference between HashSet and TreeSet?

HashSet maintains no order whereas TreeSet maintains ascending order.
9) What is the difference between HashMap and TreeMap?
HashMap maintains no order but TreeMap maintains ascending order.

How to find user defined objects as a key from HashMap?


Description:
Below example shows how to search user defined objects as a key from HashMap. 
You can achieve this by implementing equals and hashcode methods at the user defined objects.

Code:




package com.java2novice.hashmap;

import java.util.HashMap;
import java.util.Set;

public class MyObjectKeySearch {

public static void main(String a[]){
         
        HashMap<Price, String> hm = new HashMap<Price, String>();
        hm.put(new Price("Banana", 20), "Banana");
        hm.put(new Price("Apple", 40), "Apple");
        hm.put(new Price("Orange", 30), "Orange");
        printMap(hm);
        Price key = new Price("Banana", 20);
        System.out.println("Does key available? "+hm.containsKey(key));
    }
     
    public static void printMap(HashMap<Price, String> map){
         
        Set<Price> keys = map.keySet();
        for(Price p:keys){
            System.out.println(p+"==>"+map.get(p));
        }
    }
}

class Price{
     
    private String item;
    private int price;
     
    public Price(String itm, int pr){
        this.item = itm;
        this.price = pr;
    }
     
    public int hashCode(){
        System.out.println("In hashcode");
        int hashcode = 0;
        hashcode = price*20;
        hashcode += item.hashCode();
        return hashcode;
    }
     
    public boolean equals(Object obj){
        System.out.println("In equals");
        if (obj instanceof Price) {
            Price pp = (Price) obj;
            return (pp.item.equals(this.item) && pp.price == this.price);
        } else {
            return false;
        }
    }
     
    public String getItem() {
        return item;
    }
    public void setItem(String item) {
        this.item = item;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
     
    public String toString(){
        return "item: "+item+"  price: "+price;
    }
}



Output:
item: Apple  price: 40==>Apple
item: Orange  price: 30==>Orange
item: Banana  price: 20==>Banana
Does key available? true

  
Hashmap with Object as KEY

package com.HashMap;

public class Employee {

       String name;
       int id;
      
       public Employee(String name,int id){
             
              this.name = name;
              this.id =id;
       }
      
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
       public int getId() {
              return id;
       }
       public void setId(int id) {
              this.id = id;
       }
       @Override
       public String toString() {
              return "Employee [name=" + name + ", id=" + id + "]";
       }
      
      
      
      
}
package com.HashMap;

import java.util.HashMap;

public class DemoEmployeeHashmap {

       public static void main(String[] args) {
             
              Employee e1 = new Employee("Kunal", 100);
              Employee e2 = new Employee("Kamal", 101);
              Employee e3 = new Employee("Kamalwa", 102);
             
              HashMap<Employee, Integer> mp = new HashMap<Employee, Integer>();
              mp.put(e1, 20000);
              mp.put(e2, 40000);
              mp.put(e2, 60000);

              System.out.println(mp);
       }

}
Two User Defined Objects are Same or not
package com.Compare;

class PersonAgain implements Comparable {

         private String firstName;
         private String lastName;
         private int age;
        
         public PersonAgain(String firstName, String lastName, int age) {
              super();
              this.firstName = firstName;
              this.lastName = lastName;
              this.age = age;
       }

       public String getFirstName() {
           return firstName;
         }

         public void setFirstName(String firstName) {
           this.firstName = firstName;
         }

         public String getLastName() {
           return lastName;
         }

         public void setLastName(String lastName) {
           this.lastName = lastName;
         }

         public int getAge() {
           return age;
         }

         public void setAge(int age) {
           this.age = age;
         }

         public int compareTo(Object anotherPerson) throws ClassCastException {
           if (!(anotherPerson instanceof PersonAgain))
             throw new ClassCastException("A Person object expected.");
           int anotherPersonAge = ((PersonAgain) anotherPerson).getAge(); 
           return this.age - anotherPersonAge;   
         }
        
        
        
        
        /* @Override
       public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result + age;
              result = prime * result
                           + ((firstName == null) ? 0 : firstName.hashCode());
              result = prime * result
                           + ((lastName == null) ? 0 : lastName.hashCode());
              return result;
       }

       @Override
       public boolean equals(Object obj) {
              if (this == obj)
                     return true;
              if (obj == null)
                     return false;
              if (getClass() != obj.getClass())
                     return false;
              PersonAgain other = (PersonAgain) obj;
              if (age != other.age)
                     return false;
              if (firstName == null) {
                     if (other.firstName != null)
                           return false;
              } else if (!firstName.equals(other.firstName))
                     return false;
              if (lastName == null) {
                     if (other.lastName != null)
                           return false;
              } else if (!lastName.equals(other.lastName))
                     return false;
              return true;
       }
*/
       @Override
       public String toString() {
              return "PersonAgain [firstName=" + firstName + ", lastName=" + lastName
                           + ", age=" + age + "]";
       }
       }

package com.Compare;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class DemoPersonAgain {

       public static void main(String[] args) {

              PersonAgain psg1 = new PersonAgain("Perwaiz","Ali",28);
              PersonAgain psg2 = new PersonAgain("Ravi","KG",31);
              PersonAgain psg3 = new PersonAgain("Paritosh","Singh",30);
             
              String s1 = "JOB";
              String s2 = "JOB";
             
              System.out.println(s1.equals(s2));
              System.out.println(psg1.equals(psg2));
              System.out.println(psg1==psg2);
             
              List list = new ArrayList();
              list.add(psg1);
              list.add(psg2);
              list.add(psg3);
              //Collections.sort(list);
              System.out.println(list);
             
             
       }

}
OutPut:
true
false
false
[PersonAgain [firstName=Perwaiz, lastName=Ali, age=28], PersonAgain [firstName=Ravi, lastName=KG, age=31], PersonAgain [firstName=Paritosh, lastName=Singh, age=30]]
------------------------------------------------------------------------------------------------------------------------

Difference between HashMap, LinkedHashMap and TreeMap

Map m1 = new HashMap();
m1.put("map", "HashMap");
m1.put("schildt", "java2");
m1.put("mathew", "Hyden");
m1.put("schildt", "java2s");
print(m1.keySet()); 
print(m1.values()); 

SortedMap sm = new TreeMap();
sm.put("map", "TreeMap");
sm.put("schildt", "java2");
sm.put("mathew", "Hyden");
sm.put("schildt", "java2s");
print(sm.keySet()); 
print(sm.values());

LinkedHashMap lm = new LinkedHashMap();
lm.put("map", "LinkedHashMap");
lm.put("schildt", "java2");
lm.put("mathew", "Hyden");
lm.put("schildt", "java2s");
print(lm.keySet()); 
print(lm.values());


All three classes implement the Map interface and offer mostly the same functionality. The most important difference is the order in which iteration through the entries will happen:

  • HashMap makes absolutely no guarantees about the iteration order. It can (and will) even change completely when new elements are added.
  • TreeMap will iterate according to the "natural ordering" of the keys according to their compareTo() method (or an externally supplied Comparator). Additionally, it implements the SortedMap interface, which contains methods that depend on this sort order.
  • LinkedHashMap will iterate in the order in which the entries were put into the map

"Hashtable" is the generic name for hash-based maps. In the context of the Java API, Hashtable is an obsolete class from the days of Java 1.1 before the collections framework existed. It should not be used anymore, because its API is cluttered with obsolete methods that duplicate functionality, and its methods are synchronized (which can decrease performance and is generally useless). Use ConcurrentHashMap instead of Hashtable.



╔══════════════╦═════════════════════╦═══════════════════╦═════════════════════╗
║   Property   ║       HashMap       ║      TreeMap      ║     LinkedHashMap   ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║ Iteration    ║  no guarantee order ║ sorted according  ║                     ║
║   Order      ║ will remain constant║ to the natural    ║    insertion-order  ║
║              ║      over time      ║    ordering       ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║  Get/put     ║                     ║                   ║                     ║
║   remove     ║         O(1)        ║      O(log(n))    ║         O(1)        ║
║ containsKey  ║                     ║                   ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║                     ║   NavigableMap    ║                     ║
║  Interfaces  ║         Map         ║       Map         ║         Map         ║
║              ║                     ║    SortedMap      ║                     ║
╠══════════════╬═════════════════════╬═══════════════════╬═════════════════════╣
║              ║                     ║                   ║                     ║
║     Null     ║       allowed       ║    only values    ║       allowed       ║
║ values/keys  ║                     ║                   ║                     ║
╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣
║              ║   Fail-fast behavior of an iterator cannot be guaranteed      ║
║   Fail-fast  ║ impossible to make any hard guarantees in the presence of     ║
║   behavior   ║           unsynchronized concurrent modification              ║
╠══════════════╬═════════════════════╦═══════════════════╦═════════════════════╣
║              ║                     ║                   ║                     ║
║Implementation║      buckets        ║   Red-Black Tree  ║    double-linked    ║
║              ║                     ║                   ║       buckets       ║
╠══════════════╬═════════════════════╩═══════════════════╩═════════════════════╣
║      Is      ║                                                               ║
║ synchronized ║              implementation is not synchronized               ║
╚══════════════╩═══════════════════════════════════════════════════════════════╝

All three represent mapping from unique keys to values, and therefore implement the Map interface.

         1.      HashMap is a map based on hashing of the keys. It supports O(1) get/put operations.
                  Keys must have consistent implementations of hashCode() and equals() 
                  for this to work.

         2.      LinkedHashMap is very similar to HashMap, but it adds awareness to the order at which 
                  items are added (or accessed), so the iteration order is the same as insertion order 
                  (or access order, depending on construction parameters).
        3.       TreeMap is a tree based mapping. Its put/get operations take O(log n) time.
                  It requires items to have some comparison mechanism, either with Comparable 
                  or Comparator. The iteration order is determined by this mechanism.

---------------------------------------------------------------------------------------------------
Equals

http://www.javaworld.com/article/2072762/java-app-dev/object-equality.html







HashCode

Data Structure used in HashMap

HashMaps use an array in the background. Each element in the array is another data structure 
(usually a linked list or binary search tree). The HashMap uses a function on the key to determine 
where to place the key's value in the array.




14) What does the hashCode() method?
The hashCode() method returns a hash code value (an integer number).
The hashCode() method returns the same integer number, if two keys (by calling equals() method)
 are same.
But, it is possible that two hash code numbers can have different or same keys.

15) Why we override equals() method?

The equals method is used to check whether two objects are same or not.
 It needs to be overridden if we want to check the objects based on property.
For example, Employee is a class that has 3 data members: id, name and salary.
But, we want to check the equality of employee object on the basis of salary. 
Then, we need to override the equals() method.


Iterator


1.      Recap : Difference between Fail Fast Iterator and Fail Safe Iterator

Fail Fast Iterator
Fail Safe Iterator
Throw ConcurrentModification Exception
Yes
No
Clone object
No
Yes
Memory Overhead
No
Yes
Examples
HashMap,Vector,ArrayList,HashSet

CopyOnWriteArrayList,
ConcurrentHashMap
“Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking,
 impossible to make any hard guarantees in the presence of unsynchronized concurrent modification.
Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. 
Therefore, it would be wrong to write a program that depended on this exception 
for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.”


       3) What is the difference between Iterator and ListIterator?

Iterator traverses the elements in forward direction only whereas ListIterator traverses the elements in forward and backward direction.
No.
Iterator
ListIterator
1)
Iterator traverses the elements in forward direction only.
ListIterator traverses the elements in backward and forward
directions both.
2)
Iterator can be used in List, Set and Queue.
List Iterator can be used in List only.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class ExternalIteratorDemo 
{
  public static void main(String[] args) 
  {
 List<String> names = new LinkedList<>();
 names.add("Rams");
 names.add("Posa");
 names.add("Chinni");
 
 // Getting Iterator
 Iterator<String> namesIterator = names.iterator();
  
 // Traversing elements
 while(namesIterator.hasNext()){
  System.out.println(namesIterator.next());   
 } 
 
  }



4) What is the difference between Iterator and Enumeration?

No.
Iterator
Enumeration
1)
Iterator can traverse legacy and non-legacy elements.
Enumeration can traverse
 only legacy elements.
2)
Iterator is fail-fast.
Enumeration is not fail-fast.
3)
Iterator is slower than Enumeration.
Enumeration is faster than Iterator.
4)
Iterator has remove(),
Enumeration does not have any method.
5)
hasNext(), next(), remove()
hasNextElement(),





Q14) What is difference between iterator access and index access?
Ans) Index based access allow access of the element directly on the basis of index. The cursor of the datastructure can directly goto the 'n' location and get the element. It does not traverse through n-1 elements.
In Iterator based access, the cursor has to traverse through each element to get the desired element. So to reach the 'n'th element it need to traverse through n-1 elements.
Insertion, updation or deletion will be faster for iterator based access if the operations are performed on elements present in between the datastructure.
Traversal or search in index based datastructure is faster.
ArrayList is index access and LinkedList is iterator access.
Q11) What are advantages of  iterating a collection using iterator?
Ans) For loop does not allow the updation in the array(add or remove operation) inside the loop whereas Iterator does. Also Iterator can be used where there is no clue what type of collections will be used because all collections have iterator.

Q12) Which design pattern Iterator follows?
Ans) It follows Iterator design pattern. Iterator Pattern is a type of behavioral pattern. The Iterator pattern is one, which allows you to navigate through a collection of data using a common interface without knowing about the underlying implementation. Iterator should be implemented as an interface. This allows the user to implement it anyway its easier for him/her to return data. The benefits of Iterator are about their strength to provide a common interface for iterating through collections without bothering about underlying implementation.
Example of Iteration design pattern - Enumeration The class java.util.Enumeration is an example of the Iterator pattern. It represents and abstract means of iterating over a collection of elements in some sequential order without the client having to know the representation of the collection being iterated over. It can be used to provide a uniform interface for traversing collections of all kinds.
-------------------------------------------------------------------------------------------------------------------
SORTING

package com.Sort;

import java.util.ArrayList;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class SortingTest {


public static void main(String[] args) {


Set<Integer> set = new HashSet<Integer>();

set.add(1);
set.add(32);
set.add(65);
set.add(5);

List<Integer> list = new ArrayList<Integer>();



list.add(111);
list.add(2);
list.add(3);
list.add(400);

System.out.println(list);

Collections.sort(list);

System.out.println(list);

}


}

OUTPUT:-

[111, 2, 3, 400]
[2, 3, 111, 400]



------------------------------------------------------End of Iterator----------------------------------------------
Comparable and Comparator


Java Comparable interface

Java Comparable interface is used to order the objects of user-defined class. 
This interface is found in java.lang package and contains only one method named
 compareTo(Object). It provide single sorting sequence only i.e. 
you can sort the elements on based on single data member only. 
For example it may be rollno, name, age or anything else.

compareTo(Object obj) method

public int compareTo(Object obj): is used to compare the current object with the

 specified object.
We can sort the elements of:
  1. String objects
  2. Wrapper class objects
  3. User-defined class objects       

Collections class

Collections class provides static methods for sorting the elements of collections. 
If collection elements are of Set or Map, we can use TreeSet or TreeMap.
 But We cannot sort the elements of List. Collections class provides methods for sorting the 
elements of List type elements.
Method of Collections class for sorting List elements
public void sort(List list): is used to sort the elements of List. List elements must be of 
Comparable type.

Note: String class and Wrapper classes implements Comparable interface by default. 

So if you store the objects of string or wrapper classes in list, set or map, it will be

 Comparable by default.

Java Comparable Example
Let's see the example of Comparable interface that sorts the list elements on the basis of age.
File: Student.java
class Student implements Comparable<Student>{  
int rollno;  
String name;  
int age;  
Student(int rollno,String name,int age){  
this.rollno=rollno;  
this.name=name;  
this.age=age;  
}  
  
public int compareTo(Student st){  
if(age==st.age)  
return 0;  
else if(age>st.age)  
return 1;  
else  
return -1;  
}  
}  
File: TestSort3.java
             import java.util.*;  
              import java.io.*;  
              public class TestSort3{  
                          public static void main(String args[]){  
                                     ArrayList<Student> al=new ArrayList<Student>();  
                                              al.add(new Student(101,"Vijay",23));  
                                            al.add(new Student(106,"Ajay",27));  
                                            al.add(new Student(105,"Jai",21));  
        
                                             Collections.sort(al);  
                                           for(Student st:al){  
                                                 System.out.println(st.rollno+" "+st.name+" "+st.age);  
                                        }  
                                }  
                 }  
Output:105 Jai 21
       101 Vijay 23
       106 Ajay 27
 

Java Comparator interface

Java Comparator interface is used to order the objects of 

user-defined class.
This interface is found in java.util package and contains 2 
methods compare(Object obj1,Object obj2) and
 equals(Object element).
It provides multiple sorting sequence 
i.e. you can sort the elements on the basis of any data member, 
for example rollno, name, age or anything else.
compare() method
public int compare(Object obj1,Object obj2): compares the first
 object with second object.
Collections class
Collections class provides static methods for sorting the 
elements of collection. If collection elements are of
 Set or Map, we can use TreeSet or TreeMap. 
But we cannot sort the elements of List. Collections 
class provides methods for sorting the elements of List type 
elements also.


Method of Collections class for sorting List elements
public void sort(List list, Comparator c): is used to sort
 the elements of List by the given Comparator.

Java Comparator Example (Non-generic Old Style)

Let's see the example of sorting the elements of
 List on the basis of age and name. In this example, 
we have created 4 java classes:
  1. Student.java
  2. AgeComparator.java
  3. NameComparator.java
  4. Simple.java
Student.java
This class contains three fields rollno, name and age and a parameterized constructor.
1.      class Student{  
2.      int rollno;  
3.      String name;  
4.      int age;  
5.      Student(int rollno,String name,int age){  
6.      this.rollno=rollno;  
7.      this.name=name;  
8.      this.age=age;  
9.      }  
10.  }  


AgeComparator.java
This class defines comparison logic based on the age. If age of first object is 
greater than the second, we are returning positive value, it can be any one such 
as 1, 2 , 10 etc. If age of first object is less than the second object, we are returning
 negative value, it can be any negative value and if age of both objects are equal, 
we are returning 0.


1.      import java.util.*;  
2.      class AgeComparator implements Comparator{  
3.      public int compare(Object o1,Object o2){  
4.      Student s1=(Student)o1;  
5.      Student s2=(Student)o2;  
6.        
7.      if(s1.age==s2.age)  
8.      return 0;  
9.      else if(s1.age>s2.age)  
10.  return 1;  
11.  else  
12.  return -1;  
13.  }  
14.  }  


NameComparator.java

This class provides comparison logic based on the name. In such case, we are using the 

compareTo() method of String class, which internally provides the comparison logic.
1.     

       import java.util.*;  
2.      class NameComparator implements Comparator{  
3.      public int compare(Object o1,Object o2){  
4.      Student s1=(Student)o1;  
5.      Student s2=(Student)o2;  
6.        
7.      return s1.name.compareTo(s2.name);  
8.      }  
9.      }  



Simple.java
In this class, we are printing the objects values by sorting on the basis of name and age.
import java.util.*;  
import java.io.*;  
  
class Simple{  
public static void main(String args[]){  
  
ArrayList al=new ArrayList();  
al.add(new Student(101,"Vijay",23));  
al.add(new Student(106,"Ajay",27));  
al.add(new Student(105,"Jai",21));  
  
System.out.println("Sorting by Name...");  
  
Collections.sort(al,new NameComparator());  
Iterator itr=al.iterator();  
while(itr.hasNext()){  
Student st=(Student)itr.next();  
System.out.println(st.rollno+" "+st.name+" "+st.age);  
}  
  
System.out.println("sorting by age...");  
  
Collections.sort(al,new AgeComparator());  
Iterator itr2=al.iterator();  
while(itr2.hasNext()){  
Student st=(Student)itr2.next();  
System.out.println(st.rollno+" "+st.name+" "+st.age);  
}  
}  
}  
       Sorting by Name...
       106 Ajay 27
       105 Jai 21
       101 Vijay 23
 
       Sorting by age...       
       105 Jai 21
       101 Vijay 23
       106 Ajay 27



Java Comparator Example (Generic)
Student.java
1.      class Student{  
2.      int rollno;  
3.      String name;  
4.      int age;  
5.      Student(int rollno,String name,int age){  
6.      this.rollno=rollno;  
7.      this.name=name;  
8.      this.age=age;  
9.      }  
10.  }  
AgeComparator.java
import java.util.*;  
class AgeComparator implements Comparator<Student>{  
public int compare(Student s1,Student s2){  
if(s1.age==s2.age)  
return 0;  
else if(s1.age>s2.age)  
return 1;  
else  
return -1;  
}  
}  
NameComparator.java
This class provides comparison logic based on the name.
 In such case, we are using the compareTo() 
method of String class, which internally provides the 
comparison logic.
import java.util.*;  
class NameComparator implements Comparator<Student>{  
public int compare(Student s1,Student s2){  
return s1.name.compareTo(s2.name);  
}  
}  
Simple.java
In this class, we are printing the objects values by sorting on the basis of name and age.
import java.util.*;  
import java.io.*;  
class Simple{  
public static void main(String args[]){  
  
ArrayList<Student> al=new ArrayList<Student>();  
al.add(new Student(101,"Vijay",23));  
al.add(new Student(106,"Ajay",27));  
al.add(new Student(105,"Jai",21));  
  
System.out.println("Sorting by Name...");  
  
Collections.sort(al,new NameComparator());  
for(Student st: al){  
System.out.println(st.rollno+" "+st.name+" "+st.age);  
}  
  
System.out.println("sorting by age...");  
  
Collections.sort(al,new AgeComparator());  
for(Student st: al){  
System.out.println(st.rollno+" "+st.name+" "+st.age);  
}  
  
}  
}  
Output:Sorting by Name...
       106 Ajay 27
       105 Jai 21
       101 Vijay 23
 
       Sorting by age...       
       105 Jai 21
       101 Vijay 23
       106 Ajay 27

Comparator and Comparable in Java Examples
Difference between Comparator and Comparable in Java is very popular Java interview question 
mostly asked in telephonic round and writing code to sort object using Comparable or Comparator 
is popular on  written test round of interview. The question was this “How you will sort Employee
 object based on his Employee ID and his name” and this involves the use of both Comparable as
 well as Comparator interface in Java. This post is my revision on Java fundamentals similar to 
I did about equals method in Java and  some tips to override hashCode in Java. All of these 
methods are fundamentals in Java programming language and correct understanding is must 
for any Java developer. Comparators and comparable in Java are two interfaces which is used
 to implement sorting in Java. It’s often required to sort objects stored in any collection classes 
like ArrayList, HashSet or in Array and that time we need to use either  compare() or  compareTo()
 method defined in java.util.Comparator and java.lang.Comparable. In this Java tutorial 
we will see example of  Comparator and Comparable to sort object in Java and discuss some
 best practices around when to use Comparator interface etc. Any way before moving ahead
 Let’s see some important differences between Comparable and Comparator in Java.

Comparator vs Comparable in Java
Here are some of the common differences, which is worth remembering to answer this question 
if asked during a telephonic or face to face interview:

1) Comparator in Java is defined in java.util package while Comparable interface in Java is 

defined in java.lang package, which very much says that Comparator should be used as an 
utility to sort objects which Comparable should be provided by default.

2) Comparator interface in Java has method public int compare (Object o1, Object o2) 

which returns a negative integer, zero, or a positive integer as the first argument is less than,
 equal to, or greater than the second. While Comparable interface has method public
 int compareTo(Object o) which returns a negative integer, zero, or a positive integer as this 
object is less than, equal to, or greater than the specified object.

3) If you see then logical difference between these two is Comparator in Java compare 

two objects provided to him, while Comparable interface compares "this" reference with
 the object specified. I have shared lot of tips on how to override compareTo() method and
 avoid some common mistakes programmer makes while implementing Comparable interface.
\
4) Comparable in Java is used to implement natural ordering of object. In Java API String,
 Date and wrapper classes implements Comparable interface. Its always good practice to override
 compareTo() for value objects.

5) If any class implement Comparable interface in Java then collection of that object either

 List or Array can be sorted automatically by using  Collections.sort() or Arrays.sort() method 
and object will be sorted based on there natural order defined by CompareTo method.
\
6) Objects which implement Comparable in Java  can be used as keys in a SortedMap like
 TreeMap or elements in a SortedSet  for example TreeSet, without specifying any Comparator.

These were combination of some theoretical and practical differences between Comparator

 and Comparator interface in Java. It does help you to decide when to use Comparator vs Comparable 
but things will be more clear when we some best practices around using both of these interfaces. 
Now let’s see an example of Comparator in Java:

Example of using Comparator and Comparable in Java

So in Summary if you want to sort objects based on natural order then use 

Comparable in Java and if you want to sort on some other attribute of object then use 
Comparator in Java. Now to understand these concepts lets see an example or real life coding:

1) There is class called Person, sort the Person based on person_id, which is primary key

 in database

2) Sort the Person based on their name.

For a Person class, sorting based on person_id can be treated as natural order sorting and 

sorting based on name field can be implemented using Comparator interface. To sort based 
on person_id we need to implement compareTo() method.

public class Person implements Comparable {
   
 private int person_id;
   
 private String name;
   
 
   
 /**
     * Compare current person with specified person
     * return zero if person_id for both person is same
 
     * return negative if current person_id is less than specified one
     * return positive if specified person_id is greater than specified one
     */

    @Override 
   
 public int compareTo(Object o) {
        Person p = (Person) o; 
       
 return this.person_id - o.person_id ;
   
 }
    ….
}

Generally you should not use difference of integers to decide output of compareTo method
 as result of
 integer subtraction can overflow but if you are sure that both operands are positive

 then it’s one of the quickest way to compare two objects. See my 
post things to remember while overriding compareTo in Java for more tips on compareTo.
And for sorting based on person name we can implement compare(Object o1, Object o2) method 
of Java Comparator class.
/**
 * Comparator implementation which sorts Person objects on person_id field
 */

public
 class SortByPerson_ID implements Comparator{

   
 public int compare(Object o1, Object o2) {
        Person p1 = (Person) o;
        Person p2 = (Person) o; 
       
 return p1.getPersonId() - p2.getPersonId();
   
 }
}

Similar guidelines applies while implementing compare() method as well and instead of using
 subtraction operator, it’s better to use logical operator to compare whether two integers are equal to,
 less than or greater than. You can write several types of Java Comparator based upon your need for
 example  reverseComparator , ANDComparator , ORComparator etc which will return negative or 
positive number based upon logical results. String in Java even provides an special comparator 
called CASE_INSENSITIVE_ORDER, to perform case insensitive comparison of String objects.

How to Compare String in Java

String is immutable in Java and one of the most used value class. For comparing String in Java
 we should not be worrying because String implements Comparable interface and provides a 
lexicographic implementation for CompareTo method which compare two strings based on 
contents of characters or you can say in lexical order. You just need to call
 String.compareTo(AnotherString) and Java will determine whether specified String is greater 
than , equal to or less than current object. See my post 4 example to compare String in Java for 
alternatives ways of comparing String.
Mathematics, the lexicographic or lexicographical order (also known as lexical order, 
dictionary order, alphabetical order orlexicographic(al) product) is a generalization of 
the way the alphabetical order of words is based on the alphabetical order of their 
component letters.

How to Compare Dates in Java
Dates are represented by java.util.Date class in Java and like String,  Date also implements 
Comparable in Java so they will be automatically sorted based on there natural ordering if they
 got stored in any sorted collection like TreeSet or TreeMap. If you explicitly wants to compare 
two dates in Java you can call Date.compareTo(AnotherDate) method in Java and it will tell
 whether specified date is greater than , equal to or less than current String. See my 
post 3 ways to compare Dates in Java for more alternatives of comparing two dates.

When to use Comparator and Comparable in Java
At last let’s see some best practices and recommendation on when to use 
Comparator or Comparable in Java:
1) If there is a natural or default way of sorting Object already exist during development of
 Class than use Comparable. This is intuitive and you given the class name people should be
 able to guess it correctly like Strings are sorted chronically, Employee can be sorted by there 
Id etc. On the other hand if an Object can be sorted on multiple ways and client is specifying on 
which parameter sorting should take place than use Comparator interface. for example Employee
 can again be sorted on name, salary or department and clients needs an API to do that. Comparator
 implementation can sort out this problem.

2) Some time you write code to sort object of a class for which you are not the original author,

 or you don't have access to code. In these cases you can not implement Comparable and Comparator
 is only way to sort those objects.

3) Beware with the fact that How those object will behave if stored in SorteSet or SortedMap

 like TreeSet and TreeMap. If an object doesn't implement Comparable than while putting them 
into SortedMap, always provided corresponding Comparator which can provide sorting logic.

4) Order of comparison is very important while implementing Comparable or Comparator interface. 

for example if you are sorting object based upon name than you can compare first name or last name
 on any order, so decide it judiciously. I have shared more detailed tips on compareTo on my post
 how to implement CompareTo in Java.

5) Comparator has a distinct advantage of being self descriptive  for example if you are 

writing Comparator to compare two Employees based upon there salary than name that 
comparator as SalaryComparator, on the other hand compareTo().


12) What is the difference between Comparable and Comparator?
No.
Comparable
Comparator
1)
Comparable provides only one sort of sequence.
Comparator provides
multiple sort of sequences.
2)
It provides one method named compareTo().
It provides one method
 named compare().
3)
It is found in java.lang package.
it is found in java.util package.
4)
If we implement Comparable interface, actual class is modified.
Actual class is not modified.


Comparator





 ----------------------------------------------------------------------------------------------------
Heap & Stack

1) Difference between Stack and Heap in Java?
Why do someone this question as part of multi-threading and concurrency? 

because Stack is a memory area which is closely associated with threads. 
To answer this question, both stack and heap are specific memories in Java application. 
Each thread has their own stack, which is used to store local variables, method parameters and
 call stack. Variable stored in one Thread's stack is not visible to other. On other hand, heap is a 
common memory area which is shared by all threads. Objects whether local or at any level is 
created inside heap. To improve performance thread tends to cache values from heap into their stack,
which can create problems if that variable is modified by more than one thread, this is where 
volatile variables comes in picture. volatile suggest threads to read value of variable always 
from main memory. See this article to learn more about stack and heap in Java to answer this 
question in greater detail.

Garbage Collector

Java Garbage Collection

In java, garbage means unreferenced objects.
Garbage Collection is process of reclaiming the runtime unused 
memory automatically.
 In other words, it is a way to destroy the unused objects.
To do so, we were using free() function in C language and delete()
 in C++. 
But, in java it is performed automatically. 
So, java provides better memory management.
Advantage of Garbage Collection
  • It makes java memory efficient  because garbage collector removes the unreference 
  • objects from heap memory.
  • It is automatically done by the garbage collector(a part of JVM) 
  • so we don't need to make extra efforts.

How can an object be unreferenced?

There are many ways:
  • By nulling the reference
  • By assigning a reference to another
  • By anonymous object etc.
1) By nulling a reference:
              Employee e=new Employee();  
               e=null;  

2) By assigning a reference to another:

  Employee e1 = new Employee();  
        Employee e2 = new Employee();  
        e1=e2;//now the first object referred by e1 is available for
                    garbage collection  

3) By annonymous object:
               new Employee();  

finalize() method

The finalize() method is invoked each time before the object is 
garbage collected. This method can be used to perform cleanup 
processing. This method is defined in Object class as:
          protected void finalize(){}  

Note: The Garbage collector of JVM collects only those 

objects that are created by new keyword. 

So if you have created any object without new, 

you can use finalize method to perform cleanup 

processing (destroying remaining objects).

  gc() method

The gc() method is used to invoke the garbage collector to 
perform cleanup processing.
 The gc() is found in System and Runtime classes.
           public static void gc(){}  

Note: Garbage collection is performed by a daemon 

thread called Garbage Collector(GC). 

This thread calls the finalize() method before object is 

garbage collected.

Simple Example of garbage collection in java

        public class TestGarbage1{  
          public void finalize(){
           System.out.println("object is garbage collected");}  
          public static void main(String args[]){  
         TestGarbage1 s1=new TestGarbage1();  
          TestGarbage1 s2=new TestGarbage1();  
           s1=null;  
           s2=null;  
          System.gc();  
          }  
      }  
       object is garbage collected
       object is garbage collected

 JVM Architecture

Following diagram summarizes the key components in a JVM.
In the JVM architecture, two main components that are related to garbage collection are 
heap memory and garbage collector. Heap memory is the runtime data area where 
the instances will be store and the garbage collector will operate on. Now we know 
how these things fit in the larger scheme.

 Java Heap Memory

It is essential to understand the role of heap memory in JVM memory model.
 At runtime the Java instances are stored in the heap memory area. 
When an object is not referenced anymore it becomes eligible for eviction from heap memory. 
During garbage collection process, those objects are evicted from heap memory and 
the space is reclaimed. Heap memory has three major areas,
  1. Young Generation
    1. Eden Space (any instance enters the runtime memory area through eden)
    2. S0 Survivor Space (older instances moved from eden to S0)
    3. S1 Survivor Space (older instances moved from S0 to S1)
  2. Old Generation (instances promoted from S1 to tenured)
  3. Permanent Generation (contains meta information like class, method detail)

Update: Permanent Generation (Permgen) space is removed from Java SE 8 features.

Java Garbage Collection GC Initiation

Being an automatic process, programmers need not initiate the garbage collection process 
explicitly in the code. System.gc() and Runtime.gc() are hooks to request the JVM to initiate 
the garbage collection process.
Though this request mechanism provides an opportunity for the programmer to initiate 
the process but the onus is on the JVM. It can choose to reject the request and so it is not 
guaranteed that these calls will do the garbage collection. This decision is taken by the JVM
 based on the eden space availability in heap memory. The JVM specification leaves this choice 
to the implementation and so these details are implementation specific.
Undoubtedly we know that the garbage collection process cannot be forced. 
I just found out a scenario when invoking System.gc() makes sense. Just go through this 
article to know about this corner case when System.gc() invocation is applicable.

Java Garbage Collection Process

Garbage collection is the process of reclaiming the unused memory space and making it available
 for the future instances.


Eden Space: When an instance is created, it is first stored in the eden space in young generation 
of heap memory area.
NOTE: If you couldn’t understand any of these words, I recommend you to go through 
the garbage collection introduction tutorial which goes through the memory mode, 
JVM architecture and these terminologies in detail.


Survivor Space (S0 and S1): As part of the minor garbage collection cycle,

objects that are live (which is still referenced) are moved to survivor space S0 from eden space. 
Similarly the garbage collector scans S0 and moves the live instances to S1.
Instances that are not live (dereferenced) are marked for garbage collection. 
Depending on the garbage collector (there are four types of garbage collectors available 
and we will see about them in the next tutorial) chosen either the marked instances will be 
removed from memory on the go or the eviction process will be done in a separate process.


Old Generation: Old or tenured generation is the second logical part of the heap memory. 

When the garbage collector does the minor GC cycle, instances that are still live in the S1 
survivor space will be promoted to the old generation. Objects that are dereferenced in the
 S1 space is marked for eviction.


Major GC: Old generation is the last phase in the instance life cycle with respect to the 

Java garbage collection process. Major GC is the garbage collection process that scans the 
old generation part of the heap memory. If instances are dereferenced, then they are marked
for eviction and if not they just continue to stay in the old generation.

Memory Fragmentation: Once the instances are deleted from the heap memory the location

becomes empty and becomes available for future allocation of live instances. 
These empty spaces will be fragmented across the memory area. For quicker allocation of the
instance it should be defragmented. Based on the choice of the garbage collector, 
the reclaimed memory area will either be compacted on the go or will be done in a separate 
pass of the GC.

 Finalization of Instances in Garbage Collection

Just before evicting an instance and reclaiming the memory space,
 the Java garbage collector 
invokes the finalize() method of the respective instance 
so that the instance will get a chance to free up any resources held 
by it. Though there is a guarantee that the finalize() will be invoked 
before reclaiming the memory space, there is no order or 
time specified. The order between multiple instances cannot be 
predetermined; they can even happen in parallel. 
Programs should not pre-mediate an order between instances 
and reclaim resources using the finalize() method.
  • Any uncaught exception thrown during finalize process is ignored silently and the finalization of that instance is cancelled.
  • JVM specification does not discuss about garbage collection with respect to weak references and claims explicitly about it. Details are left to the implementer.
  • Garbage collection is done by a daemon thread.

When an object becomes eligible for garbage collection?

  • Any instances that cannot be reached by a live thread.
  • Circularly referenced instances that cannot be reached by any other instances.
There are different types of references in Java. Instances eligibility for garbage collection depends on the type of reference it has.

Reference
Garbage Collection
Strong Reference
Not eligible for garbage collection
Soft Reference
Garbage collection possible but will be done as a last option
Weak Reference
Eligible for Garbage Collection
Phantom Reference
Eligible for Garbage Collection
During compilation process as an optimization technique the Java compiler can choose to assign
null value to an instance, so that it marks that instance can be evicted.


ClassAnimal{
Publicstaticvoid main(String[] args){
Animal lion =newAnimal();
System.out.println("Main is completed.");
}
 
Protectedvoid finalize(){
System.out.println("Rest in Peace!");
}
}


In the above class, lion instance is never uses beyond the instantiation line. So the Java compiler 

as an optimization measure can assign lion = null just after the instantiation line. 
So, even before SOP’s output, the finalizer can print ‘Rest in Peace!’.
 We cannot prove this deterministically as it depends on the JVM implementation and memory used 
at runtime. But there is one learning; compiler can choose to free instances earlier in a program 
if it sees that it is referenced no more in the future.
  • One more excellent example for when an instance can become eligible for garbage collection. All the properties of an instance can be stored in the register and thereafter the registers will be accessed to read the values. There is no case in future that the values will be written back to the instance. Though the values can be used in future, still this instance can be marked eligible for garbage collection. Classic isn’t it?
  • It can get as simple as an instance is eligible for garbage collection when null is assigned to it or it can get complex as the above point. These are choices made by the JVM implementer. Objective is to leave as small footprint as possible, improves the responsiveness and increase the throughput. In order to achieve this the JVM implementer can choose a better scheme or algorithm to reclaim the memory space during garbage collection.
  • When the finalize() is invoked, the JVM releases all synchronize locks on that thread.

        Example Program for GC Scope

ClassGCScope{
               GCScope t;
               staticint i =1;
 
               publicstaticvoid main(String args[]){
                               GCScope t1 =newGCScope();
                               GCScope t2 =newGCScope();
                               GCScope t3 =newGCScope();
 
                               // No Object Is Eligible for GC
 
                               t1.t = t2;// No Object Is Eligible for GC
                               t2.t = t3;// No Object Is Eligible for GC
                               t3.t = t1;// No Object Is Eligible for GC
 
                               t1 =null;
                               // No Object Is Eligible for GC (t3.t still has a reference to t1)
 
                               t2 =null;
                               // No Object Is Eligible for GC (t3.t.t still has a reference to t2)
 
                               t3 =null;
                               // All the 3 Object Is Eligible for GC (None of them have a reference.
                               // only the variable t of the objects are referring each other in a
                               // rounded fashion forming the Island of objects with out any external
                               // reference)
               }
 
               protectedvoid finalize(){
                               System.out.println("Garbage collected from object"+ i);
                               i++;
               }

Example Program for GC OutOfMemoryError

Garbage collection does not guarantee safety from out of memory issues. 
Mindless code will lead us to OutOfMemoryError.
import java.util.LinkedList;
import java.util.List;
 
publicclass GC {
               publicstaticvoid main(String[] main){
                               List l =newLinkedList();
                               // Enter infinite loop which will add a String to the list: l on each
                               // iteration.
                               do{
                                              l.add(newString("Hello, World"));
                               }while(true);
               }
}
Output:
Exception in thread "main" java.lang.OutOfMemoryError:Java heap space
               at java.util.LinkedList.linkLast(LinkedList.java:142)
               at java.util.LinkedList.add(LinkedList.java:338)
               at com.javapapers.java.GCScope.main(GCScope.java:12)
Next is the third part of the garbage collection tutorial series and we will see about the different types of Java garbage collectors available.
----------------------------------------------------------------------------------------------------
Errors
StackOverflowError: The Java Virtual Machine implementation has run out of 
stack space for a thread, typically because the thread is doing an unbounded 
number of recursive invocations as a result of a fault in the executing program.

ClassNotFoundException vs. NoClassDefFoundError

ClassNotFoundException is an exception that occurs when you try to load a class
 at run time using Class.forName() or loadClass() methods and mentioned classes are
 not found in the classpath. NoClassDefFoundError is an error that occurs when a 
particular class is present at compile time, but was missing at run time.

ClassNotFoundException
NoClassDefFoundError
It is an exception. It is of type java.lang.Exception.
It is an error. It is of type java.lang.Error.
It occurs when an application tries to load a class at run time which is not updated in the classpath.
It occurs when java runtime system doesn’t find a class definition, which is present at compile time, but missing at run time.
It is thrown by the application itself. It is thrown by the methods like Class.forName(), loadClass() and findSystemClass().
It is thrown by the Java Runtime System.
It occurs when classpath is not updated with required JAR files.
It occurs when required class definition is missing at runtime.

ClassNotFoundException

ClassNotFoundException is a runtime exception that is thrown 
when an application tries to load a class at runtime using the 
Class.forName() or loadClass() or findSystemClass() methods 
,and the class with specified name are not found in the classpath. 
For example, you may have come across this exception when you
 try to connect to MySQL or Oracle databases and you have not
 updated the classpath with required JAR files. Most of the time, 
this exception occurs when you try to run an application without 
updating the classpath with required JAR files.
For example, the below program will throw 
ClassNotFoundException if the mentioned class
 “oracle.jdbc.driver.OracleDriver” is not found in the classpath.
public class MainClass
{
    public static void main(String[] args)
    {
        try
        {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        }catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}

NoClassDefFoundError

NoClassDefFoundError is an error that is thrown when the Java Runtime System tries to load the definition of a class, and that class definition is no longer available. The required class definition was present at compile time, but it was missing at runtime. For example, compile the program below.
class A
{
  // some code
}
public class B
{
    public static void main(String[] args)
    {
        A a = new A();
    }
}
When you compile the above program, two .class files will be generated. One is A.class and another one is B.class. If you remove the A.class file and run the B.class file, Java Runtime System will throw NoClassDefFoundError like below:
Exception in thread "main" java.lang.NoClassDefFoundError: A
at MainClass.main(MainClass.java:10)
Caused by: java.lang.ClassNotFoundException: A
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Exception
Hierarchy of Java Exception classes












Unchecked Exception List
ArrayIndexOutOfBoundsException
ClassCastException
IllegalArgumentException
IllegalStateException
IllegalMonitorStateException
NullPointerException
NumberFormatException

IllegalThreadStateException

Error
AssertionError
ExceptionInInitializerError
StackOverflowError
NoClassDefFoundError
VME : Virtual Machine error
OutOf Memory error
Linkage error
Verify Error

Checked Exception List
Exception
IOException
FileNotFoundException
ParseException
ClassNotFoundException
CloneNotSupportedException
InstantiationException
InterruptedException
NoSuchMethodException
NoSuchFieldException
Others :
NotSerializableException’
InvalidClassException

Exception Handling Examples

  • An exception is an event, which occurs during the execution of a program, that interrupts the normal flow of the program. It is an error thrown by a class or method reporting an error in code.
  • The 'Throwable' class is the superclass of all errors and exceptions in the Java language
  • Exceptions are broadly classified as 'checked exceptions' and 'unchecked exceptions'. All RuntimeExceptions and Errors are unchecked exceptions. Rest of the exceptions are called checked exceptions. Checked exceptions should be handled in the code to avoid compile time errors.
  • Exceptions can be handled by using 'try-catch' block. Try block contains the code which is under observation for exceptions. The catch block contains the remedy for the exception. If any exception occurs in the try block then the control jumps to catch block.
  • If a method doesn't handle the exception, then it is mandatory to specify the exception type in the method signature using 'throws' clause.
  • We can explicitly throw an exception using 'throw' clause.
No.
Throw
throws
1)
Java throw keyword is used to explicitly throw an exception.
Java throws keyword is used to declare an exception.
2)
Checked exception cannot be propagated using throw only.
Checked exception can be propagated with throws.
3)
Throw is followed by an instance.
Throws is followed by class.
4)
Throw is used within the method.
Throws is used with the method signature.
5)
You cannot throw multiple exceptions.
You can declare multiple exceptions
e.g. public void method()throws IOException,SQLException.

Java throw example

1.      void m(){  
2.      throw new ArithmeticException("sorry");  
3.      }  

Java throws example

1.      void m()throws ArithmeticException{  
2.      //method code  
3.      }  

Java throw and throws example
1.      void m()throws ArithmeticException{  
2.      throw new ArithmeticException("sorry");  
3.      }  


The Java throw keyword is used to explicitly throw an exception.
We can throw either checked or uncheked exception in java by throw keyword. The throw keyword is mainly used to throw custom exception. We will see custom exceptions later.
The syntax of java throw keyword is given below.
throw exception;  
Let's see the example of throw IOException.
throw new IOException("sorry device error);  
java throw keyword example
In this example, we have created the validate method that takes integer value as a parameter. If the age is less than 18, we are throwing the ArithmeticException otherwise print a message welcome to vote.
public class TestThrow1{  
   static void validate(int age){  
     if(age<18)  
      throw new ArithmeticException("not valid");  
     else  
      System.out.println("welcome to vote");  
   }  
   public static void main(String args[]){  
      validate(13);  
      System.out.println("rest of the code...");  
  }  
}  
Output:
Exception in thread main java.lang.ArithmeticException:not valid
--------------------------------------------------------------------
 
Throw Keyword related Cases: 

After throw statement , we are not allowed to write any statment directly.
Otherwise we will get compile time error saying, "Unreacheable Statement".



if I  e refers NULL then we will get null pointer exception.





Customize    RuntimeException
Create a new runtime exception type called EmptyStackException.
create type is done by
public class EmptyStackException extends RuntimeException { ... }

Now if only we knew what to put in this new type (a.k.a. class). Typically we look at the methods in the superclass and override those needing different handling. Below I have overridden some of them but delegated back to the existing class. No need to do this if you don't need to make any changes in behavior.
public class EmptyStackException extends RuntimeException {
      public EmptyStackException() {
          super();
      }
      public EmptyStackException(String s) {
          super(s);
      }
      public EmptyStackException(String s, Throwable throwable) {
          super(s, throwable);
      }
      public EmptyStackException(Throwable throwable) {
          super(throwable);
      }
    }

Java Custom Exception

If you are creating your own Exception that is known as custom exception or user-defined exception. Java custom exceptions are used to customize the exception according to user need.
By the help of custom exception, you can have your own exception and message.
Let's see a simple example of java custom exception.

1.      class InvalidAgeException extends Exception{  
2.       InvalidAgeException(String s){  
3.        super(s);  
4.       }  
5.      }  
1.      class TestCustomException1{  
2.        
3.         static void validate(int age)throws InvalidAgeException{  
4.           if(age<18)  
5.            throw new InvalidAgeException("not valid");  
6.           else  
7.                        System.out.println("welcome to vote");  
8.         }  
9.           
10.     public static void main(String args[]){  
11.        try{  
12.        validate(13);  
13.        }catch(Exception m){System.out.println("Exception occured: "+m);}  
14.    
15.        System.out.println("rest of the code...");  
16.    }  
17.  }  
Output:Exception occured: InvalidAgeException:not valid
       rest of the code...
 
 
Things to remember while creating Custom Exception in Java

Though creating a custom, exception is as easy as subclassing java.lang.Exception class, there are few best practices you can follow to make most of it. There is so much criticism of checked exception due to boilerplate require to handle it, you will hardly create your custom exception as checked.

1) Don’t' use Exception to control application behavior. Exception handling is very expensive as it requires native calls to copy 
stack trace, each time exception is created.

2) While creating a custom exception, prefer to create an unchecked, Runtime exception than a checked exception, especially if you know that client is not going to take any reactive action other than logging.

3) If your custom exception is created by passing another exception, then always contain original Exception as a source; use constructor which takes Exception rather than only message String.

4) Apart from providing default no argument constructor on your custom Exception class, consider providing at least two more constructors, one which should accept a failure message and other which can accept another Throwable as the cause.

5) If possible, avoid creating custom Exception and re-use existing, standard Exception classes from JDK itself. Most of the time you will realize that all you need is a form of 
IllegalArgumentException or ParseException or something similar.

6) While defining custom Exception, one of the most common mistake programmer make is to think that constructor is inherited from 
java.lang.Exception class, for example, they think that their Exception class will automatically inherit default no argument constructor and the one which takes a String message. This is not true. The constructor is not inherited in Java, not even default constructor. It's actually added by the compiler rather than inherited from parent class. That's why I have declared two constructors, one with String parameter and other as Throwable parameter:

public NoSuchProductException(String message, int productId) {
        super(message);
        this.productId = productId;
    }
 
    public NoSuchProductException(String message, int productId, Throwable cause) {
        super(message, cause);
        this.productId = productId;
    }

This is actually the standard way of creating custom Exception in Java. In order to save time, you can even create a template of above class in Eclipse IDE.



7) For readable code, it's good practice to append the string Exception to the names of all classes that inherits (directly or indirectly) from the Exception class e.g. instead of naming your class IncorrectPassword, name it IncorrectPasswordException.



That's all about How to create custom Exception classes in Java. As I said, first try to avoid the temptation of creating a brand new Exception class, think if you can reuse existing ones. If you absolutely need, then make sure to follow best practices. At the bare minimum, make an effort to create unchecked exception rather than a checked one.

---------------------------------------------------------------------------------------------------------------------------
 
package com.myjava.exceptions;

public class MyOwnException {
    public static void main(String[] a){
        try{
            MyOwnException.myTest(null);
        } catch(MyAppException mae){
            System.out.println("Inside catch block: "+mae.getMessage());
        }
    }
     
    static void myTest(String str) throws MyAppException{
        if(str == null){
            throw new MyAppException("String val is null");
        }
    }
}

class MyAppException extends Exception {

    private String message = null;

    public MyAppException() {
        super();
    }

    public MyAppException(String message) {
        super(message);
        this.message = message;
    }

    public MyAppException(Throwable cause) {
        super(cause);
    }

    @Override
    public String toString() {
        return message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

 

ExceptionHandling with MethodOverriding in Java

There are many rules if we talk about methodoverriding with exception handling. The Rules are as follows:
o    If the superclass method does not declare an exception
o    If the superclass method does not declare an exception, subclass overridden method cannot declare the checked exception but it can declare unchecked exception.
o    If the superclass method declares an exception
o    If the superclass method declares an exception, subclass overridden method can declare same, subclass exception or no exception but cannot declare parent exception.

If the superclass method does not declare an exception

1) Rule: If the superclass method does not declare an exception, subclass overridden method cannot declare the checked exception.

1.      import java.io.*;  
2.      class Parent{  
3.        void msg(){System.out.println("parent");}  
4.      }  
5.        
6.      class TestExceptionChild extends Parent{  
7.        void msg()throws IOException{  
8.          System.out.println("TestExceptionChild");  
9.        }  
10.    public static void main(String args[]){  
11.     Parent p=new TestExceptionChild();  
12.     p.msg();  
13.    }  
14.  }  
Output:Compile Time Error


2) Rule: If the superclass method does not declare an exception, subclass overridden method cannot declare the checked exception but can declare unchecked exception.

1.      import java.io.*;  
2.      class Parent{  
3.        void msg(){System.out.println("parent");}  
4.      }  
5.        
6.      class TestExceptionChild1 extends Parent{  
7.        void msg()throws ArithmeticException{  
8.          System.out.println("child");  
9.        }  
10.    public static void main(String args[]){  
11.     Parent p=new TestExceptionChild1();  
12.     p.msg();  
13.    }  
14.  }  
Output:child


If the superclass method declares an exception

1) Rule: If the superclass method declares an exception, subclass overridden method can declare same, subclass exception or no exception but cannot declare parent exception.

Example in case subclass overridden method declares parent exception

1.      import java.io.*;  
2.      class Parent{  
3.        void msg()throws ArithmeticException{System.out.println("parent");}  
4.      }  
5.        
6.      class TestExceptionChild2 extends Parent{  
7.        void msg()throws Exception{System.out.println("child");}  
8.        
9.        public static void main(String args[]){  
10.     Parent p=new TestExceptionChild2();  
11.     try{  
12.     p.msg();  
13.     }catch(Exception e){}  
14.    }  
15.  }  
Output:Compile Time Error


Example in case subclass overridden method declares same exception
1.      import java.io.*;  
2.      class Parent{  
3.        void msg()throws Exception{System.out.println("parent");}  
4.      }  
5.        
6.      class TestExceptionChild3 extends Parent{  
7.        void msg()throws Exception{System.out.println("child");}  
8.        
9.        public static void main(String args[]){  
10.     Parent p=new TestExceptionChild3();  
11.     try{  
12.     p.msg();  
13.     }catch(Exception e){}  
14.    }  
15.  }  
Output:child


Example in case subclass overridden method declares subclass exception
1.      import java.io.*;  
2.      class Parent{  
3.        void msg()throws Exception{System.out.println("parent");}  
4.      }  
5.        
6.      class TestExceptionChild4 extends Parent{  
7.        void msg()throws ArithmeticException{System.out.println("child");}  
8.        
9.        public static void main(String args[]){  
10.     Parent p=new TestExceptionChild4();  
11.     try{  
12.     p.msg();  
13.     }catch(Exception e){}  
14.    }  
15.  }  
Output:child


Example in case subclass overridden method declares no exception
1.      import java.io.*;  
2.      class Parent{  
3.        void msg()throws Exception{System.out.println("parent");}  
4.      }  
5.        
6.      class TestExceptionChild5 extends Parent{  
7.        void msg(){System.out.println("child");}  
8.        
9.        public static void main(String args[]){  
10.     Parent p=new TestExceptionChild5();  
11.     try{  
12.     p.msg();  
13.     }catch(Exception e){}  
14.    }  
15.  }  
Output:child

-------------------------------------------------------------------------------------------------------------
IllegalThreadStateException


package com.Thread;

public class ThreadTest_Array {

public static void main(String[] args) {

int arr[] = { 1, 2, 3, 4, 5,6,7,8,9,10};
Thread thread_1 = new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < arr.length; i++) {

System.out.println("Element in array : " + arr[i]);
}

}

});

Thread thread_2 = new Thread(new Runnable() {

@Override
public void run() {
int sum = 0;
for (int i = 0; i < arr.length; i++) {

sum = sum + arr[i];

}
System.out.println("Sum of elements in array : " + sum);
}

});

thread_1.start();
thread_1.start();
thread_2.start();
try {
thread_2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
OUTPUT:-

Exception in thread "main" Element in array : 1
Element in array : 2
Element in array : 3
Element in array : 4
Element in array : 5
Element in array : 6
Element in array : 7
Element in array : 8
Element in array : 9
Element in array : 10
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at com.Thread.ThreadTest_Array.main(ThreadTest_Array.java:37)

----------------------------------------------------------------------------------- OutOfMemory Error :


No comments:

Post a Comment