黑马程序员技术交流社区

标题: 关于保证集合元素唯一性的问题 [打印本页]

作者: 刘元明    时间: 2012-3-25 08:14
标题: 关于保证集合元素唯一性的问题
我们知道TreeSet集合是通过compareTo方法返回0来保证元素的唯一性,
但是为什么当老师将到将封装的学生对象存进TreeSet集合或者TreeMap集合,并按一定顺序存时,总会将equals和hashcode方法写上?
作者: 袁野    时间: 2012-3-25 08:55
不用equals 对象 无法保证对象的唯一啊,因为学生对象是自定义类型,先用hashcode 判断他们的地址是否相同,如果相同,才使用equals 判断是否内容相同,相同则是同一个对象 就被覆盖,否则就会存存起来
作者: 许前刚    时间: 2012-3-25 09:49
TreeSet排序的第一种方式:
让元素自身具备比较性,元素需要实现Compareable接口,覆盖compareTo方法,这种顺序也叫自然顺序,也叫默认顺序。

TreeSet集合的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时需要让集合自身具备比较性。

int equals(Object o) 和boolean hashCode() 是接口Collection<E>的方法,所有的集合都继承自Collection,Set集合里的元素是唯一的,Map集合里的键是唯一的,要想保证Set和Map里的元素唯一,原理是判断元素的hashcode是否相同,如果相同,还会继续判断元素的equals方法,是否为true。



作者: 朱辉    时间: 2012-3-25 10:19
许前刚 发表于 2012-3-25 09:49
TreeSet排序的第一种方式:
让元素自身具备比较性,元素需要实现Compareable接口,覆盖compareTo方法,这种 ...

如果是往HashSet集合里面装入学生的话,为了保证唯一性确实是需要重写hashCode方法和equals方法,但是现在明确了要往TreeSet集合里面装入学生对象的话,为什么还要重写这两个方法?学生对象不具备比较性,但是可以自定义一个比较器,让学生对象具备比较性
作者: 许前刚    时间: 2012-3-25 10:47
朱辉 发表于 2012-3-25 10:19
如果是往HashSet集合里面装入学生的话,为了保证唯一性确实是需要重写hashCode方法和equals方法,但是现 ...

因为set集合中不会存储相同的元素,而是否相同也是你判断的。为了方便,内部的规则是先判断hashcode,如果hashcode不同的话就直接存入。如果hashcode相同的再判断equals是不是true。
    虚拟机判断两个元素是不是相同首先判断两个元素的hashcode,如果hashcode不同,则直接认为不同;如果hashcode相同,再判断equals方法是不是相同,如果equals不同,则两个元素不同,如果equals相同,则才会最终认为元素相同。因为很多系统的类实现了这些方法,因此我们在自定义的时候可以拿来调用系统类的这些方法。
作者: 刘元明    时间: 2012-3-25 19:56
许前刚 发表于 2012-3-25 10:47
因为set集合中不会存储相同的元素,而是否相同也是你判断的。为了方便,内部的规则是先判断hashcode,如 ...

但TreeSet集合保证元素唯一性的依据不是通过compareTo()方法吗,如果返回0,就表示相同啊
就比如封装一个有姓名有年龄的学生对象,compareTo方法如下:
public int compareTo(Student s)
{
       int num=new Integer(this.age).compareTo(new Integer (s.age))
       if(num==0)
       {
                return this.name.compareTo(s.name);
        }
        return num;
}
作者: 刘元明    时间: 2012-3-25 19:56
朱辉 发表于 2012-3-25 10:19
如果是往HashSet集合里面装入学生的话,为了保证唯一性确实是需要重写hashCode方法和equals方法,但是现 ...

这也就是我迷惑的地方啊
作者: 刘元明    时间: 2012-3-25 20:24
呵呵,通过查Api文档我明白了,原因是这样的:因为 Set 接口是按照 equals 操作定义的,
但 TreeSet 实例使用它的 compareTo(或 compare)方法对所有元素进行比较,因此从 set 的观点来看,
此方法认为相等的两个元素就是相等的,为保证equals方法定义相等的比较方式和指定比较器定义相等的方式相符合,
就把它们都写上了,这样就不会不一致,而当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2