Thursday, 27 September 2018

HashMap in Java With Examples

HashMap in Java is Hash table based implementation of the Map interface that is used for storing (key, value) pairs. HashMap class in Java extends AbstractMap class and implements Map, Cloneable and Serializable interfaces.

Some of the important points about HashMap are-

  1. HashMap is an unordered collection which means HashMap does not guarantee the order of its elements.
  2. HashMap in Java permits multiple null values and a single null key.
  3. Key in the HashMap should be unique otherwise the previous stored value for the same key will be overwritten. Duplicate values are allowed though.
  4. HashMap works on the concept of hashing and the key is used to calculate the hash code. This hash code decides where will be the (key, value) pair stored.
  5. HashMap in Java is not synchronized so it is not thread safe. If HashMap is accessed concurrently by multiple threads and at least one of the threads modifies the map structurally, then the HashMap must be synchronized externally.
  6. HashMap does not implement Iterable interface so HashMap by itself can’t be iterated. You can get the “Collection view” of the Map though and iterate it.

Java HashMap constructors

HashMap class in Java has four constructors-

  • HashMap()- This constructor creates an empty HashMap with the default initial capacity (16) and the default load factor (0.75).
  • HashMap(int initialCapacity)- This constructor creates an empty HashMap with the specified initial capacity and the default load factor (0.75). If you want a HashMap with a bigger initial capacity you can use this constructor.
  • HashMap(int initialCapacity, float loadFactor)- This constructor creates an empty HashMap with the specified initial capacity and load factor.
  • HashMap(Map<? extends K,? extends V> m)- Constructs a new HashMap with the same mappings as the specified Map.

Java HashMap creation example

Here is a simple Java example creating a HashMap and storing (key, value) pairs to it. We’ll also get the collection view of the Map using the entrySet method and use that to iterate the created HashMap.

public class HashMapSorting {

    public static void main(String[] args) {
        // creating HashMap
        Map<String, String> langMap = new HashMap<String, String>();
        // Storing (key, value) pair to HashMap
        langMap.put("ENG", "English");
        langMap.put("NLD", "Dutch");
        langMap.put("ZHO", "Chinese");
        langMap.put("BEN", "Bengali");
        langMap.put("ZUL", "Zulu");
        // retrieving value using key
        String language = langMap.get("BEN");
        System.out.println("Language- " + language);
        
        System.out.println("-- Map Elements --");
        for(Map.Entry<String, String> lang : langMap.entrySet()) {
            System.out.println("Key- " + lang.getKey() + 
                          " Value- " + lang.getValue());
        }
    }
}

Output

Language- Bengali
-- Map Elements --
Key- ZHO Value- Chinese
Key- ZUL Value- Zulu
Key- NLD Value- Dutch
Key- BEN Value- Bengali
Key- ENG Value- English

As you can see in the code a HashMap is created using the default constructor and the elements added to it using the put() method. Value mapped to any specific key can be retrieved by passing the key in the get() method.

From the displayed elements of the HashMap you can also see that the order is not maintained.

Initial capacity and load factor in HashMap

HashMap has two parameters that affect its performance:

  • Initial capacity
  • Load factor

The capacity is the number of buckets in the hash table. Initial capacity is simply the capacity at the time the hash table is created.

HashMap internally uses an array for storing its elements and each array of index is known as one bucket. By default an array has 16 buckets. For every (key, value) pair added to HashMap a hashcode is calculated using the key. That hashcode decides element goes to which bucket.

The load factor is a measure of how full the hash table is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets. Default load factor is 0.75

Methods in Java HashMap class

Some of the important methods in the HashMap class are listed below.

  • clear()- Removes all of the mappings from this map.
  • computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)- If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
  • computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)- If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.
  • containsKey(Object key)- Returns true if this map contains a mapping for the specified key.
  • containsValue(Object value)- Returns true if this map maps one or more keys to the specified value.
  • entrySet()- Returns a Set view of the mappings contained in this map.
  • get(Object key)- Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
  • isEmpty()- Returns true if this map contains no key-value mappings.
  • keySet()- Returns a Set view of the keys contained in this map.
  • put(K key, V value)- Associates the specified value with the specified key in this map.
  • putIfAbsent(K key, V value)- If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value.
  • remove(Object key)- Removes the mapping for the specified key from this map if present.
  • remove(Object key, Object value)- Removes the entry for the specified key only if it is currently mapped to the specified value.
  • replace(K key, V value)- Replaces the entry for the specified key only if it is currently mapped to some value.
  • size()- Returns the number of key-value mappings in this map.

