Hashtable in Java

Learn via video course
FREE
View all courses
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning
Java Course - Mastering the Fundamentals
Java Course - Mastering the Fundamentals
by Tarun Luthra
1000
5
Start Learning

Overview

The Hashtable class in Java is one of the oldest members of the Java Collection Framework. A hash table is an unordered collection of key-value pairs, with a unique key for each value.

In a hash table, data is stored in an array of list format, with a distinct index value for each data value. The hash table provides an efficient combination of retrieval, edit, and delete operations.

This article explains how to build a hashtable, how to fill it with data, and finally how to use enumeration to show the key-value pairs in the hashtable. At the end of this article, there are Hashtable code examples along with desired outputs and detailed information regarding Hashtable class methods.

Introduction to Java Hashtable Class

The Hashtable class in Java is a concrete implementation of a Dictionary and was originally a part of java.util package. The Hashtable class creates a hash table by mapping keys to values.

In a hashtable, any non-null object can be used as a key or as a value. The objects used as keys must implement the hashCode and equals methods in order to effectively store and retrieve items from a hashtable.

Hashtable is not just a data structure, but also a Java Collection API class. Despite the fact that both the array and hashtable data structures are intended for fast search, i.e. constant time search operation, also known as O(1) search, the fundamental difference between them is that the array requires an index, whereas the hash table requires a key, which could be another object.

This code example generates a hashtable of numbers. It employs the bird numbers as keys:

Output:

As depicted above, a hashtable does not guarantee the order of records inserted in it.

Java Hashtable was added in the JDK 1.0 version which is a part of the java.util.Hashtable package. Prior to JDK 1.2 version, keys and values were mapped using hashtables. Later on, Java 1.2 version changed the Hashtable such that it now implements the Map interface. Thus, Hashtable has been included in the Java Collections framework. However, since it does not exactly adhere to the Java Collections Framework, it is now considered a "legacy class."

Declaration

Hashtable in Java is a generic class created by JDK 1.5 which can be declared as follows:

Parameters

Two parameters are accepted by hashtable:

  • K – the type of keys maintained by this map
  • V – the type of mapped values

Internal Working of Hashtable

Before getting into how hashtables operate in Java, let's have a look at how they're implemented.

The hashtable class extends the Dictionary class and implements Map, Cloneable, and Serializable interfaces. The following diagram clearly depicts the Hashtable hierarchy in Java.

internal-working-of-hashtable

A Hashtable is an array of a list. Each list is referred to as a bucket that contains the key/value pairs in them. It uses the hashCode() method for identifying which bucket should be assigned to the key/value combination. Hashcode, in general, use a non-negative integer that is equal for equal Objects but may or may not be equal for unequal Objects. The equals() function is used by the hashtable to detect if two items are equal or not.

The hash function assists in locating a specific key in the bucket list. In theory, a hash function is a function that creates an address in a table when given a key. For an object, a hash function always returns a number.

Note: It should be noted that the Java Hashtable class includes unique elements and does not support null keys or values. You cannot even attempt to acquire a null key since it would throw a NullPointerException.

Two identical items will always have the same number, however, two unequal objects might not always have distinct numbers. When we add entries into a hashtable, it is possible that different objects (through the equals() function) may have the same hashcode. This is referred to as a collision.

The pairings that map to a single bucket (array index) are saved in a list, and the list reference is saved in the array index.

Hashtables are simple to understand when visualized. Hash tables are often created as arrays of linked lists. If we consider a table that stores city's names, after a few insertions it might be laid out in memory as below, where ()-enclosed integers represent hash values of the text entered as the city’s name.

hash-values-in-hash-tables

  • Each entry in the array (at indices [0], [1], and so on) is called a bucket. It begins with a potentially empty linked list containing key-value pairs which in this case is key mapped to city names.
  • Each value (e.g. "Ontario" with hash 12 ) is linked from a bucket which is identified by the formula: Hash_number % Number of buckets = Index of Bucket 12 % 10 == [2] Here, % is the modulo operator, which gives the remainder when the hash number is divided by the number of buckets. So, the city name with hash number 12 will be placed in a bucket with the index number 2.
  • Multiple data values may collide at and be linked from the same bucket, often due to the fact that their hash values collide after calculating the modulo operation (e.g. 12 % 10 == [2], and 42 % 10 == [2]), Most hash tables manage collisions by comparing the whole value (here text) of a value being searched or added to each value existing in the linked list at the hashed-to bucket. This results in somewhat decreased speed but no functional confusion.

Hashtable is synchronized and offers thread safety comparable to concurrentHashMap. However, from the perspective of performance, Hashtable writes operations employ hashtable wide lock, which locks the whole hashtable object.

Look at the below illustration for a better understanding.

illustration-of-hashtable

To get the lock on the whole hashtable object, thread T1 runs the get() and put() operations on the hashtable. As a result, if Thread T2 performs get() or put(), it must wait until Thread T1 completes the operation and releases the lock on the object.

Features of Hashtable in Java

In Java, a hashtable is a component of the collections framework in which it implements a Map interface. For backward compatibility, it inherits from the obsolete and utterly useless Dictionary class.

After learning what a hashtable in Java is and how it operates, let's examine some of its key features:

  • Key Based Hashtables need a key to search the value, which might be another object, in contrast to arrays, which require an index.

  • Dynamic Capacity By employing chaining and linked lists, the hashtable may store more items than the internal array can hold.

  • Performance Hashtable performance may be O(n) in the worst scenario when you need to go through a linked list in order to identify the proper value object due to a collision, despite the fact that hashtables are designed for fast search, that is, constant time search operations, commonly known as O(1) search.

Note: This has been somewhat improved now when JDK utilizes binary tree rather than linked lists from Java 8 and worst-case performance is now pegged to O(logN).

  • Usage Hashtables stores mapping, or pairings of key-value objects. As a result, it may be used to hold information on clients, library books, or other records.

  • Sorting Although a Hashtable cannot be sorted, sorted data can be extracted by sorting the list of keys from the Hash table and retrieving values in that order by using a TreeMap or LinkedHashMap.

  • Collision As different data items may collide at and be associated from the same bucket, most often because their hash values conflict, collisions are possible in hashtables. This can be handled by using various collision avoidance algorithms like open addressing or chaining.

  • Synchronization Since the hashtable class is synchronized, it is thread-safe. The Hashtable class instance cannot be accessed simultaneously by more than one thread. As a result, its operations are slower as compared to HashMaps in Java.

Note: If a thread-safe implementation is not required, it is advisable to use HashMap instead of Hashtable.

Note: If a thread-safe highly-concurrent implementation is needed, then it is advised to use ConcurrentHashMap instead of Hashtable.

Constructors of Java Hashtable Class

Both parameterized and non-parameterized constructors may be used to generate a Hashtable in a variety of ways:

ConstructorDescription
Hashtable()It is the default constructor of a hash table that constructs a new and empty hashtable with a default initial capacity (11) and load factor (0.75).
Hashtable(int capacity)It constructs a new, empty hashtable with the specified initial capacity and default load factor (0.75).
Hashtable(int capacity, float loadFactor)It constructs a new, empty hashtable with the specified initial capacity and the specified load factor.
Hashtable(Map<? extends K,? extends V> t)It constructs a new hashtable with the same mappings as the given Map.

Methods of Java Hashtable Class

The most commonly used methods in HashTable are shown below.

MethodDescription
void clear()Removes all the key-value mappings from a Hashtable and makes it empty.
Object clone()Creates a shallow copy of the hashtable. All the structure of the hashtable itself is copied, but the keys and values are not cloned. This is a relatively expensive operation.
boolean containsValue(Object value)Tests if the specified object is a value in the hashtable. Returns true if some value equal to the specified value exists within the hash table. Returns false if the value isn’t found.
boolean containsKey(Object key)Tests if the specified object is a key in this hashtable.
boolean contains(Object value)Tests if some key maps into the specified value in this hashtable. This operation is more expensive than the containsKey method.

