java中重写equals和hashCode方法
2017-05-24 13:31
477 查看
java中重写equals和hashCode方法
为什么要重写equals和hashCode方法
1.需要将对象放入HsahMap、HashSet等集合中的类需要重写HashCode和equals()方法:
Hashcode在基于key-value的集合如:HashMap、LinkedHashMap中扮演很重要的角色。此外在HashSet集合中也会运用到,使用合适的hashcode方法在检索操作时的时间复杂度最好的是 O(1).hashCode()和equals()定义在Object类中,这个类是所有Java类的基类,所以所有的java类都继承这两个方法。
hashCode()方法被用来获取给定对象的唯一整数。这个整数被用来确定对象被存储在HashTable类似的结构中的位置。默认的,Object类的hashCode()方法返回这个对象存储的内存地址的编号。
参考Josh Bloch的书《Effective Java》,一个好的hashcode方法通常最好是不相等的对象产生不相等的hash值,理想情况下,hashcode方法应该把集合中不相等的实例均匀分布到所有可能的hash值上面。
补充一个类似的:什么时候类需要实现Serializable接口:当某个类的实体对象需要持久化到硬盘,或通过网络传输数据
2. 对于对象中的每个域,hashCode值遵循以下原则
为该域计算int类型的哈希值hc:如果是boolean类型,计算(f?1:0)
如果是byte、char、short或者int类型,计算(int)f
如果是long类型,计算(int)(f^(f>>>32))
如果是float类型,计算Float.floatToIntBits(f)
如果是double类型,计算Double.doubleToLongBits(f),然后重复第三个步骤。
如果是一个对象引用,并且该类的equals方法通过递归调用equals方法来比较这个域,同样为这个域递归的调用hashCode,如果这个域为null,则返回0。
如果是数组,要把每一个元素当作单独的域来处理,递归的运用上述规则,如果数组域中的每个元素都很重要,那么可以使用Arrays.hashCode方法。
把上面计算得到的hash值hc合并到result中
result = result*31 + hc;
1
1
String中的Hashcode方法
String的hashcode的算法就充分利用了字符串内部字符数组的所有字符。生成hash码的算法的在string类中看起来像如下所示,注意“s“是那个字符数组,n是字符串的长度。
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
1
1
eclipse中自动生成Hashcode方法
如使用username 和password字段来生成hashCode
/** * 根据userName和password来计算hashCode */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((userName == null) ? 0 : userName.hashCode()); return result; }
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
企业级应用中一般推荐使用第三方库如Apache commons来生成hashocde方法。
Apache commons HashcodeBuilder
我们可以用Apache Commons hashcode builder来生成代码,使用这样一个第三方库的优势是可以反复验证尝试代码。下面代码显示了如何使用Apache Commons hash code 为一个自定义类构建生成hash code 。
public int hashCode(){ HashCodeBuilder builder = new HashCodeBuilder(); builder.append(mostSignificantMemberVariable); ....................... builder.append(leastSignificantMemberVariable); return builder.toHashCode(); }
1
2
3
4
5
6
7
1
2
3
4
5
6
7
equals方法重写
eclipse中自动生成equals方法如使用username 和password字段来生成equals
/** * 重写equals()方法,只要name、pass相等的员工即可认为相等 */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (password == null) { if (other.password != null) return false; } else if (!password.equals(other.password)) return false; if (userName == null) { if (other.userName != null) return false; } else if (!userName.equals(other.userName)) return false; return true; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
注意以下几点
尽量保证使用对象的同一个属性来生成hashCode()和equals()两个方法。在我们的案例中,我们使用员工id。eqauls方法必须保证一致(如果对象没有被修改,equals应该返回相同的值)
任何时候只要a.equals(b),那么a.hashCode()必须和b.hashCode()相等。
两者必须同时重写。
当使用ORM的时候特别要注意的
如果你使用ORM处理一些对象的话,你要确保在hashCode()和equals()对象中使用getter和setter而不是直接引用成员变量。因为在ORM中有的时候成员变量会被延时加载,这些变量只有当getter方法被调用的时候才真正可用。例如在我们的例子中,如果我们使用e1.id == e2.id则可能会出现这个问题,但是我们使用e1.getId() ==
e2.getId()就不会出现这个问题。
顶0踩
相关文章推荐
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- Java中重写Object类的equals方法和Hashcode方法的注意事项
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- java 重写类的equals方法和hashcode方法
- JAVA中重写equals()方法的同时要重写hashcode()方法
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)
- java 重写HashCode和equals方法以及 HashMap集合 增 删 改 查
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- 学习笔记-JAVA-考点10-什么情况下需要重写equals和hashcode()两个方法?
- java equals与hashCode 两个重要方法的重写
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- 【Java基础】JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例
- 重写Java Object对象的hashCode和equals方法实现集合元素按内容判重