View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

What is Hashtable in Java? Explained with Examples

By Pavan Vadapalli

Updated on May 28, 2025 | 18 min read | 7.93K+ views

Share:

Did you know that Java is ranked second among the top programming languages in 2025? As Java continues to dominate in enterprise environments, understanding data structures like what is a Hashtable becomes essential for developing high-performance applications in multi-threaded contexts.

A Hashtable in Java is a synchronized data structure that stores key-value pairs using a hashing technique. It ensures thread safety in concurrent environments by determining the index for storing values, making it efficient for lookups. 

Unlike HashMap, it doesn’t allow null keys or values, and its iteration order is not guaranteed. Understanding what is a Hashtable is crucial for implementing thread-safe data structures in Java applications, particularly for legacy systems or simple multi-threaded use cases.

In this blog, we will explore what is a hashtable in Java, along with examples that are relevant within enterprises. 

Master Java and more with upGrad’s Software Development course featuring an updated Generative AI curriculum and specializations in Cyber Security, Full Stack Development, Game Development, and more. Build a strong foundation with hands-on projects, expert mentorship, and training on the latest tools and languages!

What is a Hashtable in Java?

A Hashtable is a synchronized, legacy Java collection that stores key-value pairs using hashing, unlike JavaScript’s Map or unsynchronized HashMap. It forbids null keys and values, ensuring thread safety but causing performance issues in high-concurrency applications. For scalable, modern Java or JavaScript environments, ConcurrentHashMap or asynchronous collections offer better alternatives than Hashtable.

If you want to learn Java and other programming languages for modern enterprise operations, the following courses from upGrad can help you succeed.

Hashtable vs HashMap in Java: Key Differences

Both Hashtable and HashMap rely on hashing code in Java to store key-value pairs efficiently, but their concurrency handling and usage contexts differ significantly. While ReactJS developers might often interact with Java backends, understanding these distinctions is critical when dealing with data caching or session management in full-stack applications. 

Although both classes use a hash table to store key-value pairs, they differ in some crucial aspects:

Feature Hashtable HashMap
Thread Safety
  • Synchronized internally with coarse-grained locking, causing slower performance in high concurrency.
  • Suitable for legacy multi-threaded environments without external synchronization.
  • Not synchronized by default; can be wrapped with Collections.synchronizedMap() for thread safety. 
  • For high concurrency, ConcurrentHashMap offers fine-grained locking and superior scalability.
Null Support
  • Does not allow null keys or null values, preventing NullPointerExceptions in legacy code.
  • Allows one null key and multiple null values, offering more flexibility in data handling.
Iteration Behavior
  • Iterators are not fail-fast, meaning concurrent modifications might go undetected, potentially causing inconsistent behavior.
  • Fail-fast iterators throw ConcurrentModificationException on concurrent modification, aiding safer iteration.
Performance
  • Slower due to synchronized methods and locking overhead; not suitable for performance-critical or highly concurrent modern applications.
  • Generally faster with better throughput; supports external synchronization or concurrent alternatives for thread-safe use.
Legacy vs Modern Use
  • Part of Java’s legacy collections; primarily used for backward compatibility in older systems where synchronized maps were essential.
  • Core component of the modern Collections Framework; recommended for most new Java applications and frameworks integrating backend APIs with frontend tools like ReactJS.
Use Case Scenarios
  • Useful when maintaining legacy applications requiring thread-safe hash tables without refactoring.
  • Ideal for new development needing flexible null handling, better performance, and scalable concurrency control.

Example Scenario:

You maintain a legacy financial system that relies on Hashtable for thread-safe caching without refactoring. Migrating to HashMap requires extensive code changes and synchronization adjustments. Continuing with Hashtable ensures stability and backward compatibility while new systems adopt modern concurrent collections.

Now that you know what is a hashtable and how it compares with HashMap, let’s understand how it works internally and what makes it efficient.

How Does a Hashtable Work Internally? An Example

Understanding what is a hashtable Java involves knowing its internal workings. A Hashtable stores key-value pairs in an array called buckets, where each key’s hashcode determines the bucket index. When multiple keys share the same index, collisions occur, resolved by chaining, storing entries as linked lists within buckets.

