Java TreeSet and HashSet are implementations of the Set interface. Often you may have wondered whether to choose HashSet or TreeSet and which is faster. In this article, I will be comparing the HashSet and TreeSet classes in Java.
Since both HashSet and TreeSet implement the Set interface, they do not allow duplicates. So consider the following code:
Set<String> hashSet = new HashSet<String>();
hashSet.add("Mango");
hashSet.add("Mango");
Set<String> treeSet = new TreeSet<String>();
treeSet.add("Mango");
treeSet.add("Mango");
System.out.println("Number of elements in Hashset:"+hashSet.size());
System.out.println("Number of elements in Treeset:"+treeSet.size());
When you execute this code, it will print the following output:
Number of elements in Hashset:1
Number of elements in Treeset:1
Both HashSet and TreeSet are not synchronized and are not thread-safe. So you need to write code to explicitly synchronize them.
So you will need to write code similar to the following:
Set<String> synHashSet = Collections.synchronizedSet(hashSet);
Set<String> synTreeSet = Collections.synchronizedSet(treeSet);
A TreeSet is sorted, whereas a HashSet is not sorted. When you insert elements into a HashSet, no order will be maintained. On the other hand, when you insert elements into a TreeSet, they will be ordered according to their natural order. The following code demonstrates this:
HashSet example
Set<String> hashSet = new HashSet<String>();
hashSet.add("Mango");
hashSet.add("Banana");
hashSet.add("Apple");
hashSet.add("Pear");
hashSet.forEach(str -> System.out.println(str));
The code above creates a HashSet of String values, inserts some data and then prints it. When you execute this code, it will print the following output:
Apple
Pear
Mango
Banana
So you can see that the Strings in the HashSet are not sorted.
TreeSet example
Set<String> treeSet = new TreeSet<String>();
treeSet.add("Mango");
treeSet.add("Banana");
treeSet.add("Apple");
treeSet.add("Pear");
treeSet.forEach(str -> System.out.println(str));
When you execute this code, it will print the following output:
Apple
Banana
Mango
Pear
So you can see that the Strings in the TreeSet are sorted alphabetically.
A HashSet allows null objects, a TreeSet does not allow null objects. So you can insert a null value in a HashSet, but you cannot do this in a TreeSet. The following code demonstrates this:
hashSet.add("Mango");
hashSet.add("Banana");
hashSet.add(null);
hashSet.forEach(str -> System.out.println(str));
The above code will not cause any issues. So when you execute this code, the following will be printed to the console:
null
Mango
Banana
However, consider the following code:
treeSet.add("Mango");
treeSet.add("Banana");
treeSet.add(null);
treeSet.forEach(str -> System.out.println(str));
When you run this code, a NullPointerException will occur as follows:
Exception in thread "main" java.lang.NullPointerException
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at learnjava.collections.HashSetTreeSetDemo.main(HashSetTreeSetDemo.java:15)
HashSet internally uses a HashTable. TreeSet on the other hand internally uses a Red-Black Tree.
Since HashSet internally uses a HashTable, it is faster as compared to a TreeSet. So most operations like add, remove, etc are faster in a HashSet.
If you want to store the data in sorted order and don’t care about the performance then you should use a TreeSet. If performance is critical for your application, you should use a HashSet.
So, in this article, we learned about the similarities and differences between Java TreeSet and HashSet.