覆盖equals【引自http://www.javapractices.com/Topic17.cjp】
来源:互联网 发布:安卓 intent获取数据 编辑:程序博客网 时间:2024/06/05 10:04
All objects have both identity (the object's location in memory) and state (the object's data). The == operator always compares identity. The default implementation of equals compares identity as well.
Sometimes the default implementation of equals has the desired behaviour (as in a type-safe enumeration, for example), but equals should usually compare state, not identity. This is particularly true for "data-centric" classes which map to database records.
hashCode and equals are closely related :
- if you override equals, you must override hashCode
- hashCode must generate equal values for equal objects
If you extend a concrete class, and add a new field which contributes to equals, then it is not possible to write a perfectly correct equals method for the new class. Instead, you should use composition instead of inheritance.
Example
Here is an implementation of equals for a data-centric class. It demonstrates how different types of fields are treated:
- object fields, including collections : use equals
- type-safe enumerations : use either equals or == (they amount to the same thing, in this case)
- possibly-null object fields : use both == and equals
- array fields : use Arrays.equals
- primitive fields other than float or double : use ==
- float : convert to int using Float.floatToIntBits, then use ==
- double : convert to long using Double.doubleToLongBits, then use ==
The above policies can be collected in a utility class :
import java.util.Arrays;/*** Collected methods which allow easy implementation of <code>equals</code>.** Example use case in a class called Car:* <pre>public boolean equals(Object that){ if ( this == that ) return true; if ( !(that instanceof Car) ) return false; Car thatCar = (Car)that; return EqualsUtil.areEqual(this.fName, that.fName) && EqualsUtil.areEqual(this.fNumDoors, that.fNumDoors) && EqualsUtil.areEqual(this.fGasMileage, that.fGasMileage) && EqualsUtil.areEqual(this.fColor, that.fColor) && Arrays.equals(this.fMaintenanceChecks, that.fMaintenanceChecks); //array!}* </pre>** <em>Arrays are not handled by this class</em>.* This is because the <code>Arrays.equals</code> methods should be used for* array fields.*/public final class EqualsUtil { static public boolean areEqual(boolean aThis, boolean aThat){ //System.out.println("boolean"); return aThis == aThat; } static public boolean areEqual(char aThis, char aThat){ //System.out.println("char"); return aThis == aThat; } static public boolean areEqual(long aThis, long aThat){ /* * Implementation Note * Note that byte, short, and int are handled by this method, through * implicit conversion. */ //System.out.println("long"); return aThis == aThat; } static public boolean areEqual(float aThis, float aThat){ //System.out.println("float"); return Float.floatToIntBits(aThis) == Float.floatToIntBits(aThat); } static public boolean areEqual(double aThis, double aThat){ //System.out.println("double"); return Double.doubleToLongBits(aThis) == Double.doubleToLongBits(aThat); } /** * Possibly-null object field. * * Includes type-safe enumerations and collections, but does not include * arrays. See class comment. */ static public boolean areEqual(Object aThis, Object aThat){ //System.out.println("Object"); return aThis == null ? aThat == null : aThis.equals(aThat); }}
Car is a class which uses EqualsUtil to implement its equals method :
import java.util.*;public final class Car { public Car ( String aName, int aNumDoors, List<String> aOptions, double aGasMileage, String aColor, Date[] aMaintenanceChecks ){ fName = aName; fNumDoors = aNumDoors; fOptions = new ArrayList<String>(aOptions); fGasMileage = aGasMileage; fColor = aColor; fMaintenanceChecks = new Date[aMaintenanceChecks.length]; for (int idx=0; idx < aMaintenanceChecks.length; ++idx) { fMaintenanceChecks[idx] = new Date( aMaintenanceChecks[idx].getTime() ); } } public boolean equals(Object aThat) { //check for self-comparison if ( this == aThat ) return true; //use instanceof instead of getClass here for two reasons //1. if need be, it can match any supertype, and not just one class; //2. it renders an explict check for "that == null" redundant, since //it does the check for null already - "null instanceof [type]" always //returns false. (See Effective Java by Joshua Bloch.) if ( !(aThat instanceof Car) ) return false; //Alternative to the above line : //if ( aThat == null || aThat.getClass() != this.getClass() ) return false; //cast to native object is now safe Car that = (Car)aThat; //now a proper field-by-field evaluation can be made return EqualsUtil.areEqual(this.fName, that.fName) && EqualsUtil.areEqual(this.fNumDoors, that.fNumDoors) && EqualsUtil.areEqual(this.fOptions, that.fOptions) && EqualsUtil.areEqual(this.fGasMileage, that.fGasMileage) && EqualsUtil.areEqual(this.fColor, that.fColor) && Arrays.equals(this.fMaintenanceChecks, that.fMaintenanceChecks); } //..other methods elided // PRIVATE //// /** * The following fields are chosen to exercise most of the different * cases. */ private String fName; private int fNumDoors; private List<String> fOptions; private double fGasMileage; private String fColor; //treat as possibly-null private Date[] fMaintenanceChecks; /** * Exercise the equals method. */ public static void main (String[] aArguments) { List<String> options = new ArrayList<String>(); options.add("sunroof"); Date[] dates = new Date[1]; dates[0] = new Date(); //Create a bunch of Cars; only one and two should be equal Car one = new Car("Nissan", 2, options, 46.3, "Green", dates); //two is equal to one Car two = new Car("Nissan", 2, options, 46.3, "Green", dates); //three has a differs in fName only Car three = new Car("Pontiac", 2, options, 46.3, "Green", dates); //four differs in fNumDoors only Car four = new Car("Nissan", 4, options, 46.3, "Green", dates); //five differs in fOptions only List<String> optionsTwo = new ArrayList<String>(); optionsTwo.add("air conditioning"); Car five = new Car("Nissan", 2, optionsTwo, 46.3, "Green", dates); //six differs in fGasMileage only Car six = new Car("Nissan", 2, options, 22.1, "Green", dates); //seven differs in fColor only Car seven = new Car("Nissan", 2, options, 46.3, "Fuchsia", dates); //eight differs in fMaintenanceChecks only Date[] datesTwo = new Date[1]; datesTwo[0] = new Date(1000000); Car eight = new Car("Nissan", 2, options, 46.3, "Green", datesTwo); System.out.println( "one = one: " + one.equals(one) ); System.out.println( "one = two: " + one.equals(two) ); System.out.println( "two = one: " + two.equals(one) ); System.out.println( "one = three: " + one.equals(three) ); System.out.println( "one = four: " + one.equals(four) ); System.out.println( "one = five: " + one.equals(five) ); System.out.println( "one = six: " + one.equals(six) ); System.out.println( "one = seven: " + one.equals(seven) ); System.out.println( "one = eight: " + one.equals(eight) ); System.out.println( "one = null: " + one.equals(null) ); }}
An example run of this class demonstrates that only objects one and two are equal :
one = one: true
one = two: true
two = one: true
one = three: false
one = four: false
one = five: false
one = six: false
one = seven: false
one = eight: false
one = null: false
- 覆盖equals【引自http://www.javapractices.com/Topic17.cjp】
- 用PHP模拟登陆(引自http://www.tianjiaonet.com)
- C#中的多線程-----引自:http://www.daima.com.cn/info/234.htm
- C#的多线程机制初探 (引自 http://www.daima.com.cn/info/234.htm ,在此感谢原作者)
- 什么是SoC(源引自 http://www.elenchina.com/bbs.do?method=view&id=1440&code=plate02)
- 在C#中使用MSHTML的高级支持接口(引自http://www.vckbase.com/document/viewdoc.asp?id=1018)
- http://www.martinfowler.com/
- http://www.free8.com/
- http://www.serverwatch.com/
- http://www.javadict.com/
- http://www.vckbase.com/
- http://www.mycconline.com
- http://www.howstuffworks.com/
- http://www.perforce.com/
- http://www.xmugd.com
- http://www.programsalon.com
- http://www.caixiong.com/
- http://www.koders.com/
- 愛情與婚姻
- OpenSolaris just released!
- 检查有日文片假名的新闻
- VB异步处理应用实例:磁盘文件全文搜索
- 手机铃声格式汇总!
- 覆盖equals【引自http://www.javapractices.com/Topic17.cjp】
- sql server中批量更改对象的所有者
- 三年
- Bob关于content management的理解!(转载)
- Dev-Cpp/Mingw32 环境介绍(10)
- Cutting Edge:为ASP.NET控件加入快捷菜单(4)(完)
- 学习"图解路由器接口及连接"笔记
- PHOTOSHOP中的模糊滤镜 【转】
- 有效防范IP地址泄漏 【转】