hashCode()的作用
来源:互联网 发布:动态表单数据库设计 编辑:程序博客网 时间:2024/06/14 03:12
1.hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序这一章有
例如内存中有这样的位置
0 1 2 3 4 5 6 7
而我有个类,这个类有个字段叫ID,我要把这个类存放在以上8个位置之一,如果不用hashcode而任意存放,那么当查找时就需要到这八个位置里挨个去找,或者用二分法一类的算法。
但如果用hashcode那就会使效率提高很多。
我 们这个类中有个字段叫ID,那么我们就定义我们的hashcode为ID%8,然后把我们的类存放在取得得余数那个位置。比如我们的ID为9,9除8的余 数为1,那么我们就把该类存在1这个位置,如果ID是13,求得的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过ID除8求余数直接找到存放的位置了。
2.但是如果两个类有相同的hashcode怎么办那(我们假设上面的类的ID不是唯一的),例如9除以8和17除以8的余数都是1,那么这是不是合法的,回答是:可以这样。那么如何判断呢?在这个时候就需要定义 equals了。
也就是说,我们先通过 hashcode来判断两个类是否存放某个桶里,但这个桶里可能有很多类,那么我们就需要再通过 equals 来在这个桶里找到我们要的类。
那么。重写了equals(),为什么还要重写hashCode()呢?
想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊
3。你要对A类排序,有两种方法,一种就是让A类实现comparabole结构并实现compareTo()方法,那么可以通过Collections.sort(List <A> list)对其进行排序
另一种方法:自己定义一个类B实现Comparator类并实现compare方法,
然后通过Collections.sort(List <A> list,B b)进行排序
hashCode()是用来产生哈希玛的,而哈希玛是用来在散列存储结构中确定对象的存储地址的,(这一段在 Java编程思想 中讲的很清楚的)象util包中的 带hash 的集合类都是用这种存储结构 :HashMap,HashSet, 他们在将对象存储时(严格说是对象引用),需要确定他们的地址吧, 而HashCode()就是这个用途的,一般都需要重新定义它的,因为默认情况下,由 Object 类定义的 hashCode方法会针对不同的对象返回不同的整数,这一般是通过将该对象的内部地址转换成一个整数来实现的,现在举个例子来说, 就拿HashSet来说 ,在将对象存入其中时,通过被存入对象的 hashCode() 来确定对象在 HashSet中的存储地址,通过equals()来确定存入的对象是否重复,hashCode(),equals()都需要自己重新定义,因为hashCode()默认前面已经说啦,而equals()默认是比较的对象引用,你现在想一下,如果你不定义equals()的话,那么同一个类产生的两个内容完全相同的对象都可以存入Set,因为他们是通过equals()来确定的,这样就使得HashSet 失去了他的意义,看一下下面这个:
1
2 public class Test {
3 public static void main(String[] args) {
4 HashSet set = new HashSet();
5 for (int i = 0; i <= 3; i++){
6 set.add(new Demo1(i,i));
7 }
8 System.out.println(set);
9 set.add(new Demo1(1,1));
10 System.out.println(set);
11 System.out.println(set.contains(new Demo1(0,0)));
12 System.out.println(set.add(new Demo1(1,1)));
13 System.out.println(set.add(new Demo1(4,4)));
14 System.out.println(set);
15 }
16
17 private static class Demo1 {
18 private int value;
19
20 private int id;
21
22 public Demo1(int value,int id) {
23 this.value = value;
24 this.id=id;
25 }
26
27 public String toString() {
28 return " value = " + value;
29 }
30
31 public boolean equals(Object o) {
32 Demo1 a = (Demo1) o;
33 return (a.value == value) ? true : false;
34 }
35
36 public int hashCode() {
37 return id;
38 }
39 }
40 }
你分别注释掉hashCode()和 equals()来比较一下他们作用就可以拉,关键要自己动手看看比较的结果你就可以记得很清楚啦
如果还不是很明确可以再看另一个例子:
41
42 public final class Test {
43
44 public static void main(String[] args) {
45 Map m = new HashMap();
46 m.put(new PhoneNumber(020, 12345678), "shellfeng");
47 System.out.println(m.get(new PhoneNumber(020, 12345678)));
48 }
49
50 private static class PhoneNumber {
51 /**
52 * 区号
53 */
54 private short areaCode;
55
56 /**
57 * 扩展号
58 */
59 private short extension;
60
61 public PhoneNumber(int areaCode, int extension) {
62 this.areaCode = (short) areaCode;
63 this.extension = (short) extension;
64 }
65
66 public boolean equals(Object o) {
67 if (o == this) {
68 return true;
69 }
70 if (!(o instanceof PhoneNumber)) {
71 return false;
72 }
73 PhoneNumber pn = (PhoneNumber) o;
74 return pn.extension == extension && pn.areaCode == areaCode;
75 }
76
77 /**
78 * @see java.lang.Object#hashCode()
79 * @return result就是我们得到的散列值,其实我们的计算过程可以多种,这里只不过是一个例子,需要你的灵活运用,使其接近你需要的理想结果
80 */
81 public int hashCode() {
82 int result = 17;
83 result = 37 * result + areaCode;
84 result = 37 * result + extension;
85 return result;
86 }
87 }
88 }
还是那句话:你注释掉hashCode()比较一下他们作用就可以拉,关键要自己动手看看比较的结果你就可以记得很清楚啦
总结
hashCode()方法使用来提高Map里面的搜索效率的,Map会根据不同的hashCode()来放在不同的桶里面,Map在搜索一个对象的时候先通过hashCode()找到相应的桶,然后再根据equals()方法找到相应的对象.要正确的实现Map里面查找元素必须满足一下两个条件:
(1)当obj1.equals(obj2)为true时obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时obj.equals(obj2)必须为false
Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。
那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是Object.equals方法了。
但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。
也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。
哈 希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。我们可以认为hashCode方法返回的就是对象存储的物理地址(实际可能并不是,例 如:通过获取对象的物理地址然后除以8再求余,余数几是计算得到的散列值,我们就认为返回一个不是物理地址的数值,而是一个可以映射到物理地址的值)。
这 样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直 接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列 其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
- hashCode的作用
- hashCode()的作用
- Hashcode的作用
- hashCode()的作用
- Hashcode 的作用
- hashCode()的作用
- HashCode的作用
- HashCode的作用
- hashcode的作用
- HashCode的作用
- hashcode()的作用
- HashCode的作用
- hashcode的作用
- hashCode()的作用
- HashCode方法的作用
- hashCode()的作用
- hashcode的作用
- hashCode()方法的作用
- 黑马程序员 网络编程
- 每天一个linux命令目录
- git的使用之三
- 动态链接库DLL创建和使用
- Data Modle:游戏对战模型
- hashCode()的作用
- J2EE中JSP页面引用外部资源时的路径问题
- protected成员在c++和java的区别
- Ubuntu 13.04 flash
- 花1元钱试用了阿里云服务器
- Miller_Rabbin 素数测试
- hdu-1031
- 改造nachos内核以支持多道程序4(转)
- vim插入模式下的技巧