读书人

Set 怎么比较重复元素

发布时间: 2012-12-27 10:17:10 作者: rapoo

Set 如何比较重复元素

HashSet部分:?

???以下以HashSet为例进行分析。?
???从Hashset类的主体部分:?
public class HashSet<E> extends AbstractSet<E>?
?????implements Set<E>, Cloneable, java.io.Serializable?
{?
??static final long serialVersionUID = -5024744406713321676L;?
??private transient HashMap<E,Object> map;?
??// Dummy value to associate with an Object in the backing Map?
??//这是每个键所指的对像?
??private static final Object PRESENT = new Object();?


?????public HashSet() {?
???map = new HashMap<E,Object>();?
??????}?
?????public boolean add(E o) {?
???return map.put(o, PRESENT)==null;?
??????}?
????//以下省略..........?
????}?

????????public HashSet() {?

??map = new HashMap<E,Object>();?
????
}?
???可以看到HashSet使用了HashMap作为其Map保存“键-值”对。?
???
???请看示例程序4:?
import java.util.*;?

public class SetTest4 {?
public static void main(String[] args){?
??Set set = new HashSet();?
??set.add(new SetElement4("aa"));?
??set.add(new SetElement4("aa"));?
??set.add(new SetElement4("bb"));?
??System.out.println(set);?
}?
static class SetElement4{?
??String s;?
??public SetElement4(String s){?
???this.s =??s;?
??}?
??public String toString(){?
???return s;?
??}?
??public boolean equals(Object obj) {?
???return s.equals(((SetElement4)obj).s);?
??}?
}?
}?

???运行结果:?
???[bb, aa, aa]?
???没有“示例程序1”中的java.lang.ClassCastException,但是运行结果似乎不对,因为有两个“aa”。?
???
???请看示例程序5:?
import java.util.*;?
public class SetTest5 {?
??public static void main(String[] args){?
???Set set = new HashSet();?
???set.add(new SetElement5("aa"));?
???set.add(new SetElement5("aa"));?
???set.add(new SetElement5("bb"));?
???System.out.println(set);?
??}?
??static class SetElement5{?
???String s;?
???public SetElement5(String s){?
????this.s =??s;?
???}?
???public String toString(){?
????return s;?
???}?
???public boolean equals(Object obj) {?
????return s.equals(((SetElement5)obj).s);?
???}?
???public int hashCode() {?
????//return super.hashCode();?
????return s.hashCode();?
???}?
??}?
}?
????运行结果:?
????[bb, aa]?
????这就对了。“示例程序4”和“示例程序5”有什么区别?是SetElement5重写了hashCode方法。?
????
????可见HashSet中是采用了比较元素hashCode的方法来判断元素是否相同(duplicate),而不是采用其他类似equals之类的东东来判断。?
????
????说了这么多,那java类库中到底有没有根据equals来判断元素是否相同(duplicate)的Set呢?请看下文。?
2.2、CopyOnWriteArraySet部分:?
???类CopyOnWriteArraySet是java.util.concurrent包中的一个类,所以它是线程安全的。?
???CopyOnWriteArraySet是使用CopyOnWriteArrayList作为其盛放元素的容器。当往CopyOnWriteArrayList添加新元素,它都要遍历整个List,并且用equals来????比较两个元素是否相同。?

???请看示例程序6:?
import java.util.*;?
import java.util.concurrent.*;?
public class SetTest6 {?
??public static void main(String[] args){?
???Set set = new CopyOnWriteArraySet();?
???set.add(new SetElement6("aa"));?
???set.add(new SetElement6("aa"));?
???set.add(new SetElement6("bb"));?
???System.out.println(set);?
??}?
??static class SetElement6{?
???String s;?
???public SetElement6(String s){?
????this.s =??s;?
???}?
???public String toString(){?
????return s;?
???}?
???public boolean equals(Object obj) {?
????return s.equals(((SetElement6)obj).s);?
???}?
??}?
}?
???运行结果:?
???[aa, bb]?
???好了,一切搞定!!?

3、总结:?
???Javadoc中的一些描述可能是不准确的,大家要当心了!?
???
???Set中实现元素互异的各种方法差异很大,大致可以分为三种:使用equals,使用hashCode,使用compareTo。但是我还没有发现采用“判断地址空间是否相同”来判断元素是否相同的类,当然我们可以用现有的三种方法来实现“判断地址空间是否相同”。?
???
???综上所述,我们可以总结出使用Set的三种不同的情形:(以下假设元素类为Element)?
???A、如果想使用Element的equals方法来判断元素是否相同,那么可以使用CopyOnWriteArraySet来构造类的实体。?
???B、如果Element实现了Comparable接口,而且想使用compareTo方法来判断元素是否相同,那么可以使用TreeSet来构造类的实体。?
???C、如果想使用判断hashCode是否相同的方法来判断元素是否相同,那么可以使用HashSet来构造类的实体

发表于 @ 2009年12月17日 17:


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pss360/archive/2009/12/17/5026516.aspx

读书人网 >编程

热点推荐