o7planning

Java NavigableMap Tutorial with Examples

  1. NavigableMap
  2. NavigableMap Methods
  3. Examples
  4. descendingMap()
  5. navigableKeySet()
  6. descendingKeySet()
  7. subMap(K, boolean, K, boolean)
  8. headMap(K, boolean)
  9. tailMap(K, boolean)
  10. firstEntry()
  11. lastEntry()
  12. pollFirstEntry()
  13. pollLastEntry()
  14. lowerKey(K key)
  15. lowerEntry(K key)
  16. floorKey(K key)
  17. floorEntry(K key)
  18. ceilingKey(K key)
  19. ceilingEntry(K key)
  20. higherKey(K key)
  21. higherEntry(K key)

1. NavigableMap

NavigableMapis a subinterface of SortedMap interface, so it works like a SortedMap. In addition, it is supplemented with methods that allow navigating, searching for keys, and mappings.
For example, NavigableMap allows navigating in ascending or descending order of keys, providing methods like lowerKey, floorKey, ceilingKey, higherKey, lowerEntry, floorEntry, ceilingEntry, higherEntry.. to search for keys and mappings.
public interface NavigableMap<K,V> extends SortedMap<K,V>
Map<K,V>
SortedMap<K,V>
NavigableMap<K,V>
Duplicate keys are not allowed.
Can allow null key and null values.
Keys order is not guaranteed.
The keys are sorted in ascending order based on their natural order or according to a supplied Comparator.
All keys of NavigableMap/SortedMap must be Comparable type or you must provide a Comparator for NavigableMap/SortedMap so that it compares keys. Otherwise, ClassCastException will be thrown.

2. NavigableMap Methods

Map.Entry<K,V> firstEntry();
Map.Entry<K,V> lastEntry();
Map.Entry<K,V> pollFirstEntry();
Map.Entry<K,V> pollLastEntry();

Map.Entry<K,V> lowerEntry(K key);
Map.Entry<K,V> floorEntry(K key);
Map.Entry<K,V> ceilingEntry(K key);
Map.Entry<K,V> higherEntry(K key);

K lowerKey(K key);
K floorKey(K key);
K ceilingKey(K key);
K higherKey(K key);  

NavigableMap<K,V> descendingMap();
NavigableSet<K> navigableKeySet();
NavigableSet<K> descendingKeySet();

NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
                        K toKey,   boolean toInclusive);

NavigableMap<K,V> headMap(K toKey, boolean inclusive);
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);

// Inherited from SortedSet:
SortedMap<K,V> subMap(K fromKey, K toKey);
SortedMap<K,V> headMap(K toKey);
SortedMap<K,V> tailMap(K fromKey);
...

3. Examples

Example: A NavigableMap<Integer,String> object contains mappings between the year of the World Cup and the host country. We use some of its methods to navigate, find keys and mappings.
NavigableMapEx1.java
package org.o7planning.navigablemap.ex;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

public class NavigableMapEx1 {

    public static void main(String[] args) {
        // Map: World Cup Year --> Country Name
        NavigableMap<Integer, String> worldCupMap = new TreeMap<>();

        worldCupMap.put(1934, "Italy");
        worldCupMap.put(1930, "Uruguay");
        worldCupMap.put(1970, "Mexico");
        worldCupMap.put(1966, "England");
        worldCupMap.put(1962, "Chile");
        worldCupMap.put(1958, "Sweden");
        worldCupMap.put(1954, "Switzerland");
        worldCupMap.put(1950, "Brazil");
        worldCupMap.put(1938, "France");

        System.out.println("--- World Cup Map ---:");
        printMap(worldCupMap);

        // Get a reverse view of the navigable map.
        NavigableMap<Integer, String> reverseMap = worldCupMap.descendingMap();

        System.out.println("\n--- World Cup Map (Reverse View) ---:");
        printMap(reverseMap);

        // World Cup Map (Year >= 1935)
        NavigableMap<Integer, String> tailMap1 = worldCupMap.tailMap(1935, true);

        System.out.println("\n--- World Cup Map (Year >= 1935) ---:");
        printMap(tailMap1);

        // World Cup Map (Year <= 1958)
        NavigableMap<Integer, String> headMap1 = worldCupMap.headMap(1938, true);

        System.out.println("\n--- World Cup Map (Year <= 1938) ---:");
        printMap(headMap1);

        // The first year of the World Cup after 1938.
        int year1 = worldCupMap.higherKey(1938);
        System.out.printf("%nThe first year of the World Cup after 1938: %d%n", year1);

        // The last year of the World Cup before 1950.
        int year2 = worldCupMap.lowerKey(1950);
        System.out.printf("%nThe last year of the World Cup before 1950: %d%n", year2);

        // The first World Cup after 1938.
        Map.Entry<Integer, String> e1 = worldCupMap.higherEntry(1938);
        System.out.printf("%nThe first World Cup after 1938: %d --> %s%n", e1.getKey(), e1.getValue());

        // The last World Cup before 1950.
        Map.Entry<Integer, String> e2 = worldCupMap.lowerEntry(1950);
        System.out.printf("%nThe last World Cup before 1950: %d --> %s%n", e2.getKey(), e2.getValue());
    }

    private static void printMap(Map<Integer, String> map) {
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        }
    }
}
Output:
--- World Cup Map ---:
1930 --> Uruguay
1934 --> Italy
1938 --> France
1950 --> Brazil
1954 --> Switzerland
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

--- World Cup Map (Reverse View) ---:
1970 --> Mexico
1966 --> England
1962 --> Chile
1958 --> Sweden
1954 --> Switzerland
1950 --> Brazil
1938 --> France
1934 --> Italy
1930 --> Uruguay

--- World Cup Map (Year >= 1935) ---:
1938 --> France
1950 --> Brazil
1954 --> Switzerland
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

--- World Cup Map (Year <= 1938) ---:
1930 --> Uruguay
1934 --> Italy
1938 --> France

The first year of the World Cup after 1938: 1950

The last year of the World Cup before 1950: 1938

The first World Cup after 1938: 1950 --> Brazil

The last World Cup before 1950: 1938 --> France
See more examples of how to use Comparator for NavigableMap/SortedMap:

4. descendingMap()

NavigableMap<K,V> descendingMap();
Returns a reverse order view of the mappings contained in this NavigableMap. The returned NavigableMap will be sorted in descending order by key.
The returned NavigableMap is related to the current NavigableMap. Changes on one NavigableMap affect the other NavigableMap and vice versa.
NavigableMap_descendingMap_ex1.java
package org.o7planning.navigablemap.ex;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

public class NavigableMap_descendingMap_ex1 {

    public static void main(String[] args) {
        // Map: World Cup Year --> Country Name
        NavigableMap<Integer, String> worldCupMap = new TreeMap<>();

        worldCupMap.put(1934, "Italy");
        worldCupMap.put(1930, "Uruguay");
        worldCupMap.put(1970, "Mexico");
        worldCupMap.put(1966, "England");
        worldCupMap.put(1962, "Chile");
        worldCupMap.put(1958, "Sweden");
        worldCupMap.put(1954, "Switzerland");
        worldCupMap.put(1950, "Brazil");
        worldCupMap.put(1938, "France");

        System.out.println("--- World Cup Map ---:");
        printMap(worldCupMap);

        // Get a reverse view of the navigable map.
        NavigableMap<Integer, String> reverseMap = worldCupMap.descendingMap();

        System.out.println("\n--- World Cup Map (Reverse View) ---:");
        printMap(reverseMap);
    }

    private static void printMap(Map<Integer, String> map) {
        // Java 8 Syntax:
        map.entrySet().stream().forEach(entry -> {
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        });
    }
}
Output:
--- World Cup Map ---:
1930 --> Uruguay
1934 --> Italy
1938 --> France
1950 --> Brazil
1954 --> Switzerland
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

--- World Cup Map (Reverse View) ---:
1970 --> Mexico
1966 --> England
1962 --> Chile
1958 --> Sweden
1954 --> Switzerland
1950 --> Brazil
1938 --> France
1934 --> Italy
1930 --> Uruguay

5. navigableKeySet()

NavigableSet<K> navigableKeySet();
Returns a NavigableSet view of the keys contained in this NavigableMap.
The returned NavigableMap is related to the current NavigableMap. Changes on one NavigableMap affect the other NavigableMap and vice versa.
  • Adding or removing a mapping from NavigableMap will add or remove an element from NavigableSet.
  • Methods to remove elements from NavigableSet such as Set.iterator().remove, Set.remove, Set.removeAll, Set.retainAll, Set.clear.. remove the corresponding mappings from NavigableMap.
  • This NavigableSet object does not support Set.add, Set.addAll operations.
NavigableMap_navigableKeySet_ex1.java
package org.o7planning.navigablemap.ex;

import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.TreeMap;

public class NavigableMap_navigableKeySet_ex1 {

    public static void main(String[] args) {
        // Map: World Cup Year --> Country Name
        NavigableMap<Integer, String> worldCupMap = new TreeMap<>();

        worldCupMap.put(1934, "Italy");
        worldCupMap.put(1930, "Uruguay");
        worldCupMap.put(1970, "Mexico");
        worldCupMap.put(1966, "England");
        worldCupMap.put(1962, "Chile");
        worldCupMap.put(1958, "Sweden");
        worldCupMap.put(1954, "Switzerland");
        worldCupMap.put(1950, "Brazil");
        worldCupMap.put(1938, "France");

        System.out.println("--- World Cup Map ---:");
        printMap(worldCupMap);

        NavigableSet<Integer> navigableSetYears = worldCupMap.navigableKeySet();
        System.out.println("\nYears: " + navigableSetYears);
        
        // Remove some years from NavigableSet navigableSetYears
        navigableSetYears.remove(1954);
        navigableSetYears.remove(1950);
        navigableSetYears.remove(1938);
        navigableSetYears.remove(1934);
        navigableSetYears.remove(1930);
        
        System.out.println("\n--- World Cup Map (After removing some years from NavigableSet) ---:");
        printMap(worldCupMap);
    }

    private static void printMap(Map<Integer, String> map) {
        // Java 8 Syntax:
        map.entrySet().stream().forEach(entry -> {
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        });
    }
}
Output:
--- World Cup Map ---:
1930 --> Uruguay
1934 --> Italy
1938 --> France
1950 --> Brazil
1954 --> Switzerland
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

Years: [1930, 1934, 1938, 1950, 1954, 1958, 1962, 1966, 1970]

--- World Cup Map (After removing some years from NavigableSet) ---:
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

6. descendingKeySet()

NavigableSet<K> descendingKeySet();
Returns a reverse order NavigableSet view of the keys contained in this NavigableMap. Equivalent to calling descendingMap().navigableKeySet().
The returned NavigableMap is related to the current NavigableMap. Changes on one NavigableMap affect the other NavigableMap and vice versa.
  • Adding or removing a mapping from NavigableMap will add or remove an element from NavigableSet.
  • Methods to remove elements from NavigableSet such as Set.iterator().remove, Set.remove, Set.removeAll, Set.retainAll, Set.clear.. remove the corresponding mappings from NavigableMap.
  • This NavigableSet object does not support Set.add, Set.addAll operations.
NavigableMap_descendingKeySet_ex1.java
package org.o7planning.navigablemap.ex;

import java.util.Iterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.TreeMap;

public class NavigableMap_descendingKeySet_ex1 {

    public static void main(String[] args) {
        // Map: World Cup Year --> Country Name
        NavigableMap<Integer, String> worldCupMap = new TreeMap<>();

        worldCupMap.put(1934, "Italy");
        worldCupMap.put(1930, "Uruguay");
        worldCupMap.put(1970, "Mexico");
        worldCupMap.put(1966, "England");
        worldCupMap.put(1962, "Chile");
        worldCupMap.put(1958, "Sweden");
        worldCupMap.put(1954, "Switzerland");
        worldCupMap.put(1950, "Brazil");
        worldCupMap.put(1938, "France");

        System.out.println("--- World Cup Map ---:");
        printMap(worldCupMap);

        NavigableSet<Integer> descendingKeySetYears = worldCupMap.descendingKeySet();
        System.out.println("\nDescending Years: " + descendingKeySetYears);
        
        // Remove some years from NavigableSet descendingKeySetYears
        Iterator<Integer> iterator = descendingKeySetYears.iterator();
        
        while(iterator.hasNext())  {
            Integer year = iterator.next();
            if(year <= 1954) {
                iterator.remove();
            }
        }
        
        System.out.println("\n--- World Cup Map (After removing some years from NavigableSet) ---:");
        printMap(worldCupMap);
    }

    private static void printMap(Map<Integer, String> map) {
        // Java 8 Syntax:
        map.entrySet().stream().forEach(entry -> {
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        });
    }
}
Output:
--- World Cup Map ---:
1930 --> Uruguay
1934 --> Italy
1938 --> France
1950 --> Brazil
1954 --> Switzerland
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

Descending Years: [1970, 1966, 1962, 1958, 1954, 1950, 1938, 1934, 1930]

--- World Cup Map (After removing some years from NavigableSet) ---:
1958 --> Sweden
1962 --> Chile
1966 --> England
1970 --> Mexico

7. subMap(K, boolean, K, boolean)

NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
                                                K toKey,   boolean toInclusive);
Returns a view of a portion of this NavigableMap that includes mappings with keys ranging from fromKey to toKey. Include fromKey if fromInclusive is true, including toKey if toInclusive is true.
The returned NavigableMap is related to the current NavigableMap. Changes on one NavigableMap affect the other NavigableMap and vice versa.
NavigableMap_subMap_ex1.java
package org.o7planning.navigablemap.ex;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

public class NavigableMap_subMap_ex1 {

    public static void main(String[] args) {
        NavigableMap<String, String> myMap = new TreeMap<>();

        myMap.put("A", "VA");
        myMap.put("B", "VB");
        myMap.put("C", "VC");
        myMap.put("D", "VD");
        myMap.put("E", "VE");

        System.out.println(" -- myMap --");
        printMap(myMap);

        // A Sub Map ("B" <= key <= "C1")
        NavigableMap<String, String> subMap = myMap.subMap("B", true, "C1", true);

        System.out.println("\n -- subMap --");
        printMap(subMap);

        subMap.put("B1", "VB1");
        subMap.put("B2", "VB2");

        System.out.println("\n -- subMap (after putting some mappings to subMap) --");
        printMap(subMap);

        System.out.println("\n -- myMap (after putting some mappings to subMap) --");
        printMap(myMap);
    }

    private static void printMap(Map<String, String> map) {
        for (String s : map.keySet()) {
            System.out.println(s + " --> " + map.get(s));
        }
    }
}
Output:
-- myMap --
A --> VA
B --> VB
C --> VC
D --> VD
E --> VE

 -- subMap --
B --> VB
C --> VC

 -- subMap (after putting some mappings to subMap) --
B --> VB
B1 --> VB1
B2 --> VB2
C --> VC

 -- myMap (after putting some mappings to subMap) --
A --> VA
B --> VB
B1 --> VB1
B2 --> VB2
C --> VC
D --> VD
E --> VE

8. headMap(K, boolean)

NavigableMap<K,V> headMap(K toKey, boolean inclusive);
Return a view of a portion of this NavigableMap, including mappings whose key is less than (or equal, if inclusive is true) toKey.
The returned NavigableMap is related to the current NavigableMap. Changes on one NavigableMap affect the other NavigableMap and vice versa.

9. tailMap(K, boolean)

NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
Returns a view of a portion of this NavigableMap, including mappings whose key is greater than (or equal, if inclusive is true) fromKey.
The returned NavigableMap is related to the current NavigableMap. Changes on one NavigableMap affect the other NavigableMap and vice versa.
NavigableMap_tailMap_ex1.java
package org.o7planning.navigablemap.ex;

import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;

public class NavigableMap_tailMap_ex1 {

    public static void main(String[] args) {
        NavigableMap<String, String> myMap = new TreeMap<>();

        myMap.put("A", "VA");
        myMap.put("B", "VB");
        myMap.put("C", "VC");
        myMap.put("D", "VD");
        myMap.put("E", "VE");

        System.out.println(" -- myMap --");
        printMap(myMap);

        // A Tail Map (key >= "C")
        NavigableMap<String, String> tailMap = myMap.tailMap("C", true);

        System.out.println("\n -- tailMap --");
        printMap(tailMap);

        myMap.put("B1", "VB1");
        myMap.put("D1", "VD1");
        
        System.out.println("\n -- myMap (after putting some mappings to myMap) --");
        printMap(myMap);

        System.out.println("\n -- tailMap (after putting some mappings to myMap) --");
        printMap(tailMap);
    }

    private static void printMap(Map<String, String> map) {
        for (String s : map.keySet()) {
            System.out.println(s + " --> " + map.get(s));
        }
    }
}
Output:
-- myMap --
A --> VA
B --> VB
C --> VC
D --> VD
E --> VE

 -- tailMap --
C --> VC
D --> VD
E --> VE

 -- myMap (after putting some mappings to myMap) --
A --> VA
B --> VB
B1 --> VB1
C --> VC
D --> VD
D1 --> VD1
E --> VE

 -- tailMap (after putting some mappings to myMap) --
C --> VC
D --> VD
D1 --> VD1
E --> VE

10. firstEntry()

Map.Entry<K,V> firstEntry();
Return the first mapping (with the smallest key) in this NavigableMap, or null if the NavigableMap is empty.

11. lastEntry()

Map.Entry<K,V> lastEntry();
Return the last mapping (with the largest key) in this NavigableMap, or null if the NavigableMap is empty.

12. pollFirstEntry()

Map.Entry<K,V> pollFirstEntry();
Remove and return the first mapping in this NavigableMap, or null if the NavigableMap is empty.

13. pollLastEntry()

Map.Entry<K,V> pollLastEntry();
Remove and return the last mapping in this NavigableMap, or null if the NavigableMap is empty.

14. lowerKey(K key)

K lowerKey(K key);
Returns the largest key in this NavigableMap but less than the given key, or null if there is no such key.

15. lowerEntry(K key)

Map.Entry<K,V> lowerEntry(K key);
Return the mapping with the largest key in this NavigableMap but less than the given key, or null if there is no such mapping.

16. floorKey(K key)

K floorKey(K key);
Return the largest key in this NavigableMap but less than or equal to the given key, or null if there is no such key.

17. floorEntry(K key)

Map.Entry<K,V> floorEntry(K key);
Return the mapping with the smallest key in this NavigableMap but greater than or equal to the given key, or null if there is no such mapping.

18. ceilingKey(K key)

K ceilingKey(K key);
Return the largest key in this NavigableMap but less than or equal to the given key, or null if there is no such key.

19. ceilingEntry(K key)

Map.Entry<K,V> ceilingEntry(K key);
Return the mapping with the smallest key in this NavigableMap but greater than or equal to the given key, or null if there is no such mapping.

20. higherKey(K key)

K higherKey(K key);
Return the smallest key in this NavigableMap but greater than the given key, or null if there is no such key.

21. higherEntry(K key)

Map.Entry<K,V> higherEntry(K key);
Return the mapping with the smallest key in this NavigableMap but greater than the given key, or null if there is no such mapping.