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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈帅雷 黑马帝   /  2011-12-23 10:24  /  2451 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 陈帅雷 于 2011-12-23 12:22 编辑

hsaCode和equals的作用,谁详细的讲解下啊?:)

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

5 个回复

倒序浏览
杨强 黑马帝 2011-12-23 10:30:02
沙发
HashSet和HashMap一直都是JDK中最常用的两个类,HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。
那么Java运行时环境是如何判断HashSet中相同对象、HashMap中相同键的呢?当存储了“相同的东西”之后Java运行时环境又将如何来维护呢?

在研究这个问题之前,首先说明一下JDK对equals(Object obj)和hashcode()这两个方法的定义和规范:
在Java中任何一个对象都具备equals(Object obj)和hashcode()这两个方法,因为他们是在Object类中定义的。
equals(Object obj)方法用来判断两个对象是否“相同”,如果“相同”则返回true,否则返回false。
hashcode()方法返回一个int数,在Object类中的默认实现是“将该对象的内部地址转换成一个整数返回”。
接下来有两个个关于这两个方法的重要规范(我只是抽取了最重要的两个,其实不止两个):
规范1:若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。说得简单点就是:“如果两个对象相同,那么他们的hashcode应该 相等”。不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true而hashcode()返回两个不相等的值,编译和运行都是不会报错的。不过这样违反了Java规范,程序也就埋下了BUG。
规范2:如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。说的简单点就是:“如果两个对象不相同,他们的hashcode可能相同”。
根据这两个规范,可以得到如下推论:
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。
2、如果两个对象不equals,他们的hashcode有可能相等。
3、如果两个对象hashcode相等,他们不一定equals。
4、如果两个对象hashcode不相等,他们一定不equals。

这样我们就可以推断Java运行时环境是怎样判断HashSet和HastMap中的两个对象相同或不同了。我的推断是:先判断hashcode是否相等,再判断是否equals。

评分

参与人数 1技术分 +1 收起 理由
王德云 + 1

查看全部评分

回复 使用道具 举报
对象存在哈希集合中,hashcode和equals方法才有价值
  
查找对象, 根据算出来的哈希值,看哈希值属于那个区域 然后直接去该区域查找相应的值

存放对象的时候,把集合分成若干个区域,第一个要存的对象可以算出来一个哈希值,根据这个值把对象放到相应的区域

当集合里面的对象需要判断是否重复时可以用Hashcode先判断他们的哈希值是否相同,如果相同再用equals判断他们的内容

注意:
当某个对象的属性值参与hashcode的算法时,就不要更改属性的值
属性更改后,对应的hashcode值也会改变,无法删除,导致内存泄漏:

@Override
public int hashCode()
{
   name属性,参与的hashcode 的算法;

   return name.hashCode() + age*2;
   // 字符串也有自己的hashcode   
   //如果用底层hashcode比较地址,得到的都是不同的地址,不能保证元素的唯一性;
}
如何保证元素唯一行的呢?
通过2个方法,hashcode  equals

如果元素的hashcode值相同,才会判断equals是否为true
如果元素的hashcode值不同,不会调用equals。




评分

参与人数 1技术分 +1 收起 理由
王德云 + 1

查看全部评分

回复 使用道具 举报
Set中为了保证元素的唯一性,需要覆写equals和hashCode两个方法。如果元素的HashCode值相同,才会判断equals是否为真,如果元素的HashCode值不同,不会调用equals。
回复 使用道具 举报
楼上说的那么复杂,我就说的简单点:
hashcode()用来快速判断两个对象是否是一个,比较的是两个对象的hashcode码,如果两个对象的hashcode码一样,就会接着调用equals方法判断;
如果不相等就不会再去判断了。
回复 使用道具 举报
  在Object类中的定义:
No.        方法名称                             类型        描述
1        public boolean equals(Object obj)        普通        判断是否相等
2        public int hashCode()                        普通        对象编码
  hashCode()就相当于一个对象的唯一的编号,而如果要想进行具体的内容验证,就需要使用equals()方法完成。hashCode()方法返回的是一个数字,那么很明显,就必须通过一种算法,可以完成一个唯一的编号。如果现在使用的是eclipse进行开发的话,则此工具将会自动生成编号和比较。
具体用法示例:
import java.util.HashSet;
import java.util.Set;
class Person{
        private String name;
        private int age;
        public Person(String name, int age) {
                this.name = name;
                this.age = age;
        }
        @Override
        public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + age;
                result = prime * result + ((name == null) ? 0 : name.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;
                Person other = (Person) obj;
                if (age != other.age)
                        return false;
                if (name == null) {
                        if (other.name != null)
                                return false;
                } else if (!name.equals(other.name))
                        return false;
                return true;
        }
        public String toString() {
                return "姓名:" + this.name + ",年龄:" + this.age;
        }
}
public class RepeatDemo {
        public static void main(String[] args) {
                Set<Person> all = new HashSet<Person>();
                all.add(new Person("张三", 20));
                all.add(new Person("李四", 20));
                all.add(new Person("李四", 20));
                all.add(new Person("王五", 19));
                System.out.println(all);
        }
}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马