TreeMap in Java

What is TreeMap?

  • It is a Red-Black tree based NavigableMap implementation.
  • Like HashMap it contains only unique elements.
  • Unlike HashMap it cannot have null key but like HashMap it can have multiple null values.
  • The map is sorted according to the natural ordering (ascending order) of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.


TreeMap provides guaranteed log(n) time cost for the containsKey(), get(), put() and remove() operations.

Accessing in multi-threaded environment

Like HashMap and LinkedHashMap, the TreeMap implementation is not synchronized.

So multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be “wrapped” using the Collections.synchronizedMap() method. This is best done at creation time, to prevent accidental unsynchronized access to the map:

Map m = Collections.synchronizedMap(new TreeMap(...));

For multi-threaded environment you can use ConcurrentHashMap instead of Synchronized TreeMap if you do not need the natural ordering of the keys but if you have same number of reader and writer threads then ConcurrentHashMap and Synchronized TreeMap will give the same performance. Therefore ConcurrentHashMap will give you best performance when you have many reader threads and very few writer threads.

More information could be found at

Fail-fast in TreeMap

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

Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

The fail-fast behavior of an iterator cannot be guaranteed and iterators throw ConcurrentModificationException on a best-effort basis.

Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

Set keys = treeMap.keySet();
for (Object key : keys) {
    treeMap.put(someObject, someValue); //it will throw the ConcurrentModificationException here


Set keys = treeMap.keySet();
for (Object key : keys) {
    treeMap.remove(key); //it will throw the ConcurrentModificationException here


package com.roytuts.collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
public class TreeMapExample {
    public static void main(String[] args) {
        Map<String, String> llMap = new TreeMap<>();
        llMap.put("RedHat", "Unix");
        llMap.put("Google", "Android");
        llMap.put("Apple", "iOS");
        llMap.put("Microsoft", "Windows");
        // iterate over HashMap
        llMap.forEach((k, v) -> System.out.println(k + " => " + v));
        // iterate using iterator
        Iterator<Entry<String, String>> iterator = llMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<java.lang.String, java.lang.String> entry = (Map.Entry<java.lang.String, java.lang.String>) iterator
            System.out.println(entry.getKey() + " => " + entry.getValue());


Apple => iOS
Google => Android
Microsoft => Windows
RedHat => Unix
Apple => iOS
Google => Android
Microsoft => Windows
RedHat => Unix

Thanks for reading.

Leave a Comment