Here are some of the key considerations:

  • Collisions impact performance; excessive collisions can slow lookups from O(1) to O(n).
  • To manage this, Hashtable monitors its load factor (default 0.75) and triggers rehashing, resizing the internal array and redistributing entries.
  • Rehashing improves efficiency but is computationally expensive and should be minimized with proper capacity settings.
  • For scenarios requiring insertion order, LinkedHashMap offers a modern alternative combining hash table efficiency with predictable iteration order.

This balance of hashing, collision handling, and resizing ensures Hashtable performs efficiently in typical use cases, though modern alternatives may suit evolving needs better.

This approach makes lookups very fast on average, typically O(1) time complexity.

Code Example:

import java.util.Hashtable;

public class HashtableExample {
    public static void main(String[] args) {
        Hashtable<String, Integer> ht = new Hashtable<>();
        ht.put("Apple", 1);
        ht.put("Banana", 2);
        ht.put("Cherry", 3);

        System.out.println("Value for key 'Apple': " + ht.get("Apple"));
        System.out.println("Value for key 'Banana': " + ht.get("Banana"));
        System.out.println("Value for key 'Cherry': " + ht.get("Cherry"));
    }
}

Output:

Value for key 'Apple': 1
Value for key 'Banana': 2
Value for key 'Cherry': 3

Output Explanation:

The keys "Apple," "Banana," and "Cherry" are hashed to compute their index, efficiently storing corresponding values. If two keys hash to the same index, they are handled by a linked bucket list to avoid collisions.

Let’s explore how to create a hash table Java with examples and constructors to address what is a hashtable in detail.

Step-by-Step Guide to Creating a Hashtable in Java

If you’re wondering what is a hashtable and how to create one, Java provides several constructors to initialize a hashtable based on your specific needs. Using the right constructor helps optimize both performance and memory usage by setting appropriate initial capacity and load factor.

Coverage of AWS, Microsoft Azure and GCP services

Certification8 Months

Job-Linked Program

Bootcamp36 Weeks

Here’s a step-by-step guide to create a hashtable in Java:

Step 1: Choose the Default Constructor

  • Creates an empty Hashtable with an initial capacity of 11 and a load factor of 0.75.
  • Suitable for general use when you don’t know the expected size.

Step 2: Use Constructor with Initial Capacity

  • Initialize the Hashtable with a specific capacity if you expect a certain number of entries.
  • Helps reduce the need for resizing, but setting it too high wastes memory.

Step 3: Use Constructor with Initial Capacity and Load Factor

  • Allows fine control by setting how full the Hashtable can get before resizing (load factor).
  • A low load factor reduces collisions but increases memory consumption.
  • A high load factor saves memory but may increase collisions and slow performance.

Step 4: Use Constructor from an Existing Map

  • Copies all key-value pairs from an existing Map into the new Hashtable.
  • Useful for converting other map implementations into a Hashtable.

Code Example:

import java.util.Hashtable;
import java.util.HashMap;
import java.util.Map;

public class HashtableConstructorsExample {
    public static void main(String[] args) {
        // Default constructor
        Hashtable<String, Integer> ht1 = new Hashtable<>();
        System.out.println("Default constructor size: " + ht1.size());

        // Constructor with initial capacity
        Hashtable<String, Integer> ht2 = new Hashtable<>(20);
        System.out.println("Initial capacity 20, size: " + ht2.size());

        // Constructor with initial capacity and load factor
        Hashtable<String, Integer> ht3 = new Hashtable<>(20, 0.5f);
        System.out.println("Capacity 20, load factor 0.5, size: " + ht3.size());

        // Constructor from another Map
        Map<String, Integer> map = new HashMap<>();
        map.put("A", 1);
        map.put("B", 2);
        Hashtable<String, Integer> ht4 = new Hashtable<>(map);
        System.out.println("Hashtable from Map, size: " + ht4.size());
    }
}

Output:

Default constructor size: 0
Initial capacity 20, size: 0
Capacity 20, load factor 0.5, size: 0
Hashtable from Map, size: 2

Output Explanation:

Each Hashtable is initially empty except for the one created from an existing Map, which contains two entries. The initial capacity and load factor settings affect internal resizing and performance but not the immediate size. The size() method reflects the actual number of stored entries at creation time.

Important Consideration: Choosing a huge initial capacity or a very low load factor can cause unnecessary memory use without a significant performance gain. It’s best to balance these values based on your application’s expected data size and concurrency needs.

These constructors give you flexibility in how to make a hash table in Java, balancing between performance and memory use.

Hashtable Constructors Explained

When creating a Hashtable Java, selecting the right constructor is crucial for balancing memory usage and performance. Different constructors offer flexibility depending on your expected data volume and access patterns.

 

  • Hashtable(): Creates a hashtable with default settings—initial capacity of 11 and load factor 0.75. Best for general use when the expected size and load are unknown.
  • Hashtable(int initialCapacity): Ideal when you know the approximate number of entries in advance. Setting the initial capacity helps avoid costly resizing operations during runtime.
  • Hashtable(int initialCapacity, float loadFactor): Allows fine-tuning of the load factor, which controls how full the hashtable can get before resizing. A lower load factor reduces collisions but increases memory usage, while a higher load factor saves memory at the risk of more collisions.
  • Hashtable(Map<? extends K, ? extends V> m): Quickly initializes a Hashtable by copying all entries from an existing map. Useful for converting between map implementations.

Quick Tips for Choosing Parameters:

  • If your application expects many insertions, increase the initial capacity to minimize resizing.
  • Choose a load factor around 0.75 for a good balance between memory consumption and collision rate.
  • For memory-sensitive applications, consider a higher load factor but be aware it might affect lookup speed.

Each constructor serves different scenarios, and choosing the right one ensures efficient use of hashtable in Java for your specific requirements.

If you want to gain expertise in industry-relevant programming skills like Java. Check out upGrad’s AI-Powered Full Stack Development Course by IIITB. The program will allow you to gain hands-on experience with Java, JavaScript, ReactJS, and more for practical applications. 

Now that we’ve covered how to create hashtables, let’s look at the common operations you can perform on a hash table Java, including examples.

Common Hashtable Operations and Key Methods in Java

Understanding what a hashtable is also involves knowing its core and advanced methods. These methods help you manipulate and interact with the data stored efficiently. Below is a comprehensive overview of key Hashtable in Java methods, with simple descriptions and practical use cases.

Hashtable Methods: Core and Advanced

Hashtable provides a rich set of methods that let you perform various operations, from basic insertion and retrieval to more advanced concurrent programming patterns. Understanding these methods will help you manage data efficiently and avoid common pitfalls.

Below is a table summarizing the key Hashtable methods, their purposes, and when to use them:

Method

Description

put(K key, V value) Inserts or updates the key-value pair in the hashtable.
get(Object key) Retrieves the value associated with the specified key, or null if none exists.
remove(Object key) Removes the key and its corresponding value from the hashtable.
containsKey(Object key) Checks if a given key exists in the hashtable.
containsValue(Object value) Checks if a specified value is present in the hashtable.
size() Returns the number of key-value pairs currently in the hashtable.
clear() Removes all key-value pairs from the hashtable.
clone() Creates a shallow copy of the hashtable.
compute(K key, BiFunction remappingFunction) Attempts to compute a new mapping for the specified key and its current value. Useful for atomic updates.
computeIfAbsent(K key, Function mappingFunction) Computes and inserts a value if the specified key is not already associated with a value. Ideal for lazy initialization.
computeIfPresent(K key, BiFunction remappingFunction) Computes a new value for a key only if it is already present. Useful for conditional updates.
putIfAbsent(K key, V value) Inserts the key-value pair only if the key is not already associated with a value. Helps avoid overwriting existing entries.
replace(K key, V value) Replaces the value for the specified key only if it currently maps to some value.
replace(K key, V oldValue, V newValue) Replaces the value for the specified key only if currently mapped to the specified old value.
contains(Object value) Tests if some key maps to the specified value in the hashtable.
elements() Returns an enumeration of all the values in the hashtable.
entrySet() Returns a Set view of the mappings contained in this hashtable.
isEmpty() Checks if the hashtable contains no key-value pairs.
keys() Returns an enumeration of all the keys in the hashtable.
keySet() Returns a Set view of the keys contained in this hashtable.
putAll(Map<? extends K, ? extends V> t) Copies all mappings from the specified map into the hashtable.
rehash() Increases the capacity and reorganizes the hashtable internally to maintain efficient access. This can be costly in time and should be minimized. Poorly implemented hash functions may lead to excessive rehashing or even infinite loops, so designing good hashCode() methods is critical.
toString() Returns a string representation of the hashtable’s contents.
values() Returns a Collection view of the values contained in the hashtable.

