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 )); } } |
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 )); } } |
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 )); } } |
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 reflected 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 reflected 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 reflected 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); } } |
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()); } } } |
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)