Note that this method is identical in functionality to containsValue, (which is part of the Map interface in the collections framework).
boolean isEmpty()Tests if the hashtable maps no keys to values.
Enumeration keys()Returns an enumeration of the keys contained in the hash table.
Object put(Object key, Object value)Maps the specified key to the specified value in this hashtable.
void rehash()Increases the size of the hash table and rehashes all of its keys.
Object remove(Object key)Removes the key (and its corresponding value) from this hashtable.
int size()Returns the number of key-value mappings present in Hashtable.
String toString()Returns the objects of Hashtable in the form of a set of key-value mappings separated by ", ". The toString() method is used to convert all the elements of Hashtable into String.
Enumeration elements()Returns an enumeration of the values contained in the hash table.
Object get(Object key)Returns the value to which the specified key is mapped, or null if the hashtable contains no mapping for the key.
hashcode()Returns the hash code value for the Map as per the definition in the Map interface.
putAll(Map<? extends K,? extends V> t)Copies all of the mappings from a given map to the hashtable.
getOrDefault(Object key, V defaultValue)Returns the value to which the given key is mapped, or defaultValue if the hashtable contains no mapping for the key.
putIfAbsent(K key, V value)If the specified key is not already mapped with a value, maps it with the given value and returns null, else returns the current mapped value.
keySet()Returns a view of the keys contained in the hashtable as a set.
entrySet()Returns a view of the mappings contained in the hashtable as a set.

Code Examples Using Hashtable in Java

Let's look at a few example methods that conduct operations using hashtable in Java.

  • Hashtable()

This example shows how to create a hashtable and add entries to it.

Output:

  • remove()

This example shows how to remove elements from a hashtable by using the remove() function.

This function takes the key of the value to be removed as the parameter.

Output:

  • getOrDefault()

This example shows how to use the getOrDefault() function which returns the value to which a specified key is mapped, or a defaultValue if the hashtable contains no mapping for that key.

It takes two parameters: a key and a default value to be printed as a message if the key is not present in the hashtable.

Output:

  • putIfAbsent()

This example shows how to use the putIfAbsent() function which allows mapping a value to a given key if a given key is not associated with the value or mapped to null.

It takes two parameters: a key and a value to be mapped with the key. If the key-value pair is unique, then it gets inserted in the hashtable otherwise there are no changes in the hashtable.

Output:

  • Traversal of a Hashtable

We may traverse through the hashtable in a number of different methods, which are as follows:

1. Using Enumeration Interface

The java.util.Enumeration interface is used to get the data from collections framework variables like a stack or a hashtable only in the forward direction and not in the backward direction. It is one of the predefined interfaces.

Note: For new code, enumeration is regarded as being obsolete, and this interface has been replaced with an iterator.

Example:

Output:

2. Using keySet() method of Map and Enhance for loop

The java.util.HashMap.keySet() function in Java is used to generate a set from the key elements contained in the hash map.

It simply returns a view of the keys as a set, or we can construct a new set and store the key elements in it.

Example:

Output:


3. Using keySet() method of Map and Iterator Interface

This example uses the same approach as the previous method, however, iteration is performed here by using an Iterable interface.

Example:

Output:

4. Using entrySet() method of Map and Enhanced For Loop

The java.util.HashMap.entrySet() method in Java is used to build a set from the same elements found in the hash map.

It returns a view of the hash map as a set, or we can construct a new set and store the map elements in it.

Example:

Output:

5. Using entrySet() method of Map and Iterator interface

This example uses the same approach as the above method, however, iteration is performed here by using an Iterable interface.

Example:

Output:

6. Using Iterable.forEach() method from version Java 8

With the release of Java 8, several old APIs have been updated and new features are added.

One of them is forEach() method in java.lang.Iterable Interface which performs a given action for each element of the Iterable until all elements have been processed or the action throws an exception.

It performs the actions in the order of iteration unless specified otherwise.

Example:

Output:

  • Hashtable(Map<? extends K,? extends V> m)

This example shows how to construct a new hashtable with the same mappings as a given Map.

Output:

  • Hashtable(int size, float fillRatio)

This example shows a Hashtable constructor which takes a whole number depicting the initial capacity of the Hashtable and a positive loadFactor as arguments.

Output:

  • Hashtable(int initialCapacity)

This example shows a Hashtable constructor which takes a whole number as an argument depicting the initial capacity of the Hashtable.

Output:

Conclusion

  • This article covered the characteristics of the Java Hashtable class, its constructors, methods, and actual use cases.
  • Hash tables are used to store and retrieve data (or records) quickly.
  • Hashtables store the records in buckets using hash keys.
  • Java Hashtable implements the Serializable and Cloneable interfaces but not the random access interface.
  • Java Hashtable does not support null for both keys and values.
  • In a hashtable, every method is synchronized. Hence, the Hashtable object is thread-safe.
  • Although Hashtable is thread-safe, it performs poorly when used with multiple threads.