Java HashMap with Example

Java HashMap is the most popular concrete implementation of Java Map. The distinguishing feature of HashMap is that it is based on the celebrated hashtable data structure. Like any other Java Map, a HashMap maintains associations between keys and values.

A HashMap is an unordered collection, meaning you should not use HashMap if your program requires iteration or retrieval in a predictable order. Nevertheless, a HashMap is extremely efficient and therefore frequently-used popular data structure. You are likely to encounter HashMaps in all real life Java projects, therefore we will invest substantial time and cyber-estate to this class.

Salient Features of HashMap

Before we dig deeper into the internal implementation of HashMap and how to use it, let’s summarize the main characteristics of HashMap. HashMap –

  1. Is unordered collection. Elements are stored and iterated in unpredictable order.
  2. Allows exactly one null key and many null values.
  3. Has unique keys. (Follows from the fact that HashMap implements Map)
  4. Has Ο(1) complexity for search, insert and delete operations. This is the main attraction and the reason why HashMaps are so popular. This property follows from the fact that HashMap is based on hashtable data structure. We will look at the internal implementation of HashMap in the next article.

Capacity, Initial Capacity, Size and Load Factor

In the context of Java HashMap you will often come across the following terms –

  1. Capacity – is the number of buckets or slots in the underlying hashtable at any specific instant. This represents the maximum number of elements that can be fit in without re-hashing.
  2. Initial Capacity – is the number of buckets in the underlying hashtable at the time HashMap is created.
  3. Load Factor – is the threshold of size (defined below) at which the capacity of the underlying hashtable is increased and rehashing occurs. This threshold is expressed as a floating point number less than 1.
    For example, a load factor of 0.5 means that every time the number of elements in HashMap becomes more than 0.5 * initial_capacity, rehashing will be triggered.
  4. Size – is the number of elements (entries) actually present in the HashMap. This is always less than or equal to (equal to only in a badly initialized HashMap) to the capacity.

Default Values of Initial Capacity and Load Factor

Oracle JDK has the following default values of initial capacity and load factor

Initial Capacity                    16

Load Factor                          0.75

Therefore, when the number of elements in a HashMap exceeds 16 * 0.75 (i.e. 12) rehashing will be triggered and the capacity of the underlying hashtable will be enhanced.

N.B. Some of the terms described here will make more sense once you go through the internal implementation details of HashMap.

Constructors of HashMap

As indicated in the previous article on Java Map, by convention all concrete implementations of Map  interface must have no-args and copy constructor. HashMap, in addition has two more constructors – one that takes initial capacity and other that takes capacity and load factor.

  1. HashMap() – Constructs an empty HashMap with the default initial capacity (16) and the default load factor (0.75).
  2. HashMap(Map<? extends K,? extends V> m) – Constructs a new HashMap with the same mappings as the specified Map.
  3. HashMap(int initialCapacity) – Constructs an empty HashMap with the specified initial capacity and the default load factor (0.75).
  4. HashMap(int initialCapacity, float loadFactor) – Constructs an empty HashMap with the specified initial capacity and load factor.

Important Methods of HashMap

  1. int size() – returns the number of key, value pairs (entires) in the HashMap . Note that this number is different from capacity and initial capacity.
  2. boolean containsKey(k) – checks if the specified key is present in HashMap. This is one of the most frequently methods and has a constant-time asymptotic complexity. Constant time or O(1) complexity means that it always takes constant time to search an element and the time taken does not depend on the number of entries in HashMap.
  3. boolean containsValue(v) – returns true if the value v is present in the HashMap, false otherwise.
  4. V put(K key, V value) – inserts an entry into HashMap
  5. void putAll(Map<? extends K,? extends V> m) – copies all the entries from the Map passed as argument to the current HashMap
  6. V get(Object key) – retrieves the value associated with key. This method has constant-time characteristics and therefore is very lucrative.

HashMap, like all other Maps provide the three Collection-view methods that we discussed in the Map Interface lesson.

Example Program Using HashMap

In this section we will write a trivial program that associates job designations to job descriptions. Since we need an associative relationship we will go with HashMap.

Here is the sample program that uses job titles as keys and job descriptions as values. Note that we are using entrySet() collection-view method for iteration. There are multiple other methods available for iteration.

The output of the above program is –

In this article we introduced HashMap. Next we will examine HashMap internals in detail.

Leave a comment

Your email address will not be published.