3. Sets
What is a Set?
A set is a collection of items where you are only allowed one of each item. For example, a set cannot be {1,2,2,3} because there are two 2's. Most Set's in Java also have no sense of order, so one would treat {1,2,3} as the same as {3,1,2}.
Declaring a HashSet
Like ArrayList, HashSet uses angle brackets to specify the inner type:
HashSet<Integer> s = new HashSet<Integer>(); s.add(5); s.add(5); //no effect s.add(42); for( Integer v : s ) { println(v); } //prints 5 and 42, although not necessarily in that order.
Hash sets also have remove(), clear(), and size() functions that are similar to that of ArrayList. A full list of functions (methods) can be found here (Java 6 API Doc): http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html
Why use a hashset? The primary advantage of a hash set is that you can check if it contains() an item very quickly. Unlike arrays and ArrayLists, a HashSet does not need to loop through all items to check if an item is already present.
LinkedHashSet and TreeSet
A linked hash set preserves the order that items are inserted in. A TreeSet, in contrast, keeps items sorted. Compare the output of these three sets:
Set<Integer> a = new HashSet<Integer>(); a.add(30); a.add(10); a.add(20); a.add(40); Set<Integer> b = new TreeSet<Integer>(); b.add(30); b.add(10); b.add(20); b.add(40); Set<Integer> c = new LinkedHashSet<Integer>(); c.add(30); c.add(10); c.add(20); c.add(40); System.out.println(a); //"random" order (using object.hashcode) System.out.println(b); //sorted order (using object.compareTo) System.out.println(c); //original order
Changing set behavior
Hash Sets use both the .equals method and the hashCode method to determine if two items are equivalent. Thus, you must override these methods in your own classes if you want them to work properly in a Set. Otherwise, by default Sets will operator on the memory address of the object.
TreeSets do not use the hashcode method at all, and they instead use the compareTo of the class. Alternatively, you can pass a comparator to the constructor of the treeset. We will cover this type of functionality more in the inheritance section of this book.