Tag Archives: java.util.HashMap

Java: How HashSet Work?


A Set interface represents a group of unique elements arranged like an array. When we try to pass the duplicate element that is already available in the Set, then it will not store into the Set.

HashSet class

HashSet class implemnets Set interface and extends AbstractSet class.A HashSet class uses Hash Map internally for storing elements by using hashing technique.HashSet store unique elements and does not guarantee the order of elements.

Suppose, you want to create a HashSet to store a group of Strings, then create the HashSet object as:


HashSet hs=new HashSet();  

Where is the generic type parameter to represent HashSet allows only String type objects.

HashSet default constructor create instance of initial capacity 16 and capacity may increase automatically when number of elements reach to load factors. For uniqueness of object generate key as hashcode value. HashSet class doesn’t have method to retrieve object of Instance only way is retrieve object by iteration.

Note: To set your own capacity and loadfactor for HashSet. you can use below constructor.


HashSet hs=new HashSet(int capacity, float loadfactor);  

Here, loadfactor determines when number of elements in HashSet reach to that capacity limit increase capacity internally.the point where the capacity of HashSet would be increased internally.
The initial default capacity of HashSet is 16. The default load factor is 0.75. then 16*0.75=12 when no of elements reach to 12 increase capacity of HashSet to store more elements.

Example HashSet:

import java.util.HashSet;
import java.util.Iterator;

public class HashSetExample1 {
	public static void main(String[] args) {
      HashSet countries=new HashSet();
      countries.add("India");
      countries.add("Pakistan");
      countries.add("China");
      countries.add("Nepal");
      countries.add("Afganistan");
      countries.add("Canada");
      countries.add("Brazil");
      countries.add("Canada");
      countries.add("Brazil");
      countries.add("Thailand");
      countries.add("Malasia");
      countries.add("Russia");
      countries.add("London");
      countries.add("Switzerand");
      //Till that point threshold/capacity value is 12
      System.out.println("Countries Name:"+countries);
      System.out.println("Total Countries:"+countries.size());
      //Duplicate elements not allowed
      System.out.println("Add Dubai:"+countries.add("Dubai"));
      System.out.println("Add Dubai :"+countries.add("Dubai"));//return false when duplicate
      //After adding 13th element Threshold/capacity reach to 24 just double
      System.out.println("Countries Name:"+countries);
      System.out.println("Total Countries:"+countries.size());

     //iteration of Hashset elements
      System.out.println("\n\nPrint Countries by for each:");
      for(String country:countries)
      {
    	 System.out.println(country);
      }

      System.out.println("\n\nPrint Countries by for iterator:");
      Iterator it=countries.iterator();
      while(it.hasNext())
      {
    	  System.out.println(it.next());
      }

	}
}

Output


Countries Name:[Canada, Pakistan, China, Malasia, Brazil, London, Afganistan, Thailand, Nepal, Switzerand, India, Russia]
Total Countries:12
Add Dubai:true
Add Dubai :false
Countries Name:[Malasia, Thailand, Dubai, India, Russia, Canada, Pakistan, China, Brazil, London, Afganistan, Nepal, Switzerand]
Total Countries:13


Print Countries by for each:
Malasia
Thailand
Dubai
India
Russia
Canada
Pakistan
China
Brazil
London
Afganistan
Nepal
Switzerand


Print Countries by for iterator:
Malasia
Thailand
Dubai
India
Russia
Canada
Pakistan
China
Brazil
London
Afganistan
Nepal
Switzerand

In this example we have added duplicate values as Dubai in HashSet. When added it first time by add method return true because Dubai was not in HashSet. When added again return false because it was already added.

How HashSet work?

Now question comes how HashSet, add() method returns true and false. When you will open HashSet implementation of the add() method in Java APIs i.e. rt.jar, you will see the following code in it:

public class HashSet&ltE> extends AbstractSet
{
private transient HashMap map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public HashSet()
{
map = new HashMap();
}
public boolean add(E e)
{
return map.put(e, PRESENT)==null;
}
}

In this HashSet, add(object) methods use HashMap delegated to put(key, value) internally. Where key is the object added on HashSet and value is constant object as PRESENT in java.util.HashSet.

When we create HashSet Object, internally create an object of HashMap. As we know in HashMap each key is unique so, When we call add(E e) method this passing object set as key of HashMap and dummy object (new Object()) which is referred by Object reference PRESENT pass as value.

In HashMap put(key, value):

  • If the Key is unique and added then it will return null
    If the Key is duplicate, then map will return the old value of the key.

Let consider above example, when add country as countries.add(“Dubai”), java internally call HashMap put(“Dubai”,PRESENT) method to add element in map.

public boolean add(E e)
{
return map.put(e, PRESENT==null);
}

If the method map.put(key, value) returns null, then the method map.put(e, PRESENT)==null will return true internally, and the element added to the HashSet.
If the method map.put(key, value) returns the old value of the key, then the method map.put(e, PRESENT)==null will return false internally, and the element will not add to the HashSet.

As per given implementation when country “Dubai” added first time put() method return as null because “Dubai” not added before (unique) then add method return true. But when “Dubai” added again put() method will return old object and add method will return false on that case because of duplicate.

