Skip to content
Related Articles

Related Articles

Getting submap, headmap, and tailmap from Java TreeMap
  • Difficulty Level : Expert
  • Last Updated : 07 Jan, 2021

The TreeMap is used to implement Map interface and Navigable Map with the AbstractMap class in Java. Various constructors can be used in the TreeMap by to maintain the sorted ordering of its keys.

A. subMap() method of TreeMap

The subMap() method in Java is used to return the part or portion of the map defined by the specified range of keys in the parameter.

Syntax:

newTreeMap = oldTreeMap.subMap(startKey,endKey)
  • startKey: The starting point or lower end of the map including which the points are to be considered.
  • endKey: The endpoint or the higher end of the map excluding which the points are to be considered.

Return Type:



Returns another map containing the portion of the map within the specified range.

Implementation:

Java




// Java code to illustrate submap() Method
  
import java.util.*;
  
class GFG {
    public static void main(String[] args)
    {
        TreeMap<Integer, String> tree
            = new TreeMap<Integer, String>();
  
        // Mapping String to Integer
        tree.put(47, "Sashi");
        tree.put(82, "Ridhi");
        tree.put(66, "Himanshu");
        tree.put(98, "Sarthak");
        tree.put(87, "Sonika");
        tree.put(85, "Ritesh");
        tree.put(89, "Yogesh");
  
        // printing the complete TreeMap
        System.out.println("The original map is: \n"
                           + tree);
  
        // printing the submap from key
        // 67(included) to 89(excluded)
        System.out.println("The subMap is: \n"
                           + tree.subMap(67, 89));
  
        // if start key and end key are same then
        // this method returns a null map
        System.out.println("Empty subMap: \n"
                           + tree.subMap(67, 67));
    }
}
Output
The original map is: 
{47=Sashi, 66=Himanshu, 82=Ridhi, 85=Ritesh, 87=Sonika, 89=Yogesh, 98=Sarthak}
The subMap is: 
{82=Ridhi, 85=Ritesh, 87=Sonika}
Empty subMap: 
{}

B. headMap() method of TreeMap

The headMap() method of the TreeMap class is used to get all the pairs or portions of the map strictly less than the parameter key_value.

Syntax:

newTreeMap = oldTreeMap.headMap(specifiedKey)

Return Type:

The method returns the portion of the map whose keys are less than the specified key.

Implementation:

Java




// Java code to illustrate headmap() method
import java.util.*;
  
class GFG {
    public static void main(String[] args)
    {
        TreeMap<Integer, String> tree
            = new TreeMap<Integer, String>();
  
        // Mapping String to Integer
        tree.put(47, "Sashi");
        tree.put(82, "Ridhi");
        tree.put(66, "Himanshu");
        tree.put(98, "Sarthak");
        tree.put(87, "Sonika");
        tree.put(85, "Ritesh");
        tree.put(89, "Yogesh");
  
        // printing the complete TreeMap
        System.out.println("The original map is: \n"
                           + tree);
  
        // this will print all the key-value
        // pairs which are less than 67
        System.out.println("The headMap is: \n"
                           + tree.headMap(67));
    }
}
Output



The original map is: 
{47=Sashi, 66=Himanshu, 82=Ridhi, 85=Ritesh, 87=Sonika, 89=Yogesh, 98=Sarthak}
The headMap is: 
{47=Sashi, 66=Himanshu}

C. tailMap() method of TreeMap

The tailMap() method in Java is used to get a part or view of the map whose keys are greater than equal to the from_key in the parameter.

Syntax:

newMap = oldMap.tailMap(specifiedKey)

Return Type:

This method returns a map in which keys are greater than or equal to the specified key.

Implementation:

Java




// Java code to illustrate tailmap() Method
import java.util.*;
  
class GFG {
    public static void main(String[] args)
    {
        TreeMap<Integer, String> tree
            = new TreeMap<Integer, String>();
  
        // Mapping String to Integer
        tree.put(47, "Sashi");
        tree.put(82, "Ridhi");
        tree.put(66, "Himanshu");
        tree.put(98, "Sarthak");
        tree.put(87, "Sonika");
        tree.put(85, "Ritesh");
        tree.put(89, "Yogesh");
  
        // printing the complete TreeMap
        System.out.println("The original map is: \n"
                           + tree);
  
        // this will print all the key-value pairs
        // which are greater than or equal to 67
        System.out.println("The tailMap is: \n"
                           + tree.tailMap(67));
    }
}
Output
The original map is: 
{47=Sashi, 66=Himanshu, 82=Ridhi, 85=Ritesh, 87=Sonika, 89=Yogesh, 98=Sarthak}
The tailMap is: 
{82=Ridhi, 85=Ritesh, 87=Sonika, 89=Yogesh, 98=Sarthak}

Important point: Any change made to the map returned by the methods subMap(), headMap() , tailMap(), will be reflected in the original map also.

Implementation:

Java




// Combine operation on getting submap,
// headmap, and tailmap from Java TreeMap
  
import java.util.*;
  
class GFG {
    public static void main(String[] args)
    {
        TreeMap<Integer, String> originalTree
            = new TreeMap<Integer, String>();
  
        // Mapping String to Integer
        originalTree.put(82, "Ridhi");
        originalTree.put(87, "Sonika");
        originalTree.put(85, "Ritesh");
        originalTree.put(89, "Yogesh");
        originalTree.put(80, "Yashdeep");
        originalTree.put(99, "Raushan");
        originalTree.put(67, "Shishya");
  
        // printing the complete TreeMap
        System.out.println("The original map is: \n"
                           + originalTree);
  
        // submap from key 67(included) to 89(excluded)
        Map<Integer, String> newSubMap
            = originalTree.subMap(67, 89);
  
        // doing some modification in map named
        // newSubMap and this modification is going to
        // be refelected in the original treemap also
        newSubMap.remove(67);
  
        // printing the original treemap to see the
        // modification
        System.out.println(
            "The original map after remove operation is: \n"
            + originalTree);
  
        // creating a new map named newHeadMap
        Map<Integer, String> newHeadMap
            = originalTree.headMap(87);
  
        // doing some modification in map named
        // newHeadMap and this modification is going to
        // be refelected in the original treemap also
        newHeadMap.remove(82);
  
        // printing the original
        // treemap to see the modification
        System.out.println(
            "The original map after remove operation: \n"
            + originalTree);
  
        // creating a new map named newTailMap
        Map<Integer, String> newTailMap
            = originalTree.tailMap(85);
  
        // doing some modification in map named
        // newHeadMap and this modification is going to
        // be refelected in the original treemap also
        newTailMap.put(94, "Ankit");
  
        // printing the original treemap
        // to see the modification
        System.out.println(
            "The original map after put operation is: \n"
            + originalTree);
    }
}
Output
The original map is: 
{67=Shishya, 80=Yashdeep, 82=Ridhi, 85=Ritesh, 87=Sonika, 89=Yogesh, 99=Raushan}
The original map after remove operation is: 
{80=Yashdeep, 82=Ridhi, 85=Ritesh, 87=Sonika, 89=Yogesh, 99=Raushan}
The original map after remove operation: 
{80=Yashdeep, 85=Ritesh, 87=Sonika, 89=Yogesh, 99=Raushan}
The original map after put operation is: 
{80=Yashdeep, 85=Ritesh, 87=Sonika, 89=Yogesh, 94=Ankit, 99=Raushan}

Note: If trying to put an entry in the map which is out of the range of the map returned by those three methods, the code will throw an IllegalArgumentException.

Implementation:

Java




// Exception when trying to put an entry in
// the map which is out of the range of the map
import java.util.*;
  
class GFG {
    public static void main(String[] args)
    {
        TreeMap<Integer, String> originalTree
            = new TreeMap<Integer, String>();
  
        // Mapping String to Integer
        originalTree.put(47, "Sashi");
        originalTree.put(82, "Ridhi");
        originalTree.put(66, "Himanshu");
        originalTree.put(98, "Sarthak");
        originalTree.put(87, "Sonika");
        originalTree.put(85, "Ritesh");
        originalTree.put(89, "Yogesh");
        originalTree.put(80, "Yashdeep");
        originalTree.put(99, "Raushan");
        originalTree.put(67, "Shishya");
  
        // printing the complete TreeMap
        System.out.println("The original map is: \n"
                           + originalTree);
  
        // submap from key 67(included) to 89(excluded)
        Map<Integer, String> newSubMap
            = originalTree.subMap(67, 89);
  
        // This will throw an exception because
        // we can give key in between 67 - 89
        newSubMap.put(89, "Sandra");
  
        Map<Integer, String> newHeadMap
            = originalTree.headMap(87);
  
        // This will throw an exception because
        // in newHeadMap we can only put key < 87
        newHeadMap.put(98, "Aman");
  
        Map<Integer, String> newTailMap
            = originalTree.tailMap(87);
  
        // This will throw an exception because
        // in newTailMap we can only put key >= 87
        newTailMap.put(86, "Aman");
    }
}

Output:

Exception in thread "main" java.lang.IllegalArgumentException: key out of range
    at java.base/java.util.TreeMap$NavigableSubMap.put(TreeMap.java:1513)
    at GFG.main(File.java:29)

Implementation on User-Defined class:

In this example instead of using a wrapper class as a value, use the user-defined class as a value and will use methods subMap(), headMap() and tailMap(). This example is only for better understanding and better use of those three methods.

Implementation:

Java




// submap, headmap, and tailmap from Java
// TreeMap on User-Defined class
import java.util.Map;
import java.util.TreeMap;
// user defined class
class friendsDetail {
  
    // class field
    private String name;
    private String nickName;
  
    // parameterised constructor
    public friendsDetail(String name, String nickName)
    {
        this.name = name;
        this.nickName = nickName;
    }
  
    // getter for name
    public String getName() { return name; }
  
    // setter for name
    public void setName(String name) { this.name = name; }
  
    // getter for nickname
    public String getnickName() { return nickName; }
  
    // setter for nickname
    public void setNickName(int id)
    {
        this.nickName = nickName;
    }
  
    // overriding toString method
    public String toString()
    {
        // return super.toString();
        return "(" + this.getName() + ":"
            + this.getnickName() + ")";
    }
}
public class GFG {
  
    public static void main(String[] args)
    {
        // Mapping user defined class to Integer
        TreeMap<Integer, friendsDetail> originalTree
            = new TreeMap<>();
        originalTree.put(2029, new friendsDetail(
                                   "Raushan", "Chamgader"));
        originalTree.put(
            2022, new friendsDetail("Yashdeep", "Dopa"));
        originalTree.put(
            2019, new friendsDetail("Shishya", "Gorilla"));
        originalTree.put(
            2021, new friendsDetail("Sonika", "Chipkali"));
        originalTree.put(
            2025, new friendsDetail("Himanshu", "Lalten"));
        originalTree.put(
            2023, new friendsDetail("Sarthak", "Nagin"));
        originalTree.put(
            2020, new friendsDetail("Tsering", "Battak"));
        originalTree.put(
            2018, new friendsDetail("Abhishek", "Liquid"));
  
        // printing our original class
        System.out.println("This is original treemap");
        for (Map.Entry<Integer, friendsDetail> map :
             originalTree.entrySet()) {
            System.out.println("Name: " + map.getKey()
                               + " \t Name & Nickname: "
                               + map.getValue());
        }
  
        // printing submap from 2020 to 2024
        System.out.println("\n\nThis is submap");
        Map<Integer, friendsDetail> subMap
            = originalTree.subMap(2020, 2024);
        for (Map.Entry<Integer, friendsDetail> map :
             subMap.entrySet()) {
            System.out.println("Name: " + map.getKey()
                               + " \t Name & Nickname: "
                               + map.getValue());
        }
  
        // printing headmap for keys < 2020
        System.out.println("\n\nThis is headmap");
        Map<Integer, friendsDetail> headMap
            = originalTree.headMap(2020);
        for (Map.Entry<Integer, friendsDetail> map :
             headMap.entrySet()) {
            System.out.println("Name: " + map.getKey()
                               + " \t Name & Nickname: "
                               + map.getValue());
        }
  
        // printing tailmap for keys >=2025
        System.out.println("\n\nThis is tailmap");
        Map<Integer, friendsDetail> tailMap
            = originalTree.tailMap(2025);
        for (Map.Entry<Integer, friendsDetail> map :
             tailMap.entrySet()) {
            System.out.println("Name: " + map.getKey()
                               + " \t Name & Nickname: "
                               + map.getValue());
        }
    }
}
Output
This is original treemap
Name: 2018      Name & Nickname: (Abhishek:Liquid)
Name: 2019      Name & Nickname: (Shishya:Gorilla)
Name: 2020      Name & Nickname: (Tsering:Battak)
Name: 2021      Name & Nickname: (Sonika:Chipkali)
Name: 2022      Name & Nickname: (Yashdeep:Dopa)
Name: 2023      Name & Nickname: (Sarthak:Nagin)
Name: 2025      Name & Nickname: (Himanshu:Lalten)
Name: 2029      Name & Nickname: (Raushan:Chamgader)


This is submap
Name: 2020      Name & Nickname: (Tsering:Battak)
Name: 2021      Name & Nickname: (Sonika:Chipkali)
Name: 2022      Name & Nickname: (Yashdeep:Dopa)
Name: 2023      Name & Nickname: (Sarthak:Nagin)


This is headmap
Name: 2018      Name & Nickname: (Abhishek:Liquid)
Name: 2019      Name & Nickname: (Shishya:Gorilla)


This is tailmap
Name: 2025      Name & Nickname: (Himanshu:Lalten)
Name: 2029      Name & Nickname: (Raushan:Chamgader)

Attention reader! Don’t stop learning now. Get hold of all the important Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :