The Java TreeSet is a good choice when our codes, for example, do a lot of frequent read-and-write operations. It is a derivation of a Set, which means it still deals with unique items. Also, it has additional features like automatically sorting unique elements as we add them, making it ideal for heavy read and write operations because either operation generally takes O(log n) time, which is fast enough even for a massive number of inputs. However, it is not thread-safe. Hence, we need to synchronize it externally.
From Chaos to Order Within Java TreeSet
One key attribute that makes the Java TreeSet ideal for heavy read-and-write operations, especially on a large data set, is an efficient self-balancing search tree (see Red-Black tree). As a result, the operations would take O(log n) time (whereas ArrayList takes O(1) time).
Sample TreeSet Usages
Some excellent examples will help us familiarize ourselves with the Java TreeSet. When we create a TreeSet without passing anything to its constructor, it will sort the elements by their natural order in ascending order. Consider the following codes.
1 2 3 4 5 6 7 8 9 10 11 | TreeSet<String> treeSetName = new TreeSet<>(); treeSetName.add("Liam"); treeSetName.add("Oliver"); treeSetName.add("James"); treeSetName.add("Benjamin"); treeSetName.add("Henry"); treeSetName.add("Jack"); // [Benjamin, Henry, Jack, James, Liam, Oliver] System.out.println(treeSetName); |
However, we can override this behavior, for example, by providing a Comparator to the Java TreeSet constructor. Consider the following modified codes. We pass a Comparator that compares the content of the String values in reversed order. Therefore, we now see a different sorting order.
1 2 3 4 5 6 7 8 9 10 11 | TreeSet<String> treeSetName = new TreeSet<>(Comparator.comparing(String::toString).reversed()); treeSetName.add("Liam"); treeSetName.add("Oliver"); treeSetName.add("James"); treeSetName.add("Benjamin"); treeSetName.add("Henry"); treeSetName.add("Jack"); // [Oliver, Liam, James, Jack, Henry, Benjamin] System.out.println(treeSetName); |
We can use the following examples to find and remove an element from a Java TreeSet. To find out if a String exists in the TreeSet, we use the method contains, which returns a boolean value. However, we do not need first to check if a String exists before removing it from the TreeSet. We can directly remove a String using the method remove.
1 2 3 | System.out.println(treeSetName.contains("Jack")); treeSetName.remove("Jack"); System.out.println(treeSetName.contains("Jack")); |
To make the Java TreeSet synchronized, we can use the following code.
1 | Set<String> syncTreeSetName = Collections.synchronizedSet(treeSetName); |
Then, we can use syncTreeSetName to work with multiple threads for concurrent operations.