HashMap allows null as key and value

HashMap in Java allows one null key and multiple null values.

public class HashMapSorting {

    public static void main(String[] args) {
        // creating HashMap
        Map<String, String> langMap = new HashMap<String, String>();
        // Storing (key, value) pair to HashMap
        langMap.put("ENG", "English");
        langMap.put("NLD", null);
        langMap.put("ZHO", null);
        langMap.put("BEN", "Bengali");
        langMap.put("ZUL", "Zulu");
        langMap.put(null, "French");
        langMap.put(null, "Hindi");
        
        System.out.println("-- Map Elements --");
        for(Map.Entry<String, String> lang : langMap.entrySet()) {
            System.out.println("Key- " + lang.getKey() + 
                          " Value- " + lang.getValue());
        }
    }
}

Output

-- Map Elements --
Key- ZHO Value- null
Key- ZUL Value- Zulu
Key- null Value- Hindi
Key- NLD Value- null
Key- BEN Value- Bengali
Key- ENG Value- English

As you can see null is inserted twice as a key but only one null key is stored. For value null can be passed multiple times.

Java HashMap iteration

HashMap by itself can’t be iterated. You can get the “Collection view” of the Map though and iterate it for example keySet() method returns a set view of the keys in the Map which can then be iterated.

The iterators returned by all of HashMap's "collection view methods" are fail-fast: if the map 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.

Example code

In the example we’ll get the Set view of the mapped entries using the entrySet() method. While iterating that Set we’ll try to remove an element from the HashMap which means a structural modification.

public class HashMapSorting {

    public static void main(String[] args) {
        // creating HashMap
        Map<String, String> langMap = new HashMap<String, String>();
        // Storing (key, value) pair to HashMap
        langMap.put("ENG", "English");
        langMap.put("NLD", "Dutch");
        langMap.put("ZHO", "Chinese");
        langMap.put("BEN", "Bengali");
        langMap.put("ZUL", "Zulu");
        langMap.put("FRE", "French");
        
        Set<Map.Entry<String, String>> langSet = langMap.entrySet();
        Iterator<Map.Entry<String, String>> itr = langSet.iterator();
        while (itr.hasNext()) {
            Map.Entry<String, String> entry = itr.next();
            System.out.println("Key is " + entry.getKey() + " Value is " + entry.getValue());    
            // removing value using HashMap's remove method
            if(entry.getKey().equals("NLD")){
                langMap.remove(entry.getKey());
            }
        }
    }
}

Output

Key is ZHO Value is Chinese
Key is ZUL Value is Zulu
Key is NLD Value is Dutch
Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
 at java.util.HashMap$EntryIterator.next(HashMap.java:1463)
 at java.util.HashMap$EntryIterator.next(HashMap.java:1461)
 at org.netjs.examples.HashMapSorting.main(HashMapSorting.java:31)

Since Map is structurally modified while iteration is going on so the ConcurrentModificationException is thrown.

HashMap is not synchronized

HashMap in Java is not synchronized. If HashMap is accessed concurrently by multiple threads and at least one of the threads modifies the map structurally, then the HashMap must be synchronized externally. In order to synchronize Map you can use Collections.synchronizedMap() method which returns a synchronized Map backed by the specified map.

As example –

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

That's all for this topic HashMap in Java With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How to Loop Through a Map in Java
  2. How to Sort a HashMap in Java
  3. ConcurrentHashMap in Java
  4. HashSet Vs LinkedHashSet Vs TreeSet in Java
  5. How to Convert Array to ArrayList in Java

You may also like-

  1. ReentrantLock in Java Concurrency
  2. Callable And Future in Java Concurrency
  3. Method reference in Java 8
  4. Heap Memory Allocation in Java
  5. How to Pass Command Line Arguments in Eclipse
  6. Difference Between Checked And Unchecked Exception in Java
  7. Conditional Operators in Java
  8. Inheritance in Java

No comments:

Post a Comment