JAVA菜鸟入门(17) 有排序的TreeSet和无排序的HashSet, LinkedHashSet

来源:互联网 发布:出租屋网络不稳定 编辑:程序博客网 时间:2024/06/14 01:03
如果 set的key是custom key(eg. a class)。

那么对于HashSet/LinkedHashSet,这两种不提供排序的set而言,需要重载HashCode()和Equals().

对于TreeSet,那么就需要去重载 comparator()/comparable().



1.1 HashSet/LinkedHashSet 重载HashCode/equals() 
class Dog{String color; public Dog(String s){color = s;}//overridden method, has to be exactly the same like the following@Overridepublic boolean equals(Object obj) {if (!(obj instanceof Dog))return false;if (obj == this)return true;return this.color.equals(((Dog) obj).color);}@Override public int hashCode() {return this.color.hashCode();}public String getColor() {return this.color;}} public class HashSetDemo{public static void main(String[] args) {HashSet<Dog> dogSet = new HashSet<Dog>();dogSet.add(new Dog("white"));dogSet.add(new Dog("white"));dogSet.add(new Dog("green"));dogSet.add(new Dog("yellow"));dogSet.add(new Dog("blue"));dogSet.add(new Dog("Yellow"));dogSet.add(new Dog("red"));dogSet.add(new Dog("white"));for (Dog d : dogSet) {System.out.println(d.getColor());}}}

输出结果:
redbluegreenYellowwhiteyellow

如果不重载,将无法过滤重复 (上例中的white会打印2次).


2.1  TreeSet 重载Comparator
package FFtest;import java.util.Comparator;import java.util.Set;import java.util.TreeSet;class Fish{String color; public Fish(String s){color = s;}public String getColor() {return this.color;}} public class TreeSetDemo{public static void main(String[] args) {Comparator<Fish> dogComparator= new Comparator<Fish>() {    @Override    public int compare(Fish f1, Fish f2) {        return f1.getColor().compareTo(f2.getColor());    }};TreeSet<Fish> fishSet = new TreeSet<Fish>(dogComparator);fishSet.add(new Fish("white"));fishSet.add(new Fish("white"));fishSet.add(new Fish("green"));fishSet.add(new Fish("yellow"));fishSet.add(new Fish("blue"));fishSet.add(new Fish("Yellow"));fishSet.add(new Fish("red"));fishSet.add(new Fish("white")); for (Fish s : fishSet) {System.out.println(s.getColor());}}}

output: 
Yellowbluegreenredwhiteyellow




2.2  TreeSet 重载Comparable

package FFtest;import java.util.Comparator;import java.util.TreeSet;class Cat implements Comparable<Cat>{String color; public Cat(String s){color = s;}public String getColor() {return this.color;} public int compareTo(Cat c1) { return this.getColor().compareTo(c1.getColor()); }} public class TreeSetDemo2{public static void main(String[] args) {TreeSet<Cat> objectSet = new TreeSet<Cat>();objectSet.add(new Cat("white"));objectSet.add(new Cat("white"));objectSet.add(new Cat("green"));objectSet.add(new Cat("yellow"));objectSet.add(new Cat("blue"));objectSet.add(new Cat("Yellow"));objectSet.add(new Cat("red"));objectSet.add(new Cat("white"));for (Cat s : objectSet) {System.out.println(s.getColor());}}}

output: 
Yellowbluegreenredwhiteyellow


PS: A general introduction. 

Java Set FamilyHashSet, LinkedHashSet, TreeSet

Java Map Family: Hashtable, HashMap, LinkedHashMpa, TreeMap


There are three general-purpose Set implementations — HashSet, TreeSet, and LinkedHashSet. Which of these three to use is generally straightforward.HashSet is much faster than TreeSet (constant-time versus log-time for most operations) but offers no ordering guarantees. If you need to use the operations in the SortedSet interface, or if value-ordered iteration is required, use TreeSet; otherwise, use HashSet. It's a fair bet that you'll end up using HashSet most of the time.


LinkedHashSet is in some sense intermediate between HashSet and TreeSet. Implemented as a hash table with a linked list running through it, it provides insertion-ordered iteration (least recently inserted to most recently) and runs nearly as fast as HashSet. The LinkedHashSet implementation spares its clients from the unspecified, generally chaotic ordering provided by HashSet without incurring the increased cost associated with TreeSet.


One thing worth keeping in mind about HashSet is that iteration is linear in the sum of the number of entries and the number of buckets (the capacity). Thus, choosing an initial capacity that's too high can waste both space and time. On the other hand, choosing an initial capacity that's too low wastes time by copying the data structure each time it's forced to increase its capacity. If you don't specify an initial capacity, the default is 16. In the past, there was some advantage to choosing a prime number as the initial capacity. This is no longer true. Internally, the capacity is always rounded up to a power of two. The initial capacity is specified by using the int constructor. The following line of code allocates a HashSet whose initial capacity is 64.


Set<String> s = new HashSet<String>(64);
The HashSet class has one other tuning parameter called the load factor. If you care a lot about the space consumption of your HashSet, read the HashSet documentation for more information. Otherwise, just accept the default; it's almost always the right thing to do.


If you accept the default load factor but want to specify an initial capacity, pick a number that's about twice the size to which you expect the set to grow. If your guess is way off, you may waste a bit of space, time, or both, but it's unlikely to be a big problem.


LinkedHashSet has the same tuning parameters as HashSet, but iteration time is not affected by capacity. TreeSet has no tuning parameters.




0 0
原创粉丝点击