import java.util.*; public class OverrideObjectMethod { public static void main(String[] args) { Map<PhoneNumberBad, String> map = new HashMap<PhoneNumberBad, String>(); map.put(new PhoneNumberBad(110, 86, 1351), "chenzq"); //Object的hashCode实现返回对象的引用地址,所以equals相等的2个对象会返回不一样的hashCode String result = map.get(new PhoneNumberBad(110, 86, 1351)); System.out.println(result); //null Map<PhoneNumber, String> mp = new HashMap<PhoneNumber, String>(); mp.put(new PhoneNumber(110, 86, 1351), "chenzq"); result = mp.get(new PhoneNumber(110, 86, 1351)); System.out.println(result); //chenzq System.out.println(new PhoneNumber(110, 86, 1351)); PhoneNumber[] arr = new PhoneNumber[5]; arr[0] = new PhoneNumber(110, 86, 1351); arr[1] = new PhoneNumber(110, 87, 1351); arr[2] = new PhoneNumber(110, 87, 1350); arr[3] = new PhoneNumber(111, 86, 1352); arr[4] = new PhoneNumber(114, 80, 1354); Arrays.sort(arr); for(PhoneNumber pn : arr) { System.out.println(pn); } } } class PhoneNumber implements Comparable<PhoneNumber> { private final int areaCode; private final int prefix; private final int lineNumber; public PhoneNumber(int areaCode, int prefix, int lineNumber) { this.areaCode = areaCode; this.prefix = prefix; this.lineNumber = lineNumber; } @Override public int compareTo(PhoneNumber o) { // Compare area codes int areaCodeDiff = areaCode - o.areaCode; if (areaCodeDiff != 0) return areaCodeDiff; // Area codes are equal, compare prefixes int prefixDiff = prefix - o.prefix; if (prefixDiff != 0) return prefixDiff; // Area codes and prefixes are equal, compare line numbers return lineNumber - o.lineNumber; } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof PhoneNumber)) return false; PhoneNumber pn = (PhoneNumber) o; return pn.lineNumber == lineNumber && pn.prefix == prefix && pn.areaCode == areaCode; } @Override public int hashCode() { int result = 17; result = 31 * result + this.areaCode; result = 31 * result + this.prefix; result = 31 * result + this.lineNumber; return result; } @Override public String toString() { return String.format("(%03d) %03d-%04d", this.areaCode, this.prefix, this.lineNumber); } } class PhoneNumberBad { private final int areaCode; private final int prefix; private final int lineNumber; public PhoneNumberBad(int areaCode, int prefix, int lineNumber) { this.areaCode = areaCode; this.prefix = prefix; this.lineNumber = lineNumber; } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof PhoneNumberBad)) return false; PhoneNumberBad pn = (PhoneNumberBad) o; return pn.lineNumber == lineNumber && pn.prefix == prefix && pn.areaCode == areaCode; } }
输出为:
null
chenzq
(110) 086-1351
(110) 086-1351
(110) 087-1350
(110) 087-1351
(111) 086-1352
(114) 080-1354
* 对于所有对象都通用的方法:
尽管Object是一个具体类,但设计它主要是为了扩展。它所有的非final方法
(equals/hashCode/toString/clone/finalize)都有明确的通用约定。
因为它们被设计成是要被覆盖的。任何一个类在覆盖这些方法时,都有责任遵守这些通用约定。否则
其他依赖于这些约定的类(HashMap/HashSet),就无法结合该类一起正常工作。
* 什么时候应该override equals方法:如果类具有自己特有的“逻辑相等”概念(不同于对象等同),
而且超类还没有覆盖equals以实现期望的行为时,需要覆盖equals。
***************************************************************
* 覆盖equals时请遵守通用约定:
自反型:对于任何非null的引用值x,x.equals(x)必须返回true。
对称性:对于任何非null的引用值x和y,x.equals(y)返回true时,y.equals(x)也必须返回true。
传递性:对于任何非null的引用值x、y和z,x.equals(y)返回true并且y.equals(z)也返回true时,
x.equals(z)也必须返回true。
一致性:对于任何非null的引用值x和y,只要x和y对象所用的比较信息没有修改,多次调用
x.equals(y)的结果应该一致。
非空性:对于任何非null的引用值x,x.equals(null)必须返回false。
null instanceof 任何类型都会返回false,所以不需要判断比较对象是否为null。
* 使用instanceof检查参数是否为正确的类型,并把参数转换为正确的类型。
* 对于非float和double的基本类型使用==进行比较,对象引用field可以递归调用equals比较,
float类型使用Float.compare方法,double使用Double.compare。
* 有些对象field包含null值是合法的,为了避免NullPointerException,使用:
(field == null ? o.field == null : field.equals(o.field))
* 不要企图让equals过于智能。
* 不要将equals声明中的Object替换为其他类型(使用强类型参数,只是重载了equals方法,
并没有覆盖equals方法)。@Override注解可以避免这种错误。
****************************************************************
* 覆盖equals时总要覆盖hashCode:
在每个覆盖了equals的类中也必须覆盖hashCode,否则就会违反Object.hashCode的通用约定,
从而导致该类无法结合所有基于散列的集合正常工作(HashMap/Hashtable/HashSet)。
在应用程序运行期间,只要对象equals方法比较所用到的field信息没有被修改,那么对这一对象
多次调用hashCode必须始终返回同一个整数。
* 如果两个对象调用equals比较是相等的,那么两个对象的hashCode也必须返回相同的整数。
* 如果两个对象调用equals比较是不相等的,那么两个对象的hashCode不一定要返回不同的整数。
但是给不同的对象截然不同的hashCode整数结果有可能提高散列表的性能。
***************************************************************
* 始终要覆盖toString:
toString通用约定指出,被返回的字符串应该是一个“简洁的,但信息丰富,并且易于阅读的表达形式”。
建议所有的子类覆盖toString方法。在实际应用中,toString应该返回所有值得关注的信息。
***************************************************************
* 类实现了Comparable接口,就表明它的实例具有内在的排序关系(natural ordering)。
Arrays.sort(arr) 当该对象小于、等于、大于指定对象的时候,分别返回一个负整数、零、正整数。
* compareTo方法的通用约定:
必须确保所有的x和y都满足,x.compareTo(y) == - (y.compareTo(x))。
必须确保比较关系是可传递的,x.compareTo(y) > 0 && y.compareTo(z) > 0 则 x.compareTo(z) > 0
强烈建议: (x.compareTo(y) == 0) == (x.equals(y))
相关推荐
List对象排序通用方法List对象排序通用方法List对象排序通用方法List对象排序通用方法
了解并正确使用这些通用方法对于编写高质量的Java程序至关重要。 - **toString()**:返回对象的字符串表示形式,常用于调试或展示对象状态。 - **equals(Object obj)**:判断当前对象是否与传入的对象相等,这里的...
`List`对象排序通用方法就是为了解决这个问题,特别是在处理从数据库中检索出的数据列表时,避免频繁的数据库查询,转而在内存中对数据进行排序。这里我们将探讨如何对包含自定义对象的`List`进行通用排序,并减少...
LIST对象排序通用方法HIBERNATE的SET排序.pdf
分析LIST对象排序通用方法HIBERNATE的SET排序.pdf
本文主要介绍了Java执行SQL语句实现查询的通用方法详解,包括executeQuery()方法、JDBCTools工具类、PreparedStatement和ResultSet对象的使用。这些知识点可以帮助开发者更好地理解Java执行SQL语句实现查询的原理和...
LIST对象排序通用方法HIBERNATE的SET排序[整理].pdf
首先,通过`getMethod()`方法获取对象类上的指定方法,然后通过`invoke()`方法调用该方法获取属性值。最后,将两个对象的属性值转换为字符串并使用`compareTo()`进行比较,从而实现基于特定属性的排序。 在实际使用...
9. **图形用户界面**:对于桌面应用,通用对象支持库可能提供了创建窗口、按钮、文本框等GUI组件的功能。 10. **数据结构和算法**:为了高效地处理数据,库可能包含了各种数据结构(如链表、树、队列等)和算法...
### Java操作文件通用方法集合详解 在Java编程中,对文件进行操作是常见的需求,包括读取、写入、创建、删除以及获取文件属性等。本文将深入解析一个名为`FileUtils`的类,该类封装了一系列用于文件操作的通用方法...
本次解析的是一个关于正则表达式通用方法的代码片段,该方法旨在从给定的文本中提取符合指定正则表达式的分组信息,并将其存储为列表中的映射结构返回。 ### 正则表达式通用方法详解 #### 方法定义 ```java public...
在这个场景下,"使用HttpClient调试android接口-通用方法"的标题表明我们将讨论如何使用HttpClient来调试Android应用中的API接口。下面,我们将深入探讨HttpClient的基础知识、调试技巧以及如何封装通用方法。 1. *...
JAVA中excel导入导出通用方法 JAVA 中 excel 导入导出通用方法是指在 Java 项目中实现 excel 文件的导入和导出功能。这种方法可以应用于各种需要 excel 文件交互的业务场景中。 一、引入依赖 在 Java 项目中想要...
这通常涉及遍历对象的所有属性,并将它们的值转化为字符串或其他可存储的格式。这个过程允许我们将对象保存到文件或数据库,或者在网络上传输。 `Deserialize()` 方法则与之相反,它从存储的格式中恢复对象的状态。...
通用对象通常是指那些在多个场景下都能使用的模块或类库,它们能够提高代码复用性,降低开发复杂度。 在这个源码包中,我们可以期待找到一些易语言的典型通用对象实现,这些对象可能包括但不限于数据结构(如队列、...
在本项目中,"基于C++, QT,对象工厂设计一个通用计算器",我们将探讨如何使用C++编程语言、Qt框架以及对象工厂模式来构建一个功能丰富的计算器应用。这个2021年的期末课设旨在让学生掌握面向对象编程、UI设计以及...
UML通过一套图形符号来表达类、对象、关系以及它们之间的交互,为软件开发团队提供了一种通用的建模语言。 《面向对象方法学 UML》一书,由张少锋编著,是清华大学出版社出版的专业教材,适用于理解和学习面向对象...
描述中的“通用对象类型转换”可能就是一种面向对象的设计,将不同的类型转换功能封装到一个类的不同方法中。 5. **性能优化**: 除了代码执行时间的测量,这个通用类可能还包含了其他性能优化的策略,如缓存、...