Retrieving Object from the HashSet

We use iterator() method of HashSet to retrieve objects. Internally HashSet iterator method called map.keySet().iterator() method.

public Iterator iterator()
{
return map.keySet().iterator();
}

Java: HashMap Class Methods and Examples


java.util.HashMap class inherits AbstractMap class and implements the Map interface. HashMap values store on the basis of key and value pair where each pair is known as an Entry.

  • K: It’s the type of Key in HashMap
  • V: It’s a type of value with respect to Key.

HashMap Class Declaration


public class HashMap extends implements Map, Cloneable, Serializable  

See Also:

Points to Remember:

  • HashMap uses data structure as a Hash Table.
  • HashMap store values based on keys.
  • HashMap contains unique keys.
  • HashMap allows duplicate values.
  • HashMap doesn’t maintain order.
  • HashMap class allows only one null key and multiple null values.
  • HashMap is not synchronized.
  • HashMap initial default capacity is 16 elements with a load factor of 0.75.

HashMap Representataion

Difference between HashSet and HashMap

HashSet Class contains only values whereas HashMap Class contains an entry (key and value pair).

HashMap Class Constructors

Constructor Description
HashMap() It is used to construct a default HashMap.
HashMap(Map m) It is used to initialize the hash map by using the elements of the given Map object m.
HashMap(int capacity) It is used to initializes the capacity of the hash map to the given integer value, capacity.
HashMap(int capacity, float loadFactor) It is used to initialize both the capacity and load factor of the hash map by using its arguments.

HashMap Class Methods

Method Description
void clear() Use to remove all of the mappings from this map.
boolean isEmpty() Use to return true if this map contains no key-value mappings.
Object clone() Use to return a shallow copy of this HashMap instance: the keys and values themselves are not cloned.
Set entrySet() Use to return a collection view of the mappings contained in this map.
Set keySet() Use to return a set view of the keys contained in this map.
V put(Object key, Object value) Use to insert an entry in the map.
void putAll(Map map) Use to insert the specified map in the map.
V putIfAbsent(K key, V value) It inserts the specified value in the map only when  specified key is not already specified.
V remove(Object key) Use to delete an entry for the specified key.
boolean remove(Object key, Object value) removes the  values with the associated specified keys from the map.
V compute(K key, BiFunction remappingFunction) Use to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).
V computeIfAbsent(K key, Function mappingFunction) Use to compute its value using the given mapping function, if the specified key is not mapped with a value or null, and enters it into this map unless null.
V computeIfPresent(K key, BiFunction remappingFunction) Use to compute a new mapping given the key and its current mapped value if the value for the specified key is present and non-null.
boolean containsValue(Object value) It returns true if some value equal to the value exists within the map, else return false.
boolean containsKey(Object key) It returns true if some key equal to the key exists within the map, else return false.
boolean equals(Object o) Use to compare the specified Object with the Map.
void forEach(BiConsumer action) Added in Java 8 to  performs the given action for each entry in the map  or the action throws an exception.
V get(Object key) This method returns the object that contains the value associated with respect to key.
V getOrDefault(Object key, V defaultValue) Added in Java 8. It returns the value to which the specified key is mapped, or defaultValue if the map contains no mapping for the key.
boolean isEmpty() It returns true if the map is empty; returns false if it contains at least one key.
V merge(K key, V value, BiFunction remappingFunction) If the specified key is not already associated with a value or is associated with null then associates it with the given non-null value.
V replace(K key, V value) It replaces the specified value with respect to specified key.
boolean replace(K key, V oldValue, V newValue) Replaces the old value with the new value with respect to specified key.
void replaceAll(BiFunction function) It replaces each entry’s value with entry until all entries have been processed or the function throws an exception.
Collection values() It returns a collection of the values contained in the map.
int size() It returns the count of number of entries in the map.

Example: add elements

Here, you will learn different ways to insert elements.

import java.util.*;

class HashMapExample1 {
	public static void main(String args[]) {
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		System.out.println("Initial hash map elements: " + hm );
		hm.put(20, "Anuj");
		hm.put(21, "Virendra");
		hm.put(22, "Raghav");

		System.out.println("\nAfter invoking put() method");
		for (Map.Entry m : hm.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}

		hm.putIfAbsent(23, "Gaurav");
		System.out.println("\nAfter invoking putIfAbsent() method");
		for (Map.Entry m : hm.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}
		HashMap map = new HashMap();
		map.put(24, "Ravi");
		map.putAll(hm);
		System.out.println("\nAfter invoking putAll() method ");
		for (Map.Entry m : map.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}
	}
}

Output :


Initial hash map elements: {}

After invoking put() method
20 Anuj
21 Virendra
22 Raghav

After invoking putIfAbsent() method
20 Anuj
21 Virendra
22 Raghav
23 Gaurav

After invoking putAll() method 
20 Anuj
21 Virendra
22 Raghav
23 Gaurav
24 Ravi

HashMap Example : remove()

Here you will see different ways to remove elements from HashMap

