JavaGian java tutorial and java interview question and answer

JavaGian , Free Online Tutorials, JavaGian provides tutorials and interview questions of all technology like java tutorial, android, java frameworks, javascript, ajax, core java, sql, python, php, c language etc. for beginners and professionals.

what is hashmap in java collection tuorial


HashMap in java with examples

HashMap in java is most common Collection which we use nowadays. It stores entry in key-value pair.
1.     HashMap implements Map interface which maps key to value.
2.     It is not synchronized and is not thread safe.
3.     Duplicate keys are not allowed
4.     One null key and multiple null values are allowed

1
2
3
4
5

HashMap<Integer,String> employeeHashmap=new HashMap<Integer,String>();
employeeHashmap.put(1,"Arpit");
employeeHashmap.put(2,"John");

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

package org.arpit.java2blog;

import java.util.HashMap;

public class HashMapBuiltMain {

            public static void main(String[] args) {
                        HashMap<Integer, String> employeeHashmap = new HashMap<Integer, String>();
                        employeeHashmap.put(1, "Arpit");
                        employeeHashmap.put(2, "John");
                        employeeHashmap.put(3, "Martin");
                        employeeHashmap.put(4, "Vaibhav");

                        // Iterating HashMap Using keySet() and for each loop
                        System.out.println("Iterating HashMap Using keySet() and for each loop");
                        System.out.println("-----------------------------");
                        for (Integer empId : employeeHashmap.keySet()) {
                                    System.out.println("EmpId:" + empId + " and  Emp Name:" + employeeHashmap.get(empId));

                        }
                        System.out.println("-----------------------------");
            }
}

When you run above program, you will get below output
1
2
3
4
5
6
7
8
9

Iterating HashMap Using keySet() and for each loop
-----------------------------
EmpId:1 and  Emp Name:Arpit
EmpId:2 and  Emp Name:John
EmpId:3 and  Emp Name:Martin
EmpId:4 and  Emp Name:Vaibhav
-----------------------------

Storing Custom objects as Key:
You can store custom objects as Key in HashMap but you should implement hashcode and equals method, otherwise it may not work as expected.  You may go through hashcode and equal method to understand it better.
Create a class called Country.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

package org.arpit.java2blog;  
public class Country  {  

            String name;  
            long population;  

            public Country(String name, long population) {  
                        super();  
                        this.name = name;  
                        this.population = population;  
            }  
            public String getName() {  
                        return name;  
            }  
            public void setName(String name) {  
                        this.name = name;  
            }  
            public long getPopulation() {  
                        return population;  
            }  
            public void setPopulation(long population) {  
                        this.population = population;  
            }

            @Override
            public int hashCode() {
                        final int prime = 31;
                        int result = 1;
                        result = prime * result + ((name == null) ? 0 : name.hashCode());
                        result = prime * result + (int) (population ^ (population >>> 32));
                        return result;
            }
            @Override
            public boolean equals(Object obj) {
                        if (this == obj)
                                    return true;
                        if (obj == null)
                                    return false;
                        if (getClass() != obj.getClass())
                                    return false;
                        Country other = (Country) obj;
                        if (name == null) {
                                    if (other.name != null)
                                                return false;
                        } else if (!name.equals(other.name))
                                    return false;
                        return true;
            }

}  

Create another class HashMapMain.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

package org.arpit.java2blog;

import java.util.HashMap;

public class HashMapMain {

            public static void main(String args[])
            {
                        // HashMap with Country name as key and capital as value
                        // HashMap stores elements in key value pairs
                        HashMap<String,String> countryCapitalMap=new HashMap<String,String>();
                        countryCapitalMap.put("India","Delhi");
                        countryCapitalMap.put("Japan","Tokyo");
                        countryCapitalMap.put("France","Paris");
                        countryCapitalMap.put("Russia","Moscow");

                        System.out.println("-----------------------------");
                        // Iterating HashMap Using keySet() and for each loop
                        System.out.println("Iterating HashMap Using keySet() and for each loop");
                        for (String countryKey:countryCapitalMap.keySet()) {
                                    System.out.println("Country:"+ countryKey +" and  Capital:"+countryCapitalMap.get(countryKey));

                        }
                        System.out.println("-----------------------------");
            }

}

