A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

在学习集合的时候equals和hashcode要重写的问题?我是想问在哪些情况下一定要重写这两个方法...求解?

8 个回复

倒序浏览
当你在hashSet集合中添加对象的时候  而且这个对象你想自定义排序   比如按姓名  年龄  学号 身份证 等等排序的时候
就必须复写hashCode 和equals方法      而 hashCode和equals方法都是Object中的方法  所以任何对象都有这两个方法
    hashCode的默认方法 也就是在Object中是按照哈希值大小排序的    而哈希值在内存中是唯一的   就是内存地址值
  所以你添加的对象都不同的   这显然就不能添加一个类的多个对象了  所以这个时候必须复写hashCode
    在hashSet  集合中  add 元素时  是由add自动调用元素的hashCode方法的   如果hashCode值相同 则才会调用equals方法在做比较
   至于到底要不要复写equals方法 就看需求了  比如只让元素按长度排序  其他的不考虑 就不需要复写equals放法了
  如果既要判断元素的长度  还要判断元素的大小  哪就必须复写equals方法了   
回复 使用道具 举报
只是为了维护 hashCode 方法的常规协定,才要求用equals比较的两个对象的hashCode相同.

equals()和hashCode()都来自java.lang.Object。可以重写.

比如a.equals(b).仅当a的内存地址相等时,才返回true.当然如String等类已经对这个方法进行了重写,比较的就不再是内存地址了.

hashCode()的值也是与内存地址相关的.所以仅当内存地址相等时,hashCode才相等.同样很多类也重写了这个方法,还是以String为例:
    public int hashCode() {
int h = hash;
if (h == 0) {
     int off = offset;
     char val[] = value;
     int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }
就不在与内存地址相关了.这样做是为了保证用equals比较返回为true的两个对象,他们的hashCode是相同的.

所以一般重写equals的时候都会重写hashCode().
回复 使用道具 举报
首先,你要用的集合的底层数据结构是哈希表。用得时候根据需求
回复 使用道具 举报
本帖最后由 抓哇 于 2012-3-27 17:55 编辑
贠(yun)靖 发表于 2012-3-27 04:56
当你在hashSet集合中添加对象的时候  而且这个对象你想自定义排序   比如按姓名  年龄  学号 身份证 等等排 ...


我怎么觉得 如果hashCode值相同 则不会调用equals方法的
如果哈希值不相同才会调用equals方法

。。。搞错老 如果hashCode值不同 equals也必不相同
            如果hashCode值相同 当添加元素时会调用equals方法
回复 使用道具 举报
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


public class TestHashMap {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
      Map map=new HashMap();
     
      map.put(new Student4("liumeng","nan"),2);
      map.put(new Student4("liumeng","nan"), 3);
      Set s2=map.keySet();
      System.out.println(s2);
//      map.put("liumeng", 3);
//      map.put("liumeng", 3);
//      Set s3=map.keySet();
//      System.out.println(s3);
        }

}
class Student4
{
//        @Override
//        public int hashCode() {
//                final int prime = 31;
//                int result = 1;
//                result = prime * result + ((name == null) ? 0 : name.hashCode());
//                result = prime * result + ((sex == null) ? 0 : sex.hashCode());
//                return result;
//        }
//        @Override
//        public boolean equals(Object obj) {
//                if (this == obj)
//                        return true;
//                if (obj == null)
//                        return false;
//                if (getClass() != obj.getClass())
//                        return false;
//                Student4 other = (Student4) obj;
//                if (name == null) {
//                        if (other.name != null)
//                                return false;
//                } else if (!name.equals(other.name))
//                        return false;
//                if (sex == null) {
//                        if (other.sex != null)
//                                return false;
//                } else if (!sex.equals(other.sex))
//                        return false;
//                return true;
//        }
        private String name;
        private String sex;
        public Student4(String name,String sex)
        {
                this.name=name;
                this.sex=sex;
        }
}这会输出
[Student4@1fb8ee3, Student4@c17164]

回复 使用道具 举报
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


public class TestHashMap {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
      Map map=new HashMap();
     
      map.put(new Student4("liumeng","nan"),2);
      map.put(new Student4("liumeng","nan"), 3);
      Set s2=map.keySet();
      System.out.println(s2);
//      map.put("liumeng", 3);
//      map.put("liumeng", 3);
//      Set s3=map.keySet();
//      System.out.println(s3);
        }

}
class Student4
{
        @Override
        public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + ((name == null) ? 0 : name.hashCode());
                result = prime * result + ((sex == null) ? 0 : sex.hashCode());
                return result;
        }
        @Override
        public boolean equals(Object obj) {
                if (this == obj)
                        return true;
                if (obj == null)
                        return false;
                if (getClass() != obj.getClass())
                        return false;
                Student4 other = (Student4) obj;
                if (name == null) {
                        if (other.name != null)
                                return false;
                } else if (!name.equals(other.name))
                        return false;
                if (sex == null) {
                        if (other.sex != null)
                                return false;
                } else if (!sex.equals(other.sex))
                        return false;
                return true;
        }
        private String name;
        private String sex;
        public Student4(String name,String sex)
        {
                this.name=name;
                this.sex=sex;
        }
}
这会输出
[Student4@53457e13]
回复 使用道具 举报
而hashset看
import java.util.HashSet;
import java.util.Set;


public class TestHashSet {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
        Set s=new HashSet();
        s.add(new Student5("liumeng"));
        s.add(new Student5("liumeng"));
        System.out.println(s.contains(new Student5("liumeng")));
        }

}
class Student5
{
        private String name;
        public Student5(String name)
        {
                this.name=name;
        }
}
输出false
回复 使用道具 举报
抓哇 发表于 2012-3-27 17:42
我怎么觉得 如果hashCode值相同 则不会调用equals方法的
如果哈希值不相同才会调用equals方法

- -! hashCode的值相同了  不调用equals方法判断次要条件    还有其他方式吗?
     hashCode的值不想同了  第一个条件都不满足  就表示集合中的元素肯定不一样了  还判断equals不是多此一举吗?   
     默认的hashCode是唯一的值   如果自己复写的hashCode方法的话  很有可能会出现不同的对象但是hashCode的值相同   你把这些搞混了   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马