HashSet vs. TreeSet vs. LinkedHashSet
A Set contains no duplicate elements. That is one of the major reasons to use a set. There are 3 commonly used implementations of Set: HashSet, TreeSet and LinkedHashSet. When and which to use is an important question. In brief, if you need a fast set, you should use HashSet; if you need a sorted set, then TreeSet should be used; if you need a set that can be store the insertion order, LinkedHashSet should be used.
1. Set Interface
2. HashSet vs. TreeSet vs. LinkedHashSet
HashSet is Implemented using a hash table. Elements are not ordered. The
TreeSet is implemented using a tree structure(red-black tree in algorithm book). The elements in a set are sorted, but the
LinkedHashSet is between HashSet and TreeSet. It is implemented as a hash table with a linked list running through it, so it provides the order of insertion. The time complexity of basic methods is O(1).
3. TreeSet Example
TreeSet<Integer> tree = new TreeSet<Integer>(); tree.add(12); tree.add(63); tree.add(34); tree.add(45); Iterator<Integer> iterator = tree.iterator(); System.out.print("Tree set data: "); while (iterator.hasNext()) { System.out.print(iterator.next() + " "); } |
Output is sorted as follows:
Tree set data: 12 34 45 63
Now let's define a Dog class as follows:
class Dog { int size; public Dog(int s) { size = s; } public String toString() { return size + ""; } } |
Let's add some dogs to TreeSet like the following:
import java.util.Iterator; import java.util.TreeSet; public class TestTreeSet { public static void main(String[] args) { TreeSet<Dog> dset = new TreeSet<Dog>(); dset.add(new Dog(2)); dset.add(new Dog(1)); dset.add(new Dog(3)); Iterator<Dog> iterator = dset.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + " "); } } } |
Compile ok, but run-time error occurs:
Exception in thread "main" java.lang.ClassCastException: collection.Dog cannot be cast to java.lang.Comparable at java.util.TreeMap.put(Unknown Source) at java.util.TreeSet.add(Unknown Source) at collection.TestTreeSet.main(TestTreeSet.java:22)
Because TreeSet is sorted, the Dog object need to implement
class Dog implements Comparable<Dog>{ int size; public Dog(int s) { size = s; } public String toString() { return size + ""; } @Override public int compareTo(Dog o) { return size - o.size; } } |
The output is:
1 2 3
4. HashSet Example
HashSet<Dog> dset = new HashSet<Dog>(); dset.add(new Dog(2)); dset.add(new Dog(1)); dset.add(new Dog(3)); dset.add(new Dog(5)); dset.add(new Dog(4)); Iterator<Dog> iterator = dset.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + " "); } |
Output:
5 3 2 1 4
Note the order is not certain.
5. LinkedHashSet Example
LinkedHashSet<Dog> dset = new LinkedHashSet<Dog>(); dset.add(new Dog(2)); dset.add(new Dog(1)); dset.add(new Dog(3)); dset.add(new Dog(5)); dset.add(new Dog(4)); Iterator<Dog> iterator = dset.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + " "); } |
The order of the output is certain and it is the insertion order:
2 1 3 5 4
6. Performance testing
The following method tests the performance of the three class on
public static void main(String[] args) { Random r = new Random(); HashSet<Dog> hashSet = new HashSet<Dog>(); TreeSet<Dog> treeSet = new TreeSet<Dog>(); LinkedHashSet<Dog> linkedSet = new LinkedHashSet<Dog>(); // start time long startTime = System.nanoTime(); for (int i = 0; i < 1000; i++) { int x = r.nextInt(1000 - 10) + 10; hashSet.add(new Dog(x)); } // end time long endTime = System.nanoTime(); long duration = endTime - startTime; System.out.println("HashSet: " + duration); // start time startTime = System.nanoTime(); for (int i = 0; i < 1000; i++) { int x = r.nextInt(1000 - 10) + 10; treeSet.add(new Dog(x)); } // end time endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("TreeSet: " + duration); // start time startTime = System.nanoTime(); for (int i = 0; i < 1000; i++) { int x = r.nextInt(1000 - 10) + 10; linkedSet.add(new Dog(x)); } // end time endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("LinkedHashSet: " + duration); } |
From the output below, we can clearly wee that HashSet is the fastest one.
HashSet: 2244768 TreeSet: 3549314 LinkedHashSet: 2263320
* The test is not precise, but can reflect the basic idea that TreeSet is much slower because it is sorted.
Read: ArrayList vs. LinkedList vs. Vector
<pre><code> String foo = "bar"; </code></pre>
-
infoj
-
Konstantin Yegupov
-
infoj
-
ibrahim KARAYEL
-
PD
-
Paola Greco
-
BatSlug
-
Shivam Singh
-
Shivam Singh
-
konqi
-
Muhammad Aamir
-
bhawna
-
Puneeth Shivalingaiah
-
karthik
-
Somesh Rathi
-
Satish Kumar SIngh
-
Luiz Sewaybricker
-
Sandeep Jaiswal