Set的元素重复是如何判断的_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Set的元素重复是如何判断的

Set的元素重复是如何判断的

 2011/9/9 8:14:46  kaidi0314  http://kaidi0314.iteye.com  我要评论(0)
  • 摘要:相关链接:http://hi.baidu.com/gabe2008/blog/item/eb0448da41d14168d1164e6f.html当我看到这个问题:Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?比较标准的说法:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖
  • 标签:

相关链接:http://hi.baidu.com/gabe2008/blog/item/eb0448da41d14168d1164e6f.html

当我看到这个问题:Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
???????? 比较标准的说法:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

??????? 而我的研究生同学居然说,判断是否重复是由系统内部实现的,他一时半会儿无法理解一个类还须重写equals来判断是否重复。我解释得已经蛮清楚,大体说法,与上一致,但他只接受代码层次的解释,那我对于以前写的TreeSetTest这个类进行简单的修改,才发现,我本不应该拿TreeSet这么特殊的类进行打比方,虽然它也继续于Set接口

?????? Set<Cat> set = new TreeSet<Cat>();
????? Cat a = new Cat("Qi");
????? Cat b = new Cat("Qi");

?????? 代码到这里已经编译报错了?因为,TreeSet是排序的集合,被排序的元素必须实现Comparable接口,那么实现呗。事实上,这里是运行时出错(ClassCastException,而不是编译期的错误。如果TreeSet的构造方法原型内是这个造型:Comparable<? super T>,那么会在编译检错,而Arrays.sort(E, Comparator<? super T> c),那会是如果没有实现Comparator的对象当做排序器,那么编译出错。原本JDK可以使用 class TreeSet<E extends Comparable>,这样的话就能在编译时候做检查。这样的话,就有了矛盾:那些没实现Comparable但是靠Comparator的机制就不行了。

??????? class Cat implements Comparable 接口,那么按eclipse系统提示,一律返回1,我重写了Cat中的equals方法,用来说明如果Cat的name是一样的话,就返回true,按照我的设想,此TreeSet添加这个元素的时候一定不成功,可是遍历以后,发现它还是添加了两个"Qi",检索才知道,原来TreeSet是用Comparable的方法compareTo的返回值,完整代代码如下:

import java.util.*;

public class TreeSetTest {
?? public static void main(String[] args) {
????? Set<Cat> set = new TreeSet<Cat>();
?????
????? set.add(new Cat("Cat1"));
????? set.add(new Cat("Cat2"));
????? set.add(new Cat("Cat"));
????? set.add(new Cat("Cat"));
????? set.add(new Cat("Cat"));??? //无法被成功添加,因为compareTo的结果是0,Cat name相同
????? Iterator<Cat> it = set.iterator();
????? while(it.hasNext()){
???????? System.out.println(it.next().name+":");
????? }
?? }
}

class Cat implements Comparable{
?? public String name;
?? public Cat(String name){
????? this.name = name;
?? }
?? public int compareTo(Object o) {
????? String name = ((Cat)o).name;
????? return this.name.compareTo(name);
?? }
}

?????? 这里我们走一个极端,把compareTo的方法返回值一律为return 0; 那么只会添加第一个元素。如以下代码所示:

import java.util.Iterator;
import java.util.TreeSet;

class Drink implements Comparable<Object>{
?? public String name;
?? public int compareTo(Object o){
????? return 0;
?? }
}

public class TreeSetDrink {
?? public static void main(String[] args) {
????? Drink one = new Drink();
????? Drink two = new Drink();
????? one.name = "Coffee";
????? two.name = "Tea";?? //因为compareTo返回为0,添加不成功,当成重复元素。
????? TreeSet set = new TreeSet();
????? set.add(one);
????? set.add(two);
????? Iterator iterator = set.iterator();
????? while(iterator.hasNext()){
???????? System.out.println(((Drink)iterator.next()).name);?? //输出只有Coffee
????? }
?? }

??????? 再就是想到Set另一个重要子类HashSet,这个集合类继承于Set接口,爷爷是Collection接口,与HashMap没有什么直系血缘关系。首先他接受一个参数的泛型,泛型的作用就是在编译期去严格检查输入类型,HashSet添加元素时,需要对这个泛型类的hashCode值进行判断,测试是否为重复元素,代码如下:

import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;

public class HashSetTest {
?? public static void main(String[] args) {
????? Set<Pig> hashset = new HashSet<Pig>();
????? hashset.add(new Pig("X"));
????? hashset.add(new Pig("Y"));
????? hashset.add(new Pig("X"));
????? Iterator<Pig> iterator = hashset.iterator();
????? while(iterator.hasNext()){
???????? System.out.println(iterator.next().name);
????? }
?? }
}

class Pig{
?? public String name;
?? public Pig(String name){
????? this.name = name;
?? }
??
?? public boolean equals(Object o){ //如果不重写,那么所有的new Pig都会被加入,因为hashCode的默认是每个对象惟一的,与equals继承与Object,eqauls在那个阶段与==无异
????? String name = ((Pig)o).name;
????? if(this.name.equals(name)){
???????? return true;
????? }else
???????? return false;
?? }
??
?? public int hashCode(){??? //重复测试,首先测试hashCode值,如果一样,再测试equals结果。
?????? return 0;??? //这里只是测试方便这么写了,事实上,如果这么写,是没有任何存储效率的。
?? }
}

?

  • 相关文章
发表评论
用户名: 匿名