Key Method Usage Insights

  • rehash(): This method is automatically triggered when the Hashtable’s load factor threshold is reached, resizing internal buckets to optimize hashing code in Java and reduce collisions. Like CSS minimizing browser redraws, rehashing improves access speed, but frequent resizing may cause delays. Setting appropriate initial capacity and load factor helps balance performance and memory.
  • putIfAbsent(): Ideal for multi-threaded contexts, this method atomically adds a key-value pair only if the key is missing, preventing overwrites without external locks. Like HTTP’s PUT requests, it ensures safe updates without unintended side effects in concurrent environments.
  • computeIfAbsent(): Commonly used for lazy initialization, this method computes and inserts a value only when the key is absent, improving efficiency in cache-like structures. Like dynamic HTML content that loads on demand, it avoids unnecessary computation and supports thread-safe population of Hashtable entries.

Now, let’s understand how you can iterate over a hashtable.

How to Iterate Over a Hashtable?

Understanding what is a Hashtable Java is essential for managing key-value data efficiently, especially in legacy or multi-threaded applications. Hashtables use a synchronized hashing mechanism to store data, unlike modern concurrent maps, making traversal techniques critical for thread safety. Integrating Hashtable operations with backend systems like SQL or MySQL and frontend frameworks like Bootstrap in full-stack Java applications requires efficient, safe iteration.

  • Enumeration Interface: Supports legacy iteration over keys or values without fail-fast behavior, which can cause inconsistent traversal during concurrent modifications. Suitable for simple, synchronized scenarios but risky in high-concurrency environments.
  • Iterator Interface: Provides fail-fast iteration on most collections, but the default Iterator of Hashtable is not fail-safe unless you explicitly synchronize the map. Without synchronization, concurrent modifications can cause unpredictable behavior or exceptions.
  • Ensuring Thread Safety: To safely iterate over a Hashtable in multi-threaded environments, wrap it with Collections.synchronizedMap() provides a synchronized view, or use concurrent collections like ConcurrentHashMap, which offer built-in thread-safe iteration.

Use Cases: 

In Java applications integrating SQL/MySQL for data persistence or Bootstrap for frontend UI, synchronized and predictable data retrieval from Hashtables is vital to maintain state consistency and responsiveness.

Code Example:

import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Collections;

public class HashtableIterationExample {
    public static void main(String[] args) {
        Hashtable<String, Integer> ht = new Hashtable<>();
        ht.put("Apple", 50);
        ht.put("Banana", 30);
        ht.put("Cherry", 20);

        // Using Enumeration to iterate keys
        System.out.println("Using Enumeration:");
        Enumeration<String> keysEnum = ht.keys();
        while (keysEnum.hasMoreElements()) {
            String key = keysEnum.nextElement();
            System.out.println(key + " => " + ht.get(key));
        }

        // Creating synchronized map for thread-safe iteration with Iterator
        Map<String, Integer> syncMap = Collections.synchronizedMap(ht);

        // Using Iterator over synchronized map's entrySet
        System.out.println("\nUsing Iterator with synchronizedMap:");
        synchronized (syncMap) {
            Iterator<Map.Entry<String, Integer>> iterator = syncMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> entry = iterator.next();
                System.out.println(entry.getKey() + " => " + entry.getValue());
            }
        }
    }
}

Output:

Using Enumeration:
Apple => 50
Banana => 30
Cherry => 20

Using Iterator with synchronizedMap:
Apple => 50
Banana => 30
Cherry => 20

Output Explanation:

This example shows iteration using Enumeration, which is not fail-fast, and an Iterator wrapped inside a synchronized map to ensure thread safety. The synchronized block around the Iterator prevents concurrent modifications, which is essential in multi-threaded environments.

If you want to learn advanced SQL functions for industry-relevant Java applications, check out upGrad’s Advanced SQL: Functions and Formulas. The 11-hour free program will help you understand query optimization, programming structures, and more. 

Let’s explore some of the advantages and disadvantages of Hashtable Java to explain what is a hashtable and its efficacy in computational operations. 

Advantages and Disadvantages of Hashtable

The Hashtable class in Java provides synchronized key-value storage, making it thread-safe for basic concurrent access. However, its legacy design and coarse-grained locking lead to performance bottlenecks in modern containerized environments using Docker and orchestration platforms like Kubernetes.. For scalable microservices deployed in Kubernetes clusters, finer concurrency controls provided by ConcurrentHashMap are preferred.

Here’s a tabular format to address the advantages and disadvantages of a Hashtable. 

Aspects Advantages Disadvantages
Thread Safety Built-in synchronization ensures safe concurrent access. Coarse-grained locking causes contention and slows performance on multi-core systems.
Usage Simplicity Simple API for key-value storage, easy for legacy use. Lacks flexibility for advanced concurrency control.
Legacy Compatibility Compatible with older Java codebases. Outdated compared to modern collections like HashMap and ConcurrentHashMap.
Null Handling Disallows null keys and values, avoiding null errors. Restricts use cases needing null support; HashMap allows null keys and values.
Performance Works well in low-concurrency or single-threaded apps. Synchronization overhead reduces throughput in high-concurrency, containerized environments.
Concurrency & Scalability Suitable for basic multithreading. Poor scalability on multi-core and high-concurrency workloads versus ConcurrentHashMap.
Iterator Behavior Supports legacy Enumeration without fail-fast checks. Iterators are not fail-fast, risking inconsistent data during concurrent modifications.

Let’s explore some examples and best practices for Hashable in Java with code. 

Practical Examples and Best Practices for Hashtable in Java

The Hashtable class in Java is part of the legacy collections framework and is commonly used for thread-safe key-value data storage. While it offers simple synchronization, it can impact performance in high-concurrency situations compared to more modern alternatives like ConcurrentHashMap. Understanding a Hashtable's thread-safety guarantees, iteration mechanics, and memory considerations is critical to legacy and current applications. 

Below is a Hashtable example demonstrating basic operations like insertion, retrieval, iteration, and size checking.

Code Example:

import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Map;

public class HashtableDemo {
    public static void main(String[] args) {
        // Initialize Hashtable
        Hashtable<String, Integer> hashtable = new Hashtable<>();

        // Insert key-value pairs
        hashtable.put("Employee1", 50000);
        hashtable.put("Employee2", 60000);
        hashtable.put("Employee3", 55000);

        // Retrieve value for a specific key
        int employee1Salary = hashtable.get("Employee1");
        System.out.println("Salary of Employee1: " + employee1Salary);

        // Iterate over Hashtable using Enumeration
        Enumeration<String> keys = hashtable.keys();
        System.out.println("Hashtable Contents:");
        while (keys.hasMoreElements()) {
            String key = keys.nextElement();
            System.out.println(key + " = " + hashtable.get(key));
        }

        // Check size of the Hashtable
        System.out.println("Total employees in hashtable: " + hashtable.size());
    }
}

Output:

Salary of Employee1: 50000
Hashtable Contents:
Employee3 = 55000
Employee2 = 60000
Employee1 = 50000
Total employees in hashtable: 3

Output Explanation:

The program first retrieves and prints Employee1's salary, which is ₹50,000. Then, it iterates over all the key-value pairs using an Enumeration of keys and prints each pair.

The order of the entries may vary because a Hashtable does not guarantee the order of elements based on insertion. Lastly, it prints the total number of entries in the Hashtable, which is 3, reflecting the three key-value pairs inserted.

Also Read: Top 12 Java Open Source Projects on GitHub You Should Explore in 2025

Let’s explore some of the best practices for the Hashtable in Java applications to comprehensively understand what is a hashtable. 

Best Practices for Hashtable in Java

When choosing a Hashtable in Java, it’s crucial to understand its strengths and limitations, especially in multi-threaded applications. While Hashtable provides thread safety through synchronized methods, it may introduce performance bottlenecks in high-concurrency scenarios compared to alternatives like ConcurrentHashMap. Using a Hashtable effectively requires careful handling of null values, iteration behavior, and awareness of its legacy status in modern Java development

  • Use When Thread Safety is Needed but Simplicity Suffices: Hashtable’s synchronized methods make it a straightforward choice for simple concurrent access, but it might not be the most efficient.
  • Prefer ConcurrentHashMap for High-Concurrency Scenarios: ConcurrentHashMap offers finer-grained locking and higher throughput for better performance in multithreaded applications.
  • Avoid Null Keys and Values: Since Hashtable does not support nulls, always check data before insertion to prevent NullPointerException.
  • Consider Alternatives for New Projects: In most modern Java applications, HashMap or ConcurrentHashMap are preferred unless you have legacy code or specific synchronization requirements.
  • Mind Iterator Behavior: When iterating over a Hashtable, remember that its enumerators are not fail-fast. Be cautious when modifying the hashtable during iteration to avoid inconsistent results.

Also Read: Top 22 Open Source Java Projects to Enhance Your Development Skills

How Can upGrad Help You Learn Java and Data Structures?

Learning key data structures and understanding what is a Hashtable and hashing code in Java is essential for building efficient and thread-safe applications. Understanding concepts such as synchronization, hashing mechanics, and performance optimization ensures you write reliable, scalable code across real-world projects.

To deepen your knowledge and practical skills, upGrad offers specialized Java and data structures programs that cover essential concepts and advanced techniques. These additional courses prepare you to tackle complex coding challenges and optimize application data management.

Curious which course can help you in upskilling in Java proficiency? Contact upGrad for personalized counseling and expert guidance. For hands-on learning, you can also visit your nearest upGrad offline center.

Boost your career with our popular Software Engineering courses, offering hands-on training and expert guidance to turn you into a skilled software developer.

Master in-demand Software Development skills like coding, system design, DevOps, and agile methodologies to excel in today’s competitive tech industry.

Stay informed with our widely-read Software Development articles, covering everything from coding techniques to the latest advancements in software engineering.

Frequently Asked Questions (FAQs)

1. How does a Hashtable handle data retrieval efficiently?

2. How does Hashtable handle synchronization compared to modern alternatives like ConcurrentHashMap?

3. How does Hashtable ensure thread safety without external synchronization?

4. How does the internal hashing mechanism affect the performance of custom key objects in a Hashtable?

5. How can you prevent collisions in a Hashtable effectively?

6. How does the computeIfAbsent() method in Hashtable work, and when should you use it?

7. What is the impact of resizing on a Hashtable, and how does it affect performance?

8. How does Hashtable handle concurrent modifications during iteration?

9. Can Hashtable be used to implement caching, and what are its limitations?

10. What happens if two keys have the same hash code in a Hashtable?

Pavan Vadapalli

900 articles published

Director of Engineering @ upGrad. Motivated to leverage technology to solve problems. Seasoned leader for startups and fast moving orgs. Working on solving problems of scale and long term technology s...

Get Free Consultation

+91

By submitting, I accept the T&C and
Privacy Policy

India’s #1 Tech University

Executive PG Certification in AI-Powered Full Stack Development

77%

seats filled

View Program

Top Resources

Recommended Programs

upGrad

AWS | upGrad KnowledgeHut

AWS Certified Solutions Architect - Associate Training (SAA-C03)

69 Cloud Lab Simulations

Certification

32-Hr Training by Dustin Brimberry

upGrad

Microsoft | upGrad KnowledgeHut

Microsoft Azure Data Engineering Certification

Access Digital Learning Library

Certification

45 Hrs Live Expert-Led Training

upGrad

upGrad KnowledgeHut

Professional Certificate Program in UI/UX Design & Design Thinking

#1 Course for UI/UX Designers

Bootcamp

3 Months