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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何明辉 中级黑马   /  2012-8-12 12:30  /  1816 人查看  /  4 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

import java.util.*;
class Person
{
private String name;
private int age;
Person(String name,int age)
{
  this.name=name;
  this.age=age;
}
public int hashCode()
{
  
  return 60;
}
}
class PersonDemo
{
public static void main(String[] args)
{
  HashSet a1=new HashSet();
  a1.add(new Person("he",24));
  a1.add(new Person("he",24));
  a1.add(new Person("he",24));
  System.out.println(a1);
}
}
上面的程序中自己定义了一个类Person,复写了Person中的hashCode方法,将哈希值设成一样,而equlas方法依然是Object的方法,为什么的输出时候三个地址都输出了,Object比较的不是对象的地址吗,也就是调用类Person中的hashCode方法啊,所以应该智慧输出第一的对象的地址值啊。

评分

参与人数 2技术分 +1 黑马币 +15 收起 理由
张_涛 + 1 赞一个!
杨志 + 15 鼓励一下吧!

查看全部评分

4 个回复

倒序浏览
HashSet保证元素唯一性是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals。
楼主复写了hashCode,让对象的hash值都相同了,那就会去调用equals方法了,因为楼主没有复写equals方法
用的是父类的equals方法,比较的是两个对象是否是同一个,楼主new了三个对象,肯定不同,所以就是打印三个了!
回复 使用道具 举报
顶楼主 看了一下我也有点不明白了,Object中的 equals方法的实现 也是对传入的对象进行引用比较
public boolean equals(Object obj) {
        return (this == obj);
    }
引用比较就是比较两个对象的hashcode的值是否相同,这个例子中我们可以看到
new出来的三个对象new Person("he",24) 用hashCode()方法得到的hashcode都是复写后所给定的值
那么用 Object中的 equals() 所得到的返回值 难得不应该是 true吗?

求高手解释。。
回复 使用道具 举报
个人理解 Object类中的equals方法并不是完全依据 hashcode来判断两对象是否相等。
查API文档可以发现
hashcode中描述有这么一句话
“如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果
如果Object中的equals方法真的是完全靠hashcode来判断的话,就不可能出现这种情况。

当然 这个推理反过来是不成立的
因为在 对equals(java.lang.Object)的描述中提到了“该协定声明相等对象必须具有相等的哈希码”。

在你的代码中明显 对象不同,因为都是new出的,但hashcode值相同。

以上是个人分析,不喜勿喷 欢迎讨论
回复 使用道具 举报

import java.util.HashSet;

public class TestEquals {
        public static void main(String args[]) {
                HashSet a1 = new HashSet();
                Person a = new Person("he", 23);
                Person b = new Person("he", 23);
                Person c = new Person("he", 23);
                a1.add(a);
                a1.add(b);
                a1.add(c);
                //从这个输出语句可以看出,a1中返回三个相同的hashCode
                System.out.println(a1);
                //a和b引用的是对象的地址值,但是在用“==”用等号验证的时候返回false
                System.out.println(a ==b);
                //而用equals验证的时候,返回的也是false,因为equals函数默认情况下调用的也是“==”
                //下面就是调用的equals
                //                public boolean equals(Object obj) {
                //                        return (this == obj);
                //                    }
                System.out.println(a.equals(b));//false
                System.out.println(a.toString());
                System.out.println(b.toString());
                //在举一例子,这两个字符串不相同
                String aString = "Aa";
                String bString = "BB";
                //在输出的时候,它们的hashcode是相同的,都是2112,但是执行equals时,返回的是false
                System.out.println(aString.hashCode());//2112
                System.out.println(bString.hashCode());//2112
                System.out.println(bString.equals(aString));//false
                //综上所知,hashcode相同,不一定能保证两个对象时同一个对象,
                //为了安全起见,在使用HashSet的情况下,最好要同时重写equals()和hashcode()方法
        }

}

class Person {
        private String name;
        private int age;

        Person(String name, int age) {
                this.name = name;
                this.age = age;
        }

        public int hashCode() {
                Object o;

                return 60;
        }
}

class PersonDemo {

}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马