`
jaesonchen
  • 浏览: 313183 次
  • 来自: ...
社区版块
存档分类
最新评论

对于所有对象都通用的方法

 
阅读更多
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对象排序通用方法List对象排序通用方法

    注意对象的通用方法,类的设计陷阱.pdf

    了解并正确使用这些通用方法对于编写高质量的Java程序至关重要。 - **toString()**:返回对象的字符串表示形式,常用于调试或展示对象状态。 - **equals(Object obj)**:判断当前对象是否与传入的对象相等,这里的...

    List对象排序通用方法[参考].pdf

    `List`对象排序通用方法就是为了解决这个问题,特别是在处理从数据库中检索出的数据列表时,避免频繁的数据库查询,转而在内存中对数据进行排序。这里我们将探讨如何对包含自定义对象的`List`进行通用排序,并减少...

    LIST对象排序通用方法HIBERNATE的SET排序.pdf

    LIST对象排序通用方法HIBERNATE的SET排序.pdf

    分析LIST对象排序通用方法HIBERNATE的SET排序.pdf

    分析LIST对象排序通用方法HIBERNATE的SET排序.pdf

    java执行SQL语句实现查询的通用方法详解

    本文主要介绍了Java执行SQL语句实现查询的通用方法详解,包括executeQuery()方法、JDBCTools工具类、PreparedStatement和ResultSet对象的使用。这些知识点可以帮助开发者更好地理解Java执行SQL语句实现查询的原理和...

    LIST对象排序通用方法HIBERNATE的SET排序[整理].pdf

    LIST对象排序通用方法HIBERNATE的SET排序[整理].pdf

    java中List对象排序通用方法

    首先,通过`getMethod()`方法获取对象类上的指定方法,然后通过`invoke()`方法调用该方法获取属性值。最后,将两个对象的属性值转换为字符串并使用`compareTo()`进行比较,从而实现基于特定属性的排序。 在实际使用...

    通用对象支持库

    9. **图形用户界面**:对于桌面应用,通用对象支持库可能提供了创建窗口、按钮、文本框等GUI组件的功能。 10. **数据结构和算法**:为了高效地处理数据,库可能包含了各种数据结构(如链表、树、队列等)和算法...

    java 操作文件通用方法集合

    ### Java操作文件通用方法集合详解 在Java编程中,对文件进行操作是常见的需求,包括读取、写入、创建、删除以及获取文件属性等。本文将深入解析一个名为`FileUtils`的类,该类封装了一系列用于文件操作的通用方法...

    正则表达式通用方法

    本次解析的是一个关于正则表达式通用方法的代码片段,该方法旨在从给定的文本中提取符合指定正则表达式的分组信息,并将其存储为列表中的映射结构返回。 ### 正则表达式通用方法详解 #### 方法定义 ```java public...

    使用HttpClient调试android接口-通用方法

    在这个场景下,"使用HttpClient调试android接口-通用方法"的标题表明我们将讨论如何使用HttpClient来调试Android应用中的API接口。下面,我们将深入探讨HttpClient的基础知识、调试技巧以及如何封装通用方法。 1. *...

    JAVA中excel导入导出通用方法

    JAVA中excel导入导出通用方法 JAVA 中 excel 导入导出通用方法是指在 Java 项目中实现 excel 文件的导入和导出功能。这种方法可以应用于各种需要 excel 文件交互的业务场景中。 一、引入依赖 在 Java 项目中想要...

    通用序列化对象

    这通常涉及遍历对象的所有属性,并将它们的值转化为字符串或其他可存储的格式。这个过程允许我们将对象保存到文件或数据库,或者在网络上传输。 `Deserialize()` 方法则与之相反,它从存储的格式中恢复对象的状态。...

    易语言学习进阶通用对象

    通用对象通常是指那些在多个场景下都能使用的模块或类库,它们能够提高代码复用性,降低开发复杂度。 在这个源码包中,我们可以期待找到一些易语言的典型通用对象实现,这些对象可能包括但不限于数据结构(如队列、...

    基于C++,QT,对象工厂设计一个通用计算器

    在本项目中,"基于C++, QT,对象工厂设计一个通用计算器",我们将探讨如何使用C++编程语言、Qt框架以及对象工厂模式来构建一个功能丰富的计算器应用。这个2021年的期末课设旨在让学生掌握面向对象编程、UI设计以及...

    面向对象方法学 UML

    UML通过一套图形符号来表达类、对象、关系以及它们之间的交互,为软件开发团队提供了一种通用的建模语言。 《面向对象方法学 UML》一书,由张少锋编著,是清华大学出版社出版的专业教材,适用于理解和学习面向对象...

    通用类,包含通用对象类型转换、代码执行时间测量等

    描述中的“通用对象类型转换”可能就是一种面向对象的设计,将不同的类型转换功能封装到一个类的不同方法中。 5. **性能优化**: 除了代码执行时间的测量,这个通用类可能还包含了其他性能优化的策略,如缓存、...

Global site tag (gtag.js) - Google Analytics