java覆写hashcode方法
覆写hashcode
1. 把某个非零常数值,例如17,保存在int变量result中;
2. 对于对象中每一个关键域f(指equals方法中考虑的每一个域):
3, boolean型,计算(f? 0 : 1);
4. byte,char,short型,计算(int);
5. long型,计算(int)(f ^ (f>>>32));
6. float型,计算Float.floatToIntBits(afloat);
7. double型,计算Double.doubleToLongBits(adouble)得到一个long,再执行[2.3];
8. 对象引用,调用对象.hashCode()方法;
9. 对象数组域,对其中每个元素递归调用它的hashCode方法。
10. 基本数组域,对其中每个元素计算,根据类型返回2
11. 将上面计算得到的散列码保存到int变量c,然后执行result=37*result+c;
12. 返回result。
例子:
/****
*
*
* java 八大基本数据类型
*/
private int A_int;
private short A_short;
private char A_char;
private byte A_byte;
private double A_double;
private float A_float;
private boolean A_boolean;
private long A_long;
private Demo demo;// 对象
private int[] intArray;// 数组域
private Demo[] demos;// 对象数组域 @Override
public int hashCode() {
int result=17;
result =31*result+A_int;
result =31*result+(int)A_short;
result =31*result+(int)A_char;
result =31*result+(int)A_byte;
result =31*result+(int)(A_boolean?0:1);
result =31*result+(int)(A_long^(A_long >>> 32));
result=31*result+Float.floatToRawIntBits(A_float);
long tolong = Double.doubleToLongBits(A_double);
result = 31 * result + (int) (tolong ^ (tolong >>> 32)); result =31*result+demo.hashCode(); //object
result =31*result+intArrayHashcode(intArray);//数组域,对其中每个元素调用它的hashCode方法。
result =31*result+DemoArrayHashcode(demos);//对象数组域,递归调用它的hashCode方法 return result;
} private int intArrayHashcode(int[] intArray) {
int result = 17;
for (int i = 0; i < intArray.length; i++) {//基本类型数组域,对其中每个元素计算
result = 31 * result + intArray[i];
}
return result;
} private int DemoArrayHashcode(Demo[] demos) {
int result = 17;
for (int i = 0; i < demos.length; i++) {
result = 31 * result + demos[i].hashCode(); //对象数组域,递归调用它的hashCode方法;
}
return result;
}
当改写equals()的时候,总是要改写hashCode()
根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode方法,它们仅仅是两个对象。因此,违反了“相等的对象必须具有相等的散列码”。
ps:
31是个神奇的数字,因为任何数n * 31就可以被JVM优化为 (n << 5) -n,移位和减法的操作效率要比乘法的操作效率高的多,对左移现在很多虚拟机里面都有做相关优化,并且31只占用5bits!
java覆写hashcode方法的更多相关文章
- [改善Java代码]覆写equals方法必须覆写hashCode方法
覆写equals方法必须覆写hashCode方法,这条规则基本上每个Javaer都知道,这也是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢?本建议就来解释该问题,我们先 ...
- 覆写equals方法为什么需要覆写hashCode方法
覆写equals方法必须覆写hashCode方法,是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢? void test() { // Person类的实例作为Map的k ...
- java覆写equals方法
何时需要重写equals() 当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念). object规范规定,如果要重写equals(),也要重写hashcode() 如何覆写equals() ...
- 为什么覆写equals必须要覆写hashCode?
============================================= 原文链接: 为什么覆写equals必须要覆写hashCode? 转载请注明出处! ============= ...
- [改善Java代码]推荐覆写toString方法
建议49: 推荐覆写toString方法 为什么要覆写toString方法,这个问题很简单,因为Java提供的默认toString方法不友好,打印出来看不懂,不覆写不行,看这样一段代码: public ...
- 为什么覆写equals()方法的时候总是要覆写hashcode()?
要回答这个问题,我们应该先认识一下obj中的equals和hascode方法 1.equals()方法在obj中定义如下: public boolean equals(Object obj) { re ...
- [改善Java代码]不推荐覆写start方法
多线程比较简单的方式是继承Thread类,然后覆写run()方法,在客户端程序中通过调用对象的start方法即可启动一个线程,这个是多线程程序的标准写法. 错误代码: public class Cli ...
- [改善Java代码]覆写equals方法时不要识别不出自己
建议45: 覆写equals方法时不要识别不出自己 我们在写一个JavaBean时,经常会覆写equals方法,其目的是根据业务规则判断两个对象是否相等,比如我们写一个Person类,然后根据姓名判断 ...
- 千万不要误用 java 中的 HashCode 方法
刚才debug追堆栈的时候发现一个很奇怪的问题 我用IE8和Google的浏览器访问同一个地址 Action的 scope="session" 也设置了 而且两个浏览器提交的参数m ...
随机推荐
- php基础知识总结
PHP 代表 PHP: Hypertext Preprocessor PHP 文件可包含文本.HTML.JavaScript代码和 PHP 代码 PHP 代码在服务器上执行,结果以纯 HTML 形式返 ...
- 简单测试运行时类信息(RTTI),附详细例子
新建一个单元文件,填写如下代码,然后保存为 ClassInfoUnit.pas,这里定义了一个结构,用来读取指定类的信息. unit ClassInfoUnit; interface uses Cla ...
- 对开发中常见的内存泄露,GDI泄露进行检测
对开发中常见的内存泄露,GDI泄露进行检测 一.GDI泄露检测方法: 在软件测试阶段,可以通过procexp.exe 工具,或是通过任务管理器中选择GDI对象来查看软件GDI的对象是使用情况. 注意点 ...
- Java图形化界面设计——布局管理器之BorderLayout(边界布局)
- [置顶] .NET下枚举类型的Save和Load分析
今天在写代码的时候,心血来潮对原来的字符串保存状态位的方式很不满意,对于代码里出现了 state == "1" 这样的状态判断很是不爽.那么理想中的判断是怎样的呢?很简单如你所想枚 ...
- iOS开发宝典:String用法大全
一.NSString 创建字符串. NSString *astring = @"This is a String!"; 创建空字符串,给予赋值. NSString *astri ...
- 通过浏览器直接打开Android应用程序
需求 通过手机浏览器直接打开Android应用程序.假设本地已经安装了指定Android应用,就直接打开它:假设没有安装,则直接下载该应用的安装文件(也能够跳转到下载页面). 实现效果 假设手机上已经 ...
- iOS 发布应用时屏蔽NSLog
在开发过程中,经常需要使用NSLog来进行调试,但是NSLog是非常影响性能的,所以我们应该在发布应用时屏蔽掉NSLog,但是如果通过手工的去一行一行的改得话,未免太枯燥与费时了,庆幸的是,我们可以通 ...
- c#打包文件解压缩
首先要引用一下类库:using Ionic.Zip;这个类库可以到网上下载. 下面对类库使用的封装方法: /// <summary> /// 得到指定的输入流的ZIP ...
- DEV中gridview常用属性的设置
1.隐藏最上面的GroupPanel: gridView1.OptionsView.ShowGroupPanel=false; 2.得到当前选定记录某字段的值: sValue=Table.Rows[g ...