Fundamentals 19 min read

Unlocking Java’s HashMap & ConcurrentHashMap: Deep Dive into JDK 1.7 vs 1.8 Implementations

Explore the inner workings of Java’s HashMap and ConcurrentHashMap across JDK 1.7 and 1.8, examining their data structures, key methods like put and get, performance optimizations such as treeification, concurrency mechanisms, and practical insights for developers aiming to master these core collections.

Programmer DD
Programmer DD
Programmer DD
Unlocking Java’s HashMap & ConcurrentHashMap: Deep Dive into JDK 1.7 vs 1.8 Implementations

Preface

Map-like key‑value structures are classic in software development for in‑memory data storage. Before discussing the concurrent container ConcurrentHashMap , it is essential to understand HashMap , as the former builds upon it.

HashMap

Base 1.7

In JDK 1.7 the internal structure is an array plus linked list. Key member variables include initial bucket size, maximum bucket size, default load factor (0.75), the table array that stores data, map size, and bucket size.

Load factor determines when the map expands: with default capacity 16 and load factor 0.75, expansion occurs after 12 entries, triggering rehash and data copy, which is costly. Pre‑estimating map size can reduce expansion overhead.

The actual storage array is declared as:

transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;

Each Entry holds key, value, hash, and next (for the linked list).

put method

public V put(K key, V value) { ... }

Check if the table needs initialization.

If key is null, delegate to putForNullKey.

Compute hash, locate bucket, traverse linked list to find matching key, replace value if found.

If bucket is empty, create a new Entry.

After insertion, check if resizing is needed.

get method

public V get(Object key) { ... }

Compute hash, locate bucket.

If bucket is empty, return null.

Check first node; if it matches, return its value.

If the bucket is a tree, use tree lookup; otherwise traverse the linked list.

In JDK 1.8 the structure is similar but introduces TREEIFY_THRESHOLD to convert long chains into red‑black trees, improving lookup from O(N) to O(log N).

Base 1.8

Key differences: TREEIFY_THRESHOLD determines when a bucket becomes a tree.

Internal class renamed from HashEntry to Node.

The core methods put and get follow the same logical steps, with the added tree conversion for large buckets.

ConcurrentHashMap

ConcurrentHashMap also has 1.7 and 1.8 versions. Both use segment‑based locking (1.7) or CAS plus synchronized (1.8) to achieve thread safety.

Base 1.7

Structure consists of a Segment[] array, each Segment extending ReentrantLock. Inside each segment is a volatile HashEntry<K,V>[] table, count, modCount, threshold, and load factor.

Operations locate the appropriate segment, then lock it before performing put or get. The put method acquires the segment lock, checks for existing keys, updates or inserts entries, and may trigger resizing.

put method (1.7)

public V put(K key, V value) { ... }

Steps:

Validate value is not null.

Compute hash and segment index.

Ensure the segment exists.

Delegate to Segment.put, which locks the segment and inserts or updates the entry.

get method (1.7)

public V get(Object key) { ... }

Locates the segment, then reads the volatile table without locking, traversing the bucket’s linked list or tree to find the value.

Base 1.8

JDK 1.8 removes the segment concept, using a single volatile Node<K,V>[] table. Concurrency is achieved with CAS for fast paths and synchronized blocks for updates.

put method (1.8)

public V put(K key, V value) { ... }

Compute hash.

Initialize table if necessary.

Locate bucket; if empty, attempt CAS to insert a new node.

If the bucket contains a moved marker, trigger resizing.

If a node exists, synchronize on the bucket, insert or update, and treeify if size exceeds TREEIFY_THRESHOLD.

get method (1.8)

public V get(Object key) { ... }

Computes hash, locates the bucket, and then:

If the first node matches, return its value.

If the bucket is a tree, perform tree lookup.

Otherwise traverse the linked list.

All reads are lock‑free because the node’s value field is volatile, guaranteeing visibility.

Summary

Both HashMap and ConcurrentHashMap evolved from JDK 1.7 to 1.8. HashMap introduced treeification to improve lookup performance, while ConcurrentHashMap shifted from segment locks to CAS and synchronized, leveraging the same treeification technique for scalability. Understanding these implementations helps developers answer interview questions and write efficient, thread‑safe code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaconcurrencyJDKHashMapConcurrentHashMap
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.