首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

关于SET元素不反复的实现

2012-10-28 
关于SET元素不重复的实现set的实现类HashSet/TreeSet的底层实现是通过HashMap/TreeMap来实现的。Set的实现

关于SET元素不重复的实现
set的实现类HashSet/TreeSet的底层实现是通过HashMap/TreeMap来实现的。Set的实现类在创建对象的时候都,在构造方法里面都是创建了一个Map的实现类来实现的。而Map中的元素是“键-值”对,其中“键”必须是唯一的。Set就是利用“键”唯一这个特性来实现元素不重复的。它把Set中的元素作为Map的键,从而保持了元素的唯一性。

public class TestTreeSet {public static void main(String [] args){Set set = new TreeSet();set.add(new Element1("aa"));set.add(new Element1("bb"));set.add(new Element1("aa"));}}class Element1{String s ;public Element1(String s){this.s = s;}@Overridepublic String toString(){return s;}@Override  //这里重写了equals方法,但是实际是没有作用的。public boolean equals(Object obj) {return s.equals(((Element1)obj).s);}}// 报错:java.lang.ClassCastException: com.lovo.TestTreeSet$SetElement cannot be cast to java.lang.Comparable//at java.util.TreeMap.put(TreeMap.java:542)//at java.util.TreeSet.add(TreeSet.java:238)//at com.lovo.TestTreeSet.main(TestTreeSet.java:10)public class TestTreeSet2 {public static void main(String[] args) {Set set = new TreeSet();set.add(new Element2("ss"));set.add(new Element2("qq"));set.add(new Element2("ss"));System.out.println(set);}}class Element2 implements Comparable{   String s;    public Element2(String s){     this.s =  s;    }    public String toString(){     return s;    }    public int compareTo(Object o){     return s.compareTo(((Element2)o).s);    }    public boolean equals(Object obj) {     return s.equals(((Element2)obj).s);    }}/***运行结果:[qq, ss]  --达到我们想要的结果。*TestTreeSet和TestTreeSet2唯一区别就是Element2实现了Comparable接口。进入TreeMap.java:542其实可以看到TreeSet在添加*元素的时候是使用了TreeMap的put方法。而put方法的实现是通过实现接口Comparable中的CompareTo方法来实现的。所以TreeSet在添加元素*的时候是把元素cast to Comparable,再来使用compareTo进行比较。*综合:TreeSet是使用了CompareTo来实现集合中元素不重复。*/public class TestTreeSet3 {public static void main(String[] args) {Set set = new TreeSet();set.add(new Element3("ss"));set.add(new Element3("qq"));set.add(new Element3("ss"));System.out.println(set);}}class Element3 implements Comparable{   String s;    public Element3(String s){     this.s =  s;    }    public String toString(){     return s;    }    public int compareTo(Object o){     return -1;    }    public boolean equals(Object obj) {     return s.equals(((Element2)obj).s);    }}/***运行结果:[ss, qq, ss]  --没有实现元素不重复。*原因:重写了compareTo方法返回值是-1,把所有的元素都作为不同的元素处理。*/public class TestHashSet1 {public static void main(String[] args) {Set set = new HashSet();set.add(new Element4("kkk"));set.add(new Element4("jjj"));set.add(new Element4("kkk"));System.out.println(set);}}class Element4{String s;public Element4(String s) {super();this.s = s;}@Overridepublic boolean equals(Object obj) {return s.equals(((Element4)obj).s);}@Overridepublic String toString() {// TODO Auto-generated method stubreturn s;}}/** * 运行结果:[jjj, kkk, kkk]  --重写了equals没有达到元素不重复的要求 */public class TestHashSet2 {public static void main(String [] args){Set set = new HashSet();set.add(new Element5("kkk"));set.add(new Element5("jjj"));set.add(new Element5("kkk"));System.out.println(set);}}class Element5{String s;public Element5(String s) {super();this.s = s;}@Overridepublic int hashCode() {// TODO Auto-generated method stubreturn s.hashCode();}@Overridepublic String toString() {// TODO Auto-generated method stubreturn s;}@Overridepublic boolean equals(Object obj) {return s.equals(((Element5)obj).s);}}/** * 运行结果:[jjj, kkk]--达到了元素不重复的要求 * 值得注意的是:在类Element5中重写了hashCode方法和equals方法,这两个方法都是不可缺的 * 缺了其中一个就不能达到元素不重复的效果了。 * 看看源码的方法: *     public V put(K key, V value) {        if (key == null)            return putForNullKey(value);        int hash = hash(key.hashCode());        int i = indexFor(hash, table.length);        for (Entry<K,V> e = table[i]; e != null; e = e.next) {            Object k;            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {                V oldValue = e.value;                e.value = value;                e.recordAccess(this);                return oldValue;            }        }        modCount++;        addEntry(hash, key, value, i);        return null;    }    其中的有这样的条件:e.hash == hash && ((k = e.key) == key || key.equals(k))可以看出,如果这个条件成立的话,    那么就是说明元素的重复的,就不会添加元素了。而这个条件所需要的恰好是hashCode方法和equals方法。所以说HashSet实现    元素不重复是使用了:hashCode方法和equals方法。 */

呵呵,分析的比较粗糙,大家参考哈就是了哈。其实有一个CopyOnWriteArraySet,这个类是AbstractSet的子类。它在实现元素不重复的时候就是用的是List遍历的,采用了equals来实现元素不重复,大家有机会可以看看了。

热点排行