黑马程序员技术交流社区

标题: 关于集合的问题 [打印本页]

作者: fenzheng    时间: 2014-4-12 09:48
标题: 关于集合的问题
为什么在重写了equals( )方法后还要重写hashcode( )方法?
作者: 2528870651    时间: 2014-4-12 11:01
说说 哪一个集合里面没搞清楚 说具体一点啊

作者: 2528870651    时间: 2014-4-12 11:04
通过new的方式往HashSet里面存的元素的hashCode都不同,但通常我们定义对象,
比如学生对象时,虽然是new的两个学生对象,但是当他们name和age一样时,我们认为是
  同一个对象,所以为了保证元素的唯一性,我们通常在往HashSet集合里面存储元素时,
   在定义对象的类中通常复写hashCode和equals方法。
  1.                               public int hashCode()
  2.                               {
  3.                                 return name.hashCode()+age*39;
  4.                               }
  5.                               public boolean equals(Object obj)
  6.                               {
  7.                                 if(!(obj instanceof Student))
  8.                                         return false;
  9.                                 Student stu = (Student)obj;
  10.                                 return this.name.equals(stu.name)&&this.age==stu.age;
  11.                               }
复制代码

作者: 491138002    时间: 2014-4-12 11:05
hashmap中value的查找是通过 key 的 hashcode 来查找,所以对自己的对象必须重写 hashcode 通过 hashcode 找到对象后会用 equals 比较你传入的对象和 hashmap 中的 key 对象是否相同,所以要重写 equals.
1、重写equals方法时需要重写hashCode方法,主要是针对Map、Set等集合类型的使用;
a: Map、Set等集合类型存放的对象必须是唯一的;
b: 集合类判断两个对象是否相等,是先判断equals是否相等,如果equals返回TRUE,还要再判断HashCode返回值是否ture,只有两者都返回ture,才认为该两个对象是相等的。
2、由于Object的hashCode返回的是对象的hash值,所以即使equals返回TRUE,集合也可能判定两个对象不等,所以必须重写hashCode方法,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一。
作者: 2528870651    时间: 2014-4-12 11:05
举了一个例子,就是要保证元素的唯一性
作者: H._张_♂    时间: 2014-4-12 11:16
Set接口
HashSet:
数据结构是哈希表,线城是同步的
保证元素唯一性的原理。判断元素的hashCode是否相同
如果相同,还会继续判断元素的equals方法是否为true
ThreeSet:
可以对set集合的元素进行排序、默认顺序是自然顺序
往ThreeSet内存对象,必须在该对象中写出compareTo比较方法。及必须实现Comparator接口强制让学生具备比较性。
排序时,当主要条件相同时,一定要比较次要条件。
底层数据结构是二叉树
保证元素唯一性的依据
compareTo方法return 0时,表示两个元素相同,1表示前大于后,-1表示前小于后

如果改写compareTo 一直返回1,这表示按输入顺序存放

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

当一个集合中的某个元素在存入之后修改与hashCode有关的变量,这个元素就会无法在集合中删除,造成内存泄漏。
比如这个题:
  1. package com.itheima;

  2. import java.util.HashSet;
  3. import java.util.Set;

  4. public class HashCodeTest {

  5.         public static void main(String[] args) {
  6.                 // TODO Auto-generated method stub
  7.                 Set<Person>  set = new HashSet<Person>();
  8.                 Person p1=new Person(10);
  9.                 Person[] p = new Person[2];
  10.                 set.add(p1);//set中一个元素
  11.                 p1.setAge(11);//p1的age改成11
  12.                 System.out.println(set.remove(p1));//移走P1,输出false,说明p1没有被移走,这是为什么?
  13.                 System.out.println(set.contains(p1));//输出false,集合中不包含p1,说明p1不在集合中,p1究竟去哪里了?
  14.                 System.out.println(set.size());//结果为1.说明p1没有被移走,究竟存的是谁?怎么拿出来?
  15.                 p= set.toArray(p);//将set中的所有元素变成p数组
  16.                 System.out.println(p[0]);//输出为11,说明set集合中还有年龄为11的这个对象
  17.         }
  18. }
  19. class Person{
  20.         private int age;
  21.         Person (int age){
  22.                 this.age =age;
  23.         }
  24.         @Override
  25.         public int hashCode() {
  26.                 return super.hashCode()*age;
  27.                
  28.         }
  29.         public void setAge(int i) {
  30.                 this.age = i;
  31.         }
  32.         @Override
  33.         public String toString() {
  34.                 return ""+age;
  35.         }
  36. }
复制代码





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