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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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

8 个回复

正序浏览
抓哇 发表于 2012-3-27 17:42
我怎么觉得 如果hashCode值相同 则不会调用equals方法的
如果哈希值不相同才会调用equals方法

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

回复 使用道具 举报
本帖最后由 抓哇 于 2012-3-27 17:55 编辑
贠(yun)靖 发表于 2012-3-27 04:56
当你在hashSet集合中添加对象的时候  而且这个对象你想自定义排序   比如按姓名  年龄  学号 身份证 等等排 ...


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

。。。搞错老 如果hashCode值不同 equals也必不相同
            如果hashCode值相同 当添加元素时会调用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().
回复 使用道具 举报
当你在hashSet集合中添加对象的时候  而且这个对象你想自定义排序   比如按姓名  年龄  学号 身份证 等等排序的时候
就必须复写hashCode 和equals方法      而 hashCode和equals方法都是Object中的方法  所以任何对象都有这两个方法
    hashCode的默认方法 也就是在Object中是按照哈希值大小排序的    而哈希值在内存中是唯一的   就是内存地址值
  所以你添加的对象都不同的   这显然就不能添加一个类的多个对象了  所以这个时候必须复写hashCode
    在hashSet  集合中  add 元素时  是由add自动调用元素的hashCode方法的   如果hashCode值相同 则才会调用equals方法在做比较
   至于到底要不要复写equals方法 就看需求了  比如只让元素按长度排序  其他的不考虑 就不需要复写equals放法了
  如果既要判断元素的长度  还要判断元素的大小  哪就必须复写equals方法了   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马