- 浏览: 369232 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
tuspark:
关于javadoc这里讲解的更全面:《javadoc设置》。
Eclipse中生成javadoc【Z】 -
yuexiang1007:
帮我解决了问题,谢谢!!!
java.math.BigInteger使用心得总结 -
netwelfare:
个人感觉,文章对HashMap的遍历分析的有点浅,不如这里的介 ...
HashMap遍历的两种方式【Z】 -
memoryisking:
关于java.math.BigInteger讲解在这里可以看到 ...
java.math.BigInteger使用心得总结 -
巴尾的兔兔帅:
divide应该是除吧?不是减。dividepublic Bi ...
java.math.BigInteger使用心得总结
问题一:我们自定义类中的toString()、hashCode()和 equals(Object obj)均继承自Object,其中equals()方法是比较两对象的地址是否相同,hashCode()方法返回的是该对象本身的内存地址。但这个需 求不能满足我们的需求。如问题二。(JDK中其它类都已重写了上述方法,不作考虑)
问题二:在我们往HashSet中添加自定义对象的时候(HashSet中不能添加相同的对象),HashSet会先将已存在的对象与欲添加的对象进行一 一对比,相同的对象不允许再添加。其比较规则为:如果两对象的hashCode()方法返回值不一样,肯定不是相同的对象,可添加;如果 hashCode()一样,则再判断equals()返回是否为真,不为真则肯定不是相同的对象,可添加,为真由证明两对象完全相同,不再添加到 HashSet中。那按Object()中的hashCode()方法,则只要内存不一样,则两对象的hashCode就不一样,则认为两对象不相同,可 往HashSet中添加,这违背了我们实际需求。
结论:我们自定义类如果想往HashSet等集合中添加时,必须重写equals(Object obj)和hashCode()方法,使相同内容的对象其equals(Object obj)为真,返回的hashCode()一致。如下:
重写equals()方法
下面给出编写一个完美的equals方法的建议:
1) 显式参数命名为otherObject,稍后需要将它转换成另一个叫
做 other的变量。
2) 检测this与otherObject是否引用同一个对象:
if (this == otherObject) return true;
这条语句只是一个优化。实际上,这是一种经常采用的形
式。因为计算这个等式要比一个一个地比较类中的域所付
出的代价小得多。
3) 检测otherObject是否为null,如果为null,返回false。这项
检测是很必要的。
if (otherObject == null) return false;
比较this与otherObject是否属于同一个类。如果equals的语
义在每个子类中有所改变,就使用getClass检测:
if (getClass() != otherObject.getClass()) return false;
如果所有的子类都拥有统一的语义,就使用instanceof检测:
if (! (otherObject instanceof ClassName)) retrun false;
4)将otherObject转换为相应的类类型变量:
ClassName other = (ClassName)otherObject;
5) 现在开始对所有需要比较的域进行比较了。使用 == 比较
基本类型域,使用equals比较对象域。如果所有的域都匹
配,就返回ture;否则返回false。
return field1 == other.field1
&& field2.equals(other.field2)
&& ……;
代码:
public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Tree other = (Tree) obj;//Tree类 if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; }
********************************************************************************************************************
关于如何重写hashCode的方法
为什么要重写hashCode方法?
我们应该先了解java判断两个对象是否相等的规则。
在java的集合中,判断两个对象是否相等的规则是:
首先,判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等
如果相等,则判断两个对象用equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率
如何重写hashCode方法呢?
你可以写
public int hashCode(){ return 42; }
这是一种符合规则的写法,保证了两个equal 的object 拥有相同的hashCode
但这种方法显然是不可取的
比较通用的做法是
返回一个result
- public int hashCode() {
- int result = 17 ; //任意素数
- result = 31 *result +c1; //c1,c2是什么看下文解释
- result = 31 *result +c2;
- return result;
- }
public int hashCode() { int result = 17; //任意素数 result = 31*result +c1; //c1,c2是什么看下文解释 result = 31*result +c2; return result; }
其中c1,c2是我们生成的你要计算在内的字段的代码,生成规则如下:
如果字段是boolean 计算为(f?1:0);
如果字段是byte,char,short,int则计算为 (int)f;
如果字段是long 计算为 (int)(f^(f>>32));
如果字段是float 计算为 Float.floatToLongBits(f);
如果字段是一个引用对象,那么直接调用对象的hashCode方法,如果需要判空,可以加上如果为空就返回0;
如果字段是一个数组则需要遍历所有元素,按上面几种方法计算;
当你写完后hashCode方法后问问自己
1、是否两个equal的实例,拥有相同的jhashCode
2、两个不同的实例,是否拥有相同的hashCode
写一个JUnit Test 测试一下
****************************************************************************************************************
01
一个重写equals ()和hashCode()方法的例子
下面是一个根据业务键实现equals ()与hashCode()的例子。实际中需要根据实际的需求,决定如何利用相关的业务键来组合以重写这两个方法。
- public class Cat
- {
- private String name;
- private String birthday;
- public Cat()
- {
- }
- public void setName(String name)
- {
- this .name = name;
- }
- public String getName()
- {
- return name;
- }
- public void setBirthday(String birthday)
- {
- this .birthday = birthday;
- }
- public String getBirthday()
- {
- return birthday;
- }
- //重写 equals 方法
- public boolean equals (Object other)
- {
- if ( this == other)
- {
- //如果引用地址相同,即引用的是同一个对象,就返回true
- return true ;
- }
- //如果other不是Cat类的实例,返回false
- if (!(other instanceOf Cat))
- {
- return false ;
- }
- final Cat cat = (Cat)other;
- //name值不同,返回false
- if (!getName().equals (cat.getName())
- return false ;
- //birthday值不同,返回false
- if (!getBirthday().equals (cat.getBirthday()))
- return false ;
- return true ;
- }
- //重写hashCode()方法
- public int hashCode()
- {
- int result = getName().hashCode();
- result = 29 * result + getBirthday().hashCode();
- return result;
- }
- }
public class Cat { private String name; private String birthday; public Cat() { } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getBirthday() { return birthday; } //重写equals 方法 public boolean equals (Object other) { if(this == other) { //如果引用地址相同,即引用的是同一个对象,就返回true return true; } //如果other不是Cat类的实例,返回false if(!(other instanceOf Cat)) { return false; } final Cat cat = (Cat)other; //name值不同,返回false if(!getName().equals (cat.getName()) return false; //birthday值不同,返回false if(!getBirthday().equals (cat.getBirthday())) return false; return true; } //重写hashCode()方法 public int hashCode() { int result = getName().hashCode(); result = 29 * result + getBirthday().hashCode(); return result; } }
重写父类方法的原则:可以重写方法的实现内容,成员的存取权限(只能扩大,不能缩小),或是成员的返回值类型(但此时子类的返回值类型必须是父类返回值类型的子类型)。
发表评论
-
JSTL中的<c:标签【Z】
2011-08-31 20:48 1146Taglib 伪指令 Java代码 ... -
java接口嵌套【Z】
2011-05-18 17:09 1342在Java语言中,接口可以嵌套在类或其它接口中。由于Jav ... -
JMF安装【Z】
2011-05-07 20:52 1094下载并安装JMF 在MyEclipse中选择 窗口/首选项/ ... -
javaMail【Z】
2011-04-18 16:12 1078commons-email-1.1.jar: 这是Apache ... -
java生成PDF文件【Z】
2011-01-14 15:03 1211如果应用程序需要动态 ... -
字符集编码【Z】
2010-12-29 18:54 893问题研究 --字符集 ... -
java常用第三方jar包【Z】
2010-12-26 22:39 3360commons-digester.jar Digeste ... -
不使用JNI获得系统信息【Z】
2010-12-22 13:28 589在Java中,可以获得总的物理内存、剩余的物理内存、已使用的物 ... -
java获得当前路径【Z】
2010-12-18 14:37 9421、利用System.getProperty()函数获取当前路 ... -
java容器类-1【Z】
2010-12-17 21:43 1013对象的集合 如果程序的对象数量有限 ... -
java UIManager的风格【Z】
2010-12-17 12:28 2671Java'中的几种Look and Feel 1、Met ... -
serialVersionUID的作用和意义【Z】
2010-12-15 10:38 1553在Java中,软件的兼容性是一个大问题,尤其在使用到对象串行性 ... -
HashMap遍历的两种方式【Z】
2010-12-07 18:42 968HashMap遍历的两种方式 ... -
23个经典JDK设计模式——系统JDK使用设计模式的例子【Z】
2010-12-05 21:33 1029酷壳 版主陈皓近日发表博文《JDK里的设计模式 》,文中他 ... -
String/StringBuffer/StringBuild【Z】
2010-11-12 14:10 1346[编辑] String,StringBuffer和String ... -
tomcat中web.xml详解【Z】
2010-10-18 14:47 9251 定义头和根元素 部 ... -
Java 理论与实践: 线程池与工作队列【Z】
2010-10-18 09:45 932线程池有助于实现最 ... -
单例模式完全剖析【Z】
2010-10-17 22:48 790Buildfile: build.xml ... -
在MyEclipse中直接查看class文件(在没有源码的情况下)【Z】
2010-10-17 22:04 1309想直接在myeclipse中查看class文件,就像查看普通的 ... -
HashMap实现及冲突【Z】
2010-10-12 21:41 962了解 HashMap 原理对于日后的缓存机制多少有 ...
相关推荐
在Java编程语言中,`equals()`, `hashCode()` 和 `toString()` 是三个非常重要的方法,它们主要用于对象的比较、哈希存储以及打印对象信息。这三个方法是Java对象的基础特性,对于理解和开发高质量的Java程序至关...
在 Java 中,重写 equals() 方法和 hashCode() 方法是非常重要的,它们可以确保对象的比较和标识正确。如果我们违反了这两个方法的规则,那么可能会产生理解的不一致。因此,在编写 Java 代码时,需要严格遵守这两个...
在 Java 编程语言中,Object 类是所有类的父类,但是在实际开发中,我们往往需要重写 Object 中的 equals 和 hashCode 方法,以便正确地比较对象的逻辑内容,而不是内存地址。下面我们将详细地解释为什么需要重写这...
通过该案例代码,你可以学习如何在自己的类中正确重写equals()、hashCode()、toString()等方法,提高代码质量和可读性。 经验丰富的Java开发者:即使你已经有一定的Java开发经验,仍然值得深入了解Object类的使用。...
### Java 高级特性详解 #### 一、`hashCode` ...正确地重写 `equals` 和 `hashCode` 方法、使用 `Comparator` 进行排序、利用反射机制和序列化技术,以及实现 `clone` 方法都是开发高质量 Java 应用程序的重要技能。
ATM系统 Clone方法 toString方法:表示返回对象的字符串表示形式 包名.类名@hashCode(内存地址) 打印对象时,默认调用 如果不是想使用object类,toString...如果equal返回true的话,hashCode相同,重写hashCode方法
在Java中,`Object`类是所有类的父类,它提供了几个核心的方法,包括`equals()`, `hashCode()`, 和 `toString()`。 `equals()`方法用于比较两个对象是否相等。默认实现比较的是对象的引用,即两个对象是否指向内存...
在这个例子中,`Demo1`类重写了`equals`方法和`hashCode`方法。通过`equals`方法确保只有`value`相等时才认为两个对象相等;而`hashCode`方法则返回`id`的值。这样设计可以确保即使`id`不同但`value`相同的对象被视...
谁在关心toString的性能?没有人!除非当你有大量的数据在批量处理,使用...我们所钟爱的IDE们常常为我们生成equals/hashcode/toString这些方法,且我们通常不再去管它们。此外,这些IDE们提供了许多方式来生成我们自己
- 重写hashCode()时,如果两个对象根据equals()方法相等,它们的hashCode()方法必须返回相同的值。同时,不相等的对象返回不同的哈希码能提高哈希表的性能。 3. **toString() 方法**: - 默认的toString()方法...
本文将深入探讨`Object`类,以及其核心方法`equals()`与Java中的`==`操作符之间的差异。 `Object`类位于Java的核心库`java.lang`包中,它提供了基本的方法来支持对象的创建、比较和字符串表示。以下是`Object`类的...
在实际编程中,我们经常需要重写Object类中的方法,例如equals和hashCode方法。这是因为这些方法的默认实现不适合我们的需求,我们需要根据自己的需求来重写这些方法。 例如,在上面的代码中,我们重写了equals和...
因此,当重写`equals`方法时,通常也需要重写`hashCode`方法,确保两个`equals`结果为真的对象具有相同的哈希码。 #### 六、`toString`方法详解 - `toString`方法返回对象的字符串表示形式,默认情况下,`Object`...
Object 类是 Java 中所有类的父类,它提供了几个重要的方法,例如 equals()、hashCode() 和 toString() 等。这些方法可以被子类重写,以满足子类的需求。 五、继承的注意事项 继承时需要注意以下几点: * 构造...
在这个阶段,主要讲解的是Java中对象的常用API,特别是关于`equals()`方法和`toString()`方法的使用,以及API的基本概念和`Object`类的概述。以下是这些知识点的详细解释: 1. **API概念**:API,全称为Application...
Object类中默认的equals()方法实现在Java中等同于“==”,它比较的是对象的引用地址是否相同。但许多类重写了equals()方法来比较对象的实际内容。 3. toString()方法在Object类中返回的是对象的类名加上“@”符号,...
在Java中,所有的类都隐式或显式地继承自`Object`类,它提供了一些基本的方法,如`equals()`、`hashCode()`、`toString()`和`clone()`等。这些方法在处理对象比较、字符串化和复制等方面非常有用。 深入理解这些...
在Java编程语言中,面向对象是其核心特性之一。Object类是所有Java类的根父类,无论何时我们创建一个新的类,除非明确指定其他...在实际项目中,合理地重写`equals()`和`toString()`方法对于调试和日志记录尤其有用。