import java.util.*;
import java.util.HashMap;

public class HashMapExample2 {
	public static void main(String args[]) {
		HashMap<Integer,String> map = new HashMap<Integer,String>();
map.put(20, "Anuj");
		map.put(21, "Virendra");
		map.put(22, "Raghav");
		map.put(23, "Gaurav");
		System.out.println("Initial hash map elements: " + map);
		// key-based removal
		map.remove(20);
		System.out.println("\nUpdated hash map  elements: " + map);
		// value-based removal
		map.remove(21);
		System.out.println("\nUpdated hash map  elements: " + map);
		// key-value pair based removal
		map.remove(22, "Raghav");
		System.out.println("\nUpdated hash map  elements: " + map);
	}
}

Output :


Initial hash map elements: {20=Anuj, 21=Virendra, 22=Raghav, 23=Gaurav}

Updated hash map  elements: {21=Virendra, 22=Raghav, 23=Gaurav}

Updated hash map  elements: {22=Raghav, 23=Gaurav}

Updated hash map  elements: {23=Gaurav}

HashMap Example : replace()

Here you will see different ways to replace() elements in HashMap

import java.util.*;

class HashMapExample3 {
	public static void main(String args[]) {
		HashMap<Integer,String> hm = new HashMap<Integer,String>();
		hm.put(20, "Anuj");
		hm.put(21, "Virendra");
		hm.put(22, "Raghav");
		System.out.println("Initial hash map elements:");
		for (Map.Entry m : hm.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}
		System.out.println("\nUpdated hash map elements:");
		hm.replace(22, "Gaurav");
		for (Map.Entry m : hm.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}
		System.out.println("\nUpdated hash map elements:");
		hm.replace(21, "Virendra", "Ravi");
		for (Map.Entry m : hm.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}
		System.out.println("\nUpdated hash map elements:");
		hm.replaceAll((k, v) -> "Anuj");
		for (Map.Entry m : hm.entrySet()) {
			System.out.println(m.getKey() + " " + m.getValue());
		}
	}
}

Output :


Initial hash map elements:
20 Anuj
21 Virendra
22 Raghav

Updated hash map elements:
20 Anuj
21 Virendra
22 Gaurav

Updated hash map elements:
20 Anuj
21 Ravi
22 Gaurav

Updated hash map elements:
20 Anuj
21 Anuj
22 Anuj

HashMap Example: Objects handling

import java.util.*;
public class Magzine {
	int id;
	String name,author,publisher;
	int quantity;
	public Magzine(int id, String name, String author, String publisher, int quantity) {
	    this.id = id;
	    this.name = name;
	    this.author = author;
	    this.publisher = publisher;
	    this.quantity = quantity;
	}    

}
public class MapExample {
import java.util.HashMap;
import java.util.Map;

public class HashMapWithObjectsExample {

	public static void main(String[] args) {
	    //Creating map of Magzines
	    Map<Integer,Magzine> map=new HashMap<Integer,Magzine>();
	    //Creating Books
	    Magzine m1=new Magzine(21,"The Sun","Sy Sunfranchy","The Sun Company",8);
	    Magzine m2=new Magzine(22,"Glimmer Trains","Unknown","Glimmer Train Press",4);
	    Magzine m3=new Magzine(23,"Crazy horse","Brett Lot","College of Charleston",6);
	    //Adding Magzines to map
	    map.put(1,m1);
	    map.put(2,m2);
	    map.put(3,m3);  

	    //Traversing map
	    for(Map.Entry<Integer,Magzine> entry:map.entrySet()){
	        int key=entry.getKey();
	        Magzine m=entry.getValue();
	        System.out.println("\nMagzine "+key+" Details:");
	        System.out.println(m.id+" "+m.name+" "+m.author+" "+m.publisher+" "+m.quantity);
	    }
	}
}

Output :



Magzine 1 Details:
21 The Sun Sy Sunfranchy The Sun Company 8

Magzine 2 Details:
22 Glimmer Trains Unknown Glimmer Train Press 4

Magzine 3 Details:
23 Crazy horse Brett Lot College of Charleston 6

References

Java: Difference between HashMap and Hashtable


HashMap and Hashtable both implements Map interface and used to store data in key and value pairs. Both use hashing techniques to get unique keys.

Apart from some similarities, there are many differences between HashMap and Hashtable classes as follows:

java.util.HashMap java.util.HashTable
HashMap class introduced in JDK 1.2. Hashtable is a legacy class.
HashMap inherits AbstractMap class. Hashtable inherits Dictionary class.
HashMap is traversed by Iterator. Hashtable is traversed by the Enumerator and Iterator.
Hashmap, Iterator is fail-fast. Hashtable, Enumerator is not fail-fast.
HashMap is not synchronized and not-thread safe. Hashtable is synchronized and thread safe.
HashMap can be synchronized by calling this code
Map m = Collections.synchronizedMap(hashMap);
Hashtable is internally synchronized and can’t be unsynchronized.
HashMap class allows only one null key and multiple null values. Hashtable doesn’t allow any null key or value.
HashMap is fast. Hashtable is slow.

For more detail: