o7planning

Java NavigableSet Tutorial with Examples

  1. NavigableSet
  2. NavigableSet Methods
  3. Null element
  4. Examples
  5. descendingSet()
  6. descendingIterator()
  7. subSet(..)
  8. headSet(E toElement, boolean inclusive)
  9. tailSet(E fromElement, boolean inclusive)
  10. lower(E e)
  11. higher(E e)
  12. floor(E e)
  13. ceiling(E e)
  14. pollFirst()
  15. pollLast()

1. NavigableSet

NavigableSet is a subinterface of SortedSet, therefore it works like a SortedSet. Also, it has additional methods that allow navigating and finding elements.
For example: NavigableSet allows access and navigation in ascending or descending order and provides methods like lower, floor, ceiling, higher, .. to find elements.
public interface NavigableSet<E> extends SortedSet<E>
Characteristics are inherited from SortedSet:
Set<E>
SortedSet<E> / NavigableSet<E>
Duplicate elements are not allowed.
If you intentionally add a duplicate element to Set, this action will be ignored.
Similar to Set.
Allow at most one null element.
Allow at most one null element.
The order of elements is not guaranteed.
The order of elements is guaranteed.
All elements of SortedSet must be Comparable type or you must provide a Comparator for SortedSet so that it compares the elements.

2. NavigableSet Methods

NavigableSet Methods:
E lower(E e);

E floor(E e);

E ceiling(E e);

E higher(E e);

E pollFirst();

E pollLast();

NavigableSet<E> descendingSet();

Iterator<E> descendingIterator();

NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
                       E toElement,   boolean toInclusive);

NavigableSet<E> headSet(E toElement, boolean inclusive);

NavigableSet<E> tailSet(E fromElement, boolean inclusive);

// --- Methods inherited from SortedSet ------------------------------

Comparator<? super E> comparator();

E first();

E last();

SortedSet<E> subSet(E fromElement, E toElement);

SortedSet<E> headSet(E toElement);

SortedSet<E> tailSet(E fromElement);  

default Spliterator<E> spliterator();  

// --- Other ethods inherited from Set, Collection. ------------------
Iterator<E> iterator();
...

3. Null element

The specification of SortedSet and NavigableSet interface does not mention null elements at all, which means they can allow at most one null element (Inheriting from the specification of Set interface). So whether SortedSet and NavigabletSet allow null element or not depends on the class implementing these interfaces.
In Java Collection Framework, TreeSet class implements NavigableSet interface, which allows null element if you give it a Comparator to handle null element comparison with its other elements. Meanwhile, ConcurrentSkipListSet also implements NavigableSet interface but does not allow null element in any situation.
You can find examples of NavigableSet and null element in the following article:

4. Examples

Example: A NavigableSet<Integer> object containing the years that World Cup was held. Use some of its methods to navigate and find the required element.
NavigableSetEx1.java
package org.o7planning.navigableset.ex;

import java.util.Arrays;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;

public class NavigableSetEx1 {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1970, 1966, 1962, 1958, 1954, 1950, 1938, 1934, 1930);

        // A sorted set in ascending order.
        NavigableSet<Integer> worldCupYears = new TreeSet<Integer>(list);

        System.out.println("World Cup Years: " + worldCupYears);

        // Get a reverse view of the navigable set
        NavigableSet<Integer> reverseYears = worldCupYears.descendingSet();

        System.out.println("Reverse of World Cup Years: " + reverseYears);

        // World Cup Years >= 1935
        NavigableSet<Integer> tailSet1 = worldCupYears.tailSet(1935, true);
        System.out.println("World Cup Years >= 1935: " + tailSet1);

        // World Cup Years <= 1958
        NavigableSet<Integer> headSet1 = worldCupYears.headSet(1938, true);
        System.out.println("World Cup Years <= 1938: " + headSet1);

        // The first year of the World Cup after 1938.
        int year1 = worldCupYears.higher(1938);
        System.out.println("The first year of the World Cup after 1938: " + year1);

        // The last year of the World Cup before 1950.
        int year2 = worldCupYears.lower(1950);
        System.out.println("The last year of the World Cup before 1950: " + year2);
    }
}
Output:
World Cup Years: [1930, 1934, 1938, 1950, 1954, 1958, 1962, 1966, 1970]
Reverse of World Cup Years: [1970, 1966, 1962, 1958, 1954, 1950, 1938, 1934, 1930]
World Cup Years >= 1935: [1938, 1950, 1954, 1958, 1962, 1966, 1970]
World Cup Years <= 1938: [1930, 1934, 1938]
The first year of the World Cup after 1938: 1950
The last year of the World Cup before 1950: 1938
Example: Player class simulates a player with information fullName, goldMedal, silverMedal, bronzeMedal (Full name, number of gold, silver, bronze medals). Player class implements Comparable<Player> interface, so it is comparable.
The principle of comparing two objects Player bases on this principle: Player with more gold medals will be considered to have a higher ranking, then compare the number of silver medals, the number of bronze medals, full name is the final comparison criteria.
Player.java
package org.o7planning.beans;

public class Player implements Comparable<Player> {

    private String fullName;
    private int goldMedal;
    private int silverMedal;
    private int bronzeMedal;

    public Player(String fullName, int goldMedal, int silverMedal, int bronzeMedal) {
        this.fullName = fullName;
        this.goldMedal = goldMedal;
        this.silverMedal = silverMedal;
        this.bronzeMedal = bronzeMedal;
    }

    public String getFullName() {
        return fullName;
    }

    public int getGoldMedal() {
        return goldMedal;
    }

    public int getSilverMedal() {
        return silverMedal;
    }

    public int getBronzeMedal() {
        return bronzeMedal;
    }

    @Override
    public int compareTo(Player o) {
        int g = this.goldMedal - o.goldMedal;
        if (g != 0) {
            return g;
        }
        int s = this.silverMedal - o.silverMedal;
        if (s != 0) {
            return s;
        }
        int b = this.bronzeMedal - o.bronzeMedal;
        if (b != 0) {
            return b;
        }
        return this.fullName.compareTo(o.fullName);
    }
}
Example: A NavigableSet contains Player objects:
NavigableSetEx2.java
package org.o7planning.navigableset.ex;

import java.util.NavigableSet;
import java.util.TreeSet;

import org.o7planning.beans.Player;

public class NavigableSetEx2 {

    public static void main(String[] args) {
        Player tomA = new Player("Tom A", 3, 1, 4);
        Player tomB = new Player("Tom B", 2, 5, 1);
        Player jerryA = new Player("Jerry A", 1, 2, 4);
        Player jerryB = new Player("Jerry B", 3, 2, 3);
        Player donaldA = new Player("Donald A", 2, 2, 1);
        

        // A sorted set in ascending order.
        NavigableSet<Player> players = new TreeSet<Player>();

        players.add(tomA);
        players.add(tomB);
        players.add(jerryA);
        players.add(jerryB);
        players.add(donaldA);
        
        System.out.println("--- Players (in ascending order) ---");
        for(Player p: players)  {
            System.out.println(p.getGoldMedal()  + " : " + p.getSilverMedal() //
                 +" : " + p.getBronzeMedal() +" - " + p.getFullName());
        }
        
        System.out.println();
        System.out.println("--- Players in decending order ---");
        NavigableSet<Player> decendingPlayers = players.descendingSet();
        
        for(Player p: decendingPlayers)  {
            System.out.println(p.getGoldMedal()  + " : " + p.getSilverMedal() //
                 +" : " + p.getBronzeMedal() +" - " + p.getFullName());
        }
    }
}
Output:
--- Players (in ascending order) ---
1 : 2 : 4 - Jerry A
2 : 2 : 1 - Donald A
2 : 5 : 1 - Tom B
3 : 1 : 4 - Tom A
3 : 2 : 3 - Jerry B

--- Players in decending order ---
3 : 2 : 3 - Jerry B
3 : 1 : 4 - Tom A
2 : 5 : 1 - Tom B
2 : 2 : 1 - Donald A
1 : 2 : 4 - Jerry A
See more examples in the article about SortedSet:

5. descendingSet()

public NavigableSet<E> descendingSet();
Example:
NavigableSet_descendingSet_ex1.java
package org.o7planning.navigableset.ex;

import java.util.Arrays;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;

public class NavigableSet_descendingSet_ex1 {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1970, 1966, 1962, 1958, 1954, 1950, 1938, 1934, 1930);

        // A sorted set in ascending order.
        NavigableSet<Integer> worldCupYears = new TreeSet<Integer>(list); 
        System.out.println("worldCupYears: " + worldCupYears);

        // Get a reverse view of the navigable set
        NavigableSet<Integer> reverseYears = worldCupYears.descendingSet();
        
        System.out.println("reverseYears: " + reverseYears);
        System.out.println();

        System.out.println("Add year 1998");
        reverseYears.add(1998); // World Cup 1998 in France.
        
        System.out.println();
        System.out.println("worldCupYears: " + worldCupYears);
        System.out.println("reverseYears: " + reverseYears);
    }
}
Output:
worldCupYears: [1930, 1934, 1938, 1950, 1954, 1958, 1962, 1966, 1970]
reverseYears: [1970, 1966, 1962, 1958, 1954, 1950, 1938, 1934, 1930]

Add year 1998

worldCupYears: [1930, 1934, 1938, 1950, 1954, 1958, 1962, 1966, 1970, 1998]
reverseYears: [1998, 1970, 1966, 1962, 1958, 1954, 1950, 1938, 1934, 1930]

6. descendingIterator()

public Iterator<E> descendingIterator();
Returns Iterator object to iterate over elements of NavigableSet in descending order. It is equivalent to calling descendingSet().iterator().
Example:
NavigableSet_descendingIterator_ex1.java
package org.o7planning.navigableset.ex;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;

public class NavigableSet_descendingIterator_ex1 {

    public static void main(String[] args) {
        List<String> list = Arrays.asList("A1", "A2", "C1", "B1", "B2", "D1");
        // A sorted set in ascending order.
        NavigableSet<String> strings = new TreeSet<String>(list);
        System.out.println("NavigableSet: " + strings);
        System.out.println(); 
        Iterator<String> iter = strings.descendingIterator();
        
        while(iter.hasNext()) {
            System.out.println(iter.next());
        }
    }
}
Output:
NavigableSet: [A1, A2, B1, B2, C1, D1]

D1
C1
B2
B1
A2
A1

7. subSet(..)

public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,E toElement,  boolean toInclusive);
Returns portion view of this NavigableSet whose elements range from fromElement to toElement; include fromElement if fromInclusive is true, include toElement if toInclusive is true.
The returned NavigableSet is related to the current NavigableSet. Changes on one NavigableSet affect the other and vice versa.
Example:
NavigableSet_subSet_ex1.java
package org.o7planning.navigableset.ex;

import java.util.Arrays;
import java.util.List;
import java.util.NavigableSet;
import java.util.TreeSet;

public class NavigableSet_subSet_ex1 {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1986, 1990, 1994,1998,2010, 2014, 2018); // Without: 2006,2002 (!)
        // A sorted set in ascending order.
        NavigableSet<Integer> worldCupYears = new TreeSet<Integer>(list);
        System.out.println("worldCupYears: " + worldCupYears);
        NavigableSet<Integer> subSet = worldCupYears.subSet(1994, true, 2010, true);
        System.out.println("subSet: " + subSet);
        System.out.println();

        System.out.println("Add years 2002,2006 to subSet");
        subSet.add(2002); // World Cup 2002 in South Korea, Japan.
        subSet.add(2006); // World Cup 2006 in Germany.
        
        System.out.println();
        System.out.println("worldCupYears: " + worldCupYears);
        System.out.println("subSet: " + subSet);
    }
}
Output:
worldCupYears: [1986, 1990, 1994, 1998, 2010, 2014, 2018]
subSet: [1994, 1998, 2010]

Add years 2002,2006 to subSet

worldCupYears: [1986, 1990, 1994, 1998, 2002, 2006, 2010, 2014, 2018]
subSet: [1994, 1998, 2002, 2006, 2010]

8. headSet(E toElement, boolean inclusive)

public NavigableSet<E> headSet(E toElement, boolean inclusive);
Returns a view of the portion of this NavigableSet whose elements are less than (or equal to, if inclusive is true) toElement.
The returned NavigableSet is related to the current NavigableSet. Changes on one NavigableSet affect the other and vice versa.

9. tailSet(E fromElement, boolean inclusive)

public NavigableSet<E> tailSet(E fromElement, boolean inclusive);
Returns a view of the portion of this NavigableSet whose elements are greater than (or equal to, if inclusive is true) fromElement.
The returned NavigableSet is related to the current NavigableSet. Changes on one NavigableSet affect the other and vice versa.
Example:
NavigableSet_tailSet_ex1.java
package org.o7planning.navigableset.ex;

import java.util.NavigableSet;
import java.util.TreeSet;

public class NavigableSet_tailSet_ex1 {

    public static void main(String[] args) {
        NavigableSet<String> mySet = new TreeSet<String>();
        mySet.add("A");
        mySet.add("B");
        mySet.add("C");
        mySet.add("D");
        mySet.add("D1");
        mySet.add("E"); 
        // A Head Set (elements >= "C")
        NavigableSet<String> tailSet = mySet.tailSet("C", true);
        System.out.println(" -- tailSet --");
        for (String s : tailSet) {
            System.out.println(s);
        }
        // Remove some elements from tailSet
        tailSet.remove("D");
        tailSet.remove("D1");
        System.out.println();
        System.out.println(" -- mySet (After remove some elements from tailSet --");
        for (String s : mySet) {
            System.out.println(s);
        }
    }
}
Output:
-- tailSet --
C
D
D1
E

 -- mySet (After remove some elements from tailSet --
A
B
C
E

10. lower(E e)

public E lower(E e);
Returns the greatest element in this NavigableSet less than the given element, or null if there is no such element.

11. higher(E e)

public E higher(E e);
Returns the smallest element in this NavigableSet greater than the given element, or null if there is no such element.

12. floor(E e)

public E floor(E e);
Returns the greatest element in this NavigableSet less than or equal to the given element, or null if there is no such element.

13. ceiling(E e)

public E ceiling(E e);
Returns the smallest element in this NavigableSet greater than or equal to the given element, or null if there is no such element.

14. pollFirst()

public E pollFirst();
Retrieves and removes the first (smallest) element, or returns null if this NavigableSet is empty.

15. pollLast()

public E pollLast();
Retrieves and removes the last (largest) element, or returns null if this NavigableSet is empty.