When you run above program, you will get below output
1
2
3
4
5
6
7
8
9

-----------------------------
Iterating HashMap Using keySet() and for each loop
Country:France and  Capital:Paris
Country:Russia and  Capital:Moscow
Country:Japan and  Capital:Tokyo
Country:India and  Capital:Delhi
-----------------------------

HashMap is not synchronized by default but we can make it synchronized using
1
2
3

Collections.synchronizedMap(new HashMap<String, String>());

How HashMap works in java

Lets take a very simple example. I have a Country class, we are going to use Country class object as key and its capital name(string) as value. Below example will help you to understand, how these key value pair will be stored in hashmap.
1. Country.java 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

package org.arpit.java2blog;
public class Country {

 String name;
 long population;

 public Country(String name, long population) {
  super();
  this.name = name;
  this.population = population;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public long getPopulation() {
  return population;
 }
 public void setPopulation(long population) {
  this.population = population;
 }

 // If length of name in country object is even then return 31(any random number) and if odd then return 95(any random number).
 // This is not a good practice to generate hashcode as below method but I am doing so to give better and easy understanding of hashmap.
 @Override
 public int hashCode() {
  if(this.name.length()%2==0)
   return 31;
  else
   return 95;
 }
 @Override
 public boolean equals(Object obj) {
  
  Country other = (Country) obj;
   if (name.equalsIgnoreCase((other.name)))
   return true;
  return false;
 }
  
}

If you want to understand more about hashcode and equals method of object, you may refer hashcode() and equals() method in java
2. HashMapStructure.java(main class)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

import java.util.HashMap;
import java.util.Iterator;
  
public class HashMapStructure {
  
    /**
     * @author Arpit Mandliya
     */
    public static void main(String[] args) {
          
        Country india=new Country("India",1000);
        Country japan=new Country("Japan",10000);
          
        Country france=new Country("France",2000);
        Country russia=new Country("Russia",20000);
          
       HashMap<Country, String> countryCapitalMap=new HashMap<Country,String>();  
        countryCapitalMap.put(india,"Delhi");  
        countryCapitalMap.put(japan,"Tokyo");  
        countryCapitalMap.put(france,"Paris");  
        countryCapitalMap.put(russia,"Moscow");  
            
        Iterator countryCapitalIter=countryCapitalMap.keySet().iterator();//put debug point at this line  
        while(countryCapitalIter.hasNext())  
        {  
            Country countryObj=countryCapitalIter.next();  
            String capital=countryCapitalMap.get(countryObj);  
            System.out.println(countryObj.getName()+"----"+capital);  
         }  
        }  
  
  
}

Now put debug point at line 24 and right click on project->debug as-> java application. Program will stop execution at line 24 then right click on countryCapitalMap then select watch.You will be able to see structure as below.

Description: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0Sz31T5PyGNyxSqrn_RwnEirBSXLKlvLt9RHwYEUhP8FZcWz5wSNDMGPyEYP-XGCooY4exJd2F2xih-6UKJkQIGaP9Nky5ou9WXD8uBpRwUrFRsZ2N6-WpS-LWHzKCWtKGVVb8geCWV0b/s1600/HashMapStructure1.bmp
Now From above diagram, you can observe following points
1.      
1.     There is an Entry[] array called table which has size 16.
2.     This table stores Entry class’s object. HashMap class has a inner class called Entry.This Entry have key value as instance variable. Lets see structure of entry class Entry Structure.
1
2
3
4
5
6
7
8
9
10

static class Entry implements Map.Entry
{
        final K key;
        V value;
        Entry next;
        final int hash;
        ...//More code goes here
}

1.     Whenever we try to put any key value pair in hashmap, Entry class object is instantiated for key value and that object will be stored in above mentioned Entry[](table). Now you must be wondering, where will above created Enrty object get stored(exact position in table). The answer  is, hash code is calculated for a key by calling Hascode() method. This hashcode is used to calculate index for above Entry[] table.
2.     Now, If you see at array index 10 in above diagram, It has an Entry object named HashMap$Entry.
3.     We have put 4 key-values in hashmap but it seems to have only 2!!!!This is because if two objects have same hashcode, they will be stored at same index. Now question arises how? It stores objects in a form of LinkedList(logically).
So how hashcode of above country key-value pairs are calculated.
1
2
3
4
5
6

Hashcode for Japan = 95 as its length is odd.
Hashcode for India =95 as its length is odd
HashCode for Russia=31 as its length is even.
HashCode for France=31 as its length is even.

Below diagram will explain LinkedList concept clearly.
Description: https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3A-3bIRmP9oQcHtEEsFlll_flqNjzgJz3K2NqQ0Qt2sGZChwQ8EM2QJCMLLQhgMZFsteeWrzX9C1bN7lje1hFdlCacFSRT5p-jTvhbjH4oW4pMWG56L8RSLo6l-gEQyHoH16q9F6RRCLb/s1600/HashMapStructure2.bmp
So now if you have good understanding of hashmap structure,Lets go through put and get method.
Put :
Lets see implementation of put method:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

/**
  * Associates the specified value with the specified key in this map. If the
  * map previously contained a mapping for the key, the old value is
  * replaced.
  *
  * @param key
  *            key with which the specified value is to be associated
  * @param value
  *            value to be associated with the specified key
  * @return the previous value associated with <tt>key</tt>, or <tt>null</tt>
  *         if there was no mapping for <tt>key</tt>. (A <tt>null</tt> return
  *         can also indicate that the map previously associated
  *         <tt>null</tt> with <tt>key</tt>.)
  */
 public V put(K key, V value) {
  if (key == null)
   return putForNullKey(value);
  int hash = hash(key.hashCode());
  int i = indexFor(hash, table.length);
  for (Entry e = table[i]; e != null; e = e.next) {
   Object k;
   if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
    V oldValue = e.value;
    e.value = value;
    e.recordAccess(this);
    return oldValue;
   }
  }

  modCount++;
  addEntry(hash, key, value, i);
  return null;
 }

now lets understand above code step by step
1.     Key object is checked for null. If key is null then it will be stored at table[0] because hashcode for null is always 0.
2.     Key object’s hashcode() method is called and hash code is calculated. This hashcode is used to find index of array for storing Entry object. It may happen sometimes that, this hashcode function is poorly written so JDK designer has put another function called hash() which takes above calculated hash value as argument.If you want to learn more about hash() function, you can refer hash and indexFor method in hashmap.
3.     indexFor(hash,table.length)  is used to calculate exact index in table array for storing the Entry object.
4.     As we have seen in our example, if two key objects have same hashcode(which is known as collision) then it will be stored in form of linkedlist.So here, we will iterate through our linkedlist.
§  If there is no element present at that index which we have just calculated then it will directly put our Entry object at that index.
§  If There is element present at that index then it will iterate until it gets Entry->next as null.Then current Entry object become next node in that linkedlist
§  What if we are putting same key again, logically it should replace old value. Yes,it will do that.While iterating it will check key equality by calling equals() method(key.equals(k)), if this method returns true then it replaces value object with current Entry’s value object.
 Get:
 Lets see implementation of get now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

/**
  * Returns the value to which the specified key is mapped, or {@code null}
  * if this map contains no mapping for the key.
  *
  *
* More formally, if this map contains a mapping from a key {@code k} to a
* value {@code v} such that {@code (key==null ? k==null :
* key.equals(k))}, then this method returns {@code v}; otherwise it returns
* {@code null}. (There can be at most one such mapping.)
*
*
* A return value of {@code null} does not <i>necessarily</i> indicate that
* the map contains no mapping for the key; it's also possible that the map
* explicitly maps the key to {@code null}. The {@link #containsKey
* containsKey} operation may be used to distinguish these two cases.
*
* @see #put(Object, Object)
*/
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}

As you got the understanding on put functionality of hashmap. So to understand get functionality is quite simple. If you pass any key to get value object from hashmap.
1.     Key object is checked for null. If key is null then value of Object resides at table[0] will be returned.
2.     Key object’s hashcode() method is called and hash code is calculated.
3.     indexFor(hash,table.length)  is used to calculate exact index in table array using generated hashcode for getting the Entry object.
4.     After getting index in table array, it will iterate through linkedlist and check for key equality by calling equals() method and if it returns true then it returns the value of Entry object else returns null.
Key points to Remeber:
§  HashMap has a inner class called Entry which stores key-value pairs.
§  Above Entry object is stored in Entry[ ](Array) called table
§  An index of table is logically known as bucket and it stores first element of linkedlist
§  Key object’s hashcode() is used to find bucket of that Entry object.
§  If two key object ‘s have same hashcode , they will go in same bucket of table array.
§  Key object ‘s equals() method is used to ensure uniqueness of key object.
§  Value object  ‘s equals() and hashcode() method is not used at all


hash and indexFor method in HashMap


we will see how hash and indexFor method works internally in hashmap. hash and indexFor methods belong to HashMap class. Why JDK developers need to have another hash function when  key object’s have there own hashcode method.
Lets see code for hash and indexFor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

/**
 * Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 */
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

/**
 * Returns index for hash code h.
 */
static int indexFor(int h, int length) {
    return h & (length-1);
}

As java doc says about hash:
Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because HashMap uses power-of-two length hash tables, that otherwise encounter collisions for 
hashCodes that do not differ in lower bits. Note: Null keys always map to hash 0, thus index 0.
Lets understand this with the help of example: Lets say key object’s hashcode() returns only 3 values 31,63 and 95. 31,63 and 95 are integers, so all are 32 bits.
31=00000000000000000000000000011111
63=00000000000000000000000000111111
95=00000000000000000000000001011111
Now lets say our hashmap’s lenth is 16(2^4, Hashmap’s length will be always in power of two)
What if we do not use hash function:
Now if we do not use hash function then
indexFor will return :
31=00000000000000000000000000011111 => 1111=15
63=00000000000000000000000000111111  => 1111=15
95=00000000000000000000000001011111 => 1111=15
Why so?
because when we call indexFor function.It will do AND between 31&15 , 63&15 and 95&15.
For ex. 95&15
00000000000000000000000001011111 &00000000000000000000000000001111
so (2^n-1) will always have sequence of 1’s in it.so what matters here it 
last n bits as 0&1 is always 0.
In above example, all have 1111 in end that is why they are returning same index.
so although we have different hashcode,each Entry object will be stored at 15 index only.
What if we  use hash function:
If we use hash function then :
On each hashcode, first hash will  be applied.
31=00000000000000000000000000011111 => 00000000000000000000000000011110
63=00000000000000000000000000111111  => 00000000000000000000000000111100
95=00000000000000000000000001011111 => 00000000000000000000000001011010
now after passing new hash to indexFor.It will return :
00000000000000000000000000011110 =>1110=14
00000000000000000000000000111100 =>1100=12
00000000000000000000000001011010 =>1010=10
After applying hash function, above hashcodes are returning different index so hash function is redistributing elements in hashmap thus less collisions and better performance.
The main purpose of hash operation is to make the hashcode differences visible in the least significant bits so that the hashmap elements can be distributed evenly across the buckets
Note:
§  If two key objects have same hashcode, then they will always go to same index in table array
§  If two key objects do not have same hashcode then they may or may not go to same index in table array.









hashcode() and equals() method in java


These methods can be found in the Object class and hence available to all java classes.Using these two methods, an object can be stored or retrieved from a Hashtable, HashMap or HashSet.
§  hashcode()
§  equals()
hashcode() and equals() method
hashcode():
You might know if you put entry in HashMap, first hashcode is calculated and this hashcode used to find bucket(index) where this entry will get stored in hashMap.You can read more at How hashMap works in java. What if you don’t override hashcode method, it will  return integer representation of memory address.
equals():
You have to override equals method, when you want to define equality between two object. If you don’t override this method, it will check for reference equality(==) i.e. if tow reference refers to same object or not

Lets override default implemenation of hashcode() and equals():
You don’t have to always override these methods, but lets say you want to define equality of country object based on name, then you need to override equals method and if you are overriding equals method, you should override hashcode method too. Below example will make it clear.
Lets see with the help of example.We have a class called Country

1. Country.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

package org.arpit.java2blog;

public class Country {

    String name;
    long population;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public long getPopulation() {
        return population;
    }
    public void setPopulation(long population) {
        this.population = population;
    }
   
}

This country class have two basic attributes- name and population.
Now create a class called “EqualityCheckMain.java”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

package org.arpit.java2blog;

public class EqualityCheckMain {

    /**
     * @author arpit mandliya
     */
    public static void main(String[] args) {
       
        Country india1=new Country();
        india1.setName("India");
        Country india2=new Country();
        india2.setName("India");
        System.out.println("Is india1 is equal to india2:" +india1.equals(india2));
    }

}

When you run above program, you will get following output
1
2
3

Is india1 is equal to india2:false

In above program, we have created two different objects and set their name attribute to “india”.
Because both references india1 and india2 are pointing to different object, as default implementation of equals check for ==,equals method is returning false. In real life, it should have return true because no two countries can have same name.
Now lets override equals and return true if two country’s name are same.
Add this method to above country class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Country other = (Country) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

and now run EqualityCheckMain.java again
You will get following output:
1
2
3

Is india1 is equal to india2:true

Now this is because overriden equals method return true if two country have same name.
One thing to remember here, signature of equals method should be same as above.
Lets put this Country objects in hashmap:
Here we are going to use Country class object as key and its capital name(string) as value in HashMap.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

package org.arpit.java2blog;

import java.util.HashMap;
import java.util.Iterator;

public class HashMapEqualityCheckMain {

    /**
     * @author Arpit Mandliya
     */
    public static void main(String[] args) {
        HashMap<Country,String> countryCapitalMap=new HashMap<Country,String>();
        Country india1=new Country();
        india1.setName("India");
        Country india2=new Country();
        india2.setName("India");

        countryCapitalMap.put(india1, "Delhi");
        countryCapitalMap.put(india2, "Delhi");

        Iterator countryCapitalIter=countryCapitalMap.keySet().iterator();
        while(countryCapitalIter.hasNext())
        {
            Country countryObj=countryCapitalIter.next();
            String capital=countryCapitalMap.get(countryObj);
            System.out.println("Capital of "+ countryObj.getName()+"----"+capital);

        }
    }
}

When you run above program, you will see following output:
1
2
3
4

Capital of India----Delhi
Capital of India----Delhi

Now you must be wondering even through two objects are equal why HashMap contains two key value pair instead of one.This is because First HashMap uses hashcode to find bucket for that key object, if hashcodes are same then only it checks for equals method and because hashcode for above two country objects uses default hashcode method,Both will have different memory address hence different hashcode.
Now lets override hashcode method.Add following method to Country class
1
2
3
4
5
6
7
8
9

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

Now run HashMapEqualityCheckMain.java again
You will see following output:
1
2
3

Capital of India----Delhi

So now hashcode for above two objects india1 and india2 are same, so Both will be point to same bucket,now equals method will be used to compare them which  will return true.
This is the reason java doc says “if you override equals() method then you must override hashCode() method”
hashcode() and equals() contracts:
equals():
The equals method implements an equivalence relation on non-null object references:
§  It is reflexive: for any non-null reference value x, x.equals(x) should return true.
§  It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
§  It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
§  It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
§  For any non-null reference value x, x.equals(null) should return false.
hashcode():
§  Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
§  If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
§  It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Key points to remember:
1.     If you are overriding equals method then you should override hashcode() also.
2.     If two objects are equal then they must have same hashcode.
3.     If two objects have same hashcode then they may or may not be equal
4.     Always use same attributes to generate equals and hashcode as in our case we have used name.


How to sort HashMap in java by keys and values


Sorting by Keys:
Sorting by keys can be easily done using TreeMap. You just need to pass HashMap to the constructor of TreeMap.
1
2
3

TreeMap map=new TreeMap(Map hm);

Sorting by values:
We can use Comparator to sort it by values.
Sorting by Keys example :
Create Country.java as below. It should implement Comparable interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

package org.arpit.java2blog;  
public class Country implements Comparable {  
  
 String name;  
 long population;  
  
 public Country(String name, long population) {  
  super();  
  this.name = name;  
  this.population = population;  
 }  
 public String getName() {  
  return name;  
 }  
 public void setName(String name) {  
  this.name = name;  
 }  
 public long getPopulation() {  
  return population;  
 }  
 public void setPopulation(long population) {  
  this.population = population;  
 }
@Override
public int compareTo(Object o) {
    Country country=(Country) o;
 return this.getName().compareTo(country.getName());
}  
      
}  

Create TreeMapCompMain.java as below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

package org.arpit.java2blog;

import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeMap;

public class TreeMapCompMain {

 public static void main(String[] args)
 {
  Country india=new Country("India",1000);  
        Country japan=new Country("Japan",10000);  
            
        Country france=new Country("France",2000);  
        Country russia=new Country("Russia",20000);  
            
        HashMap<Country, String> countryCapitalMap=new HashMap<Country,String>();  
        countryCapitalMap.put(india,"Delhi");  
        countryCapitalMap.put(japan,"Tokyo");  
        countryCapitalMap.put(france,"Paris");  
        countryCapitalMap.put(russia,"Moscow");  
        
        System.out.println("Sorting HashMap by passing it to TreeMap constructor");
        TreeMap<Country,String> sortedTreeMapCountryCapital=new  TreeMap<Country,String> (countryCapitalMap);
        Iterator countryCapitalIter=sortedTreeMapCountryCapital.keySet().iterator();//put debug point at this line  
        while(countryCapitalIter.hasNext())  
        {  
            Country countryObj=countryCapitalIter.next();  
            String capital=countryCapitalMap.get(countryObj);  
            System.out.println(countryObj.getName()+"----"+capital);  
            }  
        }  

}

When you run program, you will get below output:
1
2
3
4
5
6
7

Sorting HashMap by passing it to TreeMap constructor
France----Paris
India----Delhi
Japan----Tokyo
Russia----Moscow

Sorting by values example:
Here we will sort HashMap by its values. Here I am taking HashMap to make example simpler.
Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

package org.arpit.java2blog;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

public class HashMapMain {

 public static void main(String args[]) {
  // HashMap with Country name as key and capital as value
  // HashMap stores elements in key value pairs
  HashMap<String, String> countryCapitalMap = new HashMap<String, String>();

  countryCapitalMap.put("Japan", "Tokyo");
  countryCapitalMap.put("France", "Paris");
  countryCapitalMap.put("Russia", "Moscow");
  countryCapitalMap.put("India", "Delhi");

  System.out.println("-----------------------------");
  // Iterating HashMap Using keySet() and for each loop
  System.out.println("Before Sorting");
  System.out.println("-----------------------------");
  for (String countryKey : countryCapitalMap.keySet()) {
   System.out.println("Country:" + countryKey + " and  Capital:" + countryCapitalMap.get(countryKey));

  }
  
  Set<Entry<String, String>> countryCapitalEntrySet=countryCapitalMap.entrySet();
  
  List<Entry<String, String>> entryList=new ArrayList<Entry<String, String>>(countryCapitalEntrySet);
  
  Collections.sort(entryList,new Comparator<Entry<String,String>>() {

   @Override
   public int compare(Entry<String,String> o1, Entry<String,String> o2) {
    return o1.getValue().compareTo(o2.getValue());
   }
  });
  System.out.println("-----------------------------");
    
  // Using LinkedHashMop to keep entries in sorted order
  LinkedHashMap<String,String> sortedHashMap=new LinkedHashMap<String,String>();
  for (Entry<String,String> entry:entryList) {
   sortedHashMap.put(entry.getKey(), entry.getValue());
  }
  
  System.out.println("After Sorting");
  System.out.println("-----------------------------");
  // Iterating sortedHashMap Using keySet() and for each loop
  
  for (String countryKey : sortedHashMap.keySet()) {
   System.out.println("Country:" + countryKey + " and  Capital:" + sortedHashMap.get(countryKey));

  }
 }
}

When you run above program, you will get below output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

-----------------------------
Before Sorting
-----------------------------
Country:France and  Capital:Paris
Country:Russia and  Capital:Moscow
Country:Japan and  Capital:Tokyo
Country:India and  Capital:Delhi
-----------------------------
After Sorting
-----------------------------
Country:India and  Capital:Delhi
Country:Russia and  Capital:Moscow
Country:France and  Capital:Paris
Country:Japan and  Capital:Tokyo

Explanation:
1.     Extract key set from HashMap using keySet() method.
2.     Create ArrayList from above set
3.     Sort above ArrayList using Comparator
4.     Create LinkedHashMap from Sorted list

Difference between HashMap and HashSet in java


HashMap

HashMap implements Map interface which maps key to value.It is not synchronized and is not thread safe.Duplicate keys are not allowed and null keys as well as values are allowed. For more details, you can also read How HashMap works in java.
1
2
3
4
5

HashMap<Interger,String> employeeHashmap=new HashMap<Integer,String>();
employeeHashmap.put(1,"Arpit");
employeeHashmap.put(2,"John");

HashSet

HashSet implements Set interface which does not allow duplicate value.It is not synchronized and is not thread safe.For more details, you can also read How HashSet works in java.
1
2
3
4
5
6

HashSet employeeSet=new HashSet();
employeeSet.add("Arpit");
employeeSet.add("Arpit");
employeeSet.add("john");

Above employeeSet will have 2 elements in it as Set does not allow duplicate values.
add method is used to add element to HashSet.If It return true then element is added successfully but if it return false then you are trying to insert duplicate value.
1
2
3

public boolean add(Object o)

One main thing about HashSet is objects which we are going to add in HashSet must implement Hashcode() and equals() method so that we can check for duplicate values.If we are adding custom objects to HashSet then we must override() Hashcode() and equals() method according to our need.If we do not override then object will take default implementation which may not desirable.

HashMap vs HashSet:

Parameter
HashMap
HashSet
Interface
This is core difference among them.HashMap implements Map interface
HashSet implement Set interface
Method for storing data
It stores data in a form of key->value pair.So it uses put(key,value) method for storing data
It uses add(value) method for storing data
Duplicates
HashMap allows duplicate value but not duplicate keys
HashSet does not allow duplicate values.
Performance
It is faster than hashset as values are stored with unique keys
It is slower than HashMap
HashCode Calculation
In hash map hashcode value is calculated using key object
In this,hashcode is calculated on the basis of value object.Hashcode can be same for two value object so we have to implement equals() method.If equals() method return false then two objects are different.


Difference between Hashtable and HashMap in java


HashMap
HashMap implements Map interface which maps key to value.It is not synchronized and is not thread safe.Duplicate keys are not allowed and null keys as well as value are allowed.
1
2
3
4
5

HashMap<Interger,String> employeeHashmap=new HashMap<Integer,String>();
employeeHashmap.put(1,"Arpit");
employeeHashmap.put(2,null);  // will work fine

Hashtable
Hashtable implements Map interface which maps key to value.It is synchronized and thread safe.Duplicate keys are not allowed and null key is not allowed.
1
2
3
4
5

Hashtable<Interger,String> employeeHashmap=new Hashtable<Integer,String>();
employeeHashmap.put(1,"Arpit");
employeeHashmap.put(2,null);  //not allowed and will throw NullPointer exception at run time

Hashtable vs HashMap:
Parameter
Hashtable
HashMap
ThreadSafe
Yes
No
Synchronized
Yes
No
Performance
Due to theadSafe and Synchronized,it is often slower than HashMap
In single threaded environment, it is much faster than Hashtable.So if you do not work in multi thread environment ,then hashMap is recommended
Null key
Do not allow
Allows null key as well as values
Fail fast
enumeration in hashtable is not fail fast
Iterator in hashMap is fail fast
Extends
It extends Dictionary class which is quite old
It extends AbstractMap class
Alternative
No alternative
You can use ConcurrentHashMap for multi thread environment
Some important points need to be discussed.
§  Synchonized meaning only one thread can modify one table  at one point of time.When any thread perform update operation on hashtable then it acquires lock on it and other threads have to wait for lock to be released.
§  Fail-fast iterator means if one thread is iterating over hashmap and other thread trying to modify hashmap structurally it will throw ConcurrentModification Exception and fail immediately.Structurally modification means inserting or deleting elements that can change structure of map.
Can we synchronize HashMap?
Yes,We can synchonized a HashMap also with the help of Collections.synchonizedMap(hashmap) so HashMap can be synchronized by
1
2
3

Map map=Collections.synchonizedMap(hashmap)


How to iterate over Map or HashMap in java


1.     Using keyset() and for each loop(Java 5)
2.     Using keyset() and java Iterator
3.     Using EntrySet() and for each loop(Java 5)
4.     Using EntrySet() and java Iterator
if you remove elements while iterating , then 1st and 3rd option  will throw java.util.ConcurrentModificationException.
If you understand internal working of HashMap, then it may be easier for you to iterate an HashMap
Lets take an example:
1. IterateMapMain.java 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

package org.arpit.java2blog;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

public class IterateMapMain {

                public static void main(String args[])
                {
                                // HashMap with Country as key and capital as value
                                HashMap<String,String> countryCapitalMap=new HashMap<String,String>();
                                countryCapitalMap.put("India","Delhi");
                                countryCapitalMap.put("Japan","Tokyo");
                                countryCapitalMap.put("France","Paris");
                                countryCapitalMap.put("Russia","Moscow");

                                // Iterating Using keySet() and for each loop
                                System.out.println("Iterating Using keySet() and for each loop");
                                for (String countryKey:countryCapitalMap.keySet()) {
                                                System.out.println("Country:"+ countryKey +" and  Capital:"+countryCapitalMap.get(countryKey));

                                }
                                System.out.println("-----------------------------");

                                // Iterating Using keySet() and java iterator
                                System.out.println("Iterating Using keySet() and java Iterator");
                                Iterator countryKeySetIterator=countryCapitalMap.keySet().iterator();
                                while(countryKeySetIterator.hasNext()){
                                                String countryKey=countryKeySetIterator.next();
                                                System.out.println("Country:"+ countryKey +" and Capital:"+countryCapitalMap.get(countryKey));

                                }
                                System.out.println("-----------------------------");

                                // Iterating Using entrySet() and for each loop
                                System.out.println("Iterating Using entrySet() and for each loop");
                                for (Entry<String,String> entry:countryCapitalMap.entrySet()) {
                                                System.out.println("Country:"+ entry.getKey() +" and  Capital:"+entry.getValue());

                                }
                                System.out.println("-----------------------------");

                                // Iterating Using entrySet() and java iterator
                                System.out.println("Iterating Using entrySet() and and java Iterator");
                                Iterator<Entry<String,String>> entryIterator=countryCapitalMap.entrySet().iterator();
                                while(entryIterator.hasNext())
                                {
                                                Entry<String,String> entry=entryIterator.next();
                                                System.out.println("Country:"+ entry.getKey() +" and  Capital:"+entry.getValue());

                                }
                                System.out.println("-----------------------------");

                }

}

Run it and you will get following output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Iterating Using keySet() and for each loop
Country:France and  Capital:Paris
Country:Russia and  Capital:Moscow
Country:Japan and  Capital:Tokyo
Country:India and  Capital:Delhi
-----------------------------
Iterating Using keySet() and java Iterator
Country:France and Capital:Paris
Country:Russia and Capital:Moscow
Country:Japan and Capital:Tokyo
Country:India and Capital:Delhi
-----------------------------
Iterating Using entrySet() and for each loop
Country:France and  Capital:Paris
Country:Russia and  Capital:Moscow
Country:Japan and  Capital:Tokyo
Country:India and  Capital:Delhi
-----------------------------
Iterating Using entrySet() and and java Iterator
Country:France and  Capital:Paris
Country:Russia and  Capital:Moscow
Country:Japan and  Capital:Tokyo
Country:India and  Capital:Delhi
-----------------------------




.