在標準Java庫中包含150多個equals方法的實現,這裡給出一個比較完美的實現方法。
1)顯示參數命名為otherObject,稍後需要將它轉換成另一個叫做other的變數。
2)檢測this與otherObject是否引用同一個對象:
if(this == otherObject) return true;
這條語句只是一個最佳化。實際上這是一種經常使用的形式。
3)檢測otherObject是否為null,如果為null,返回false。這項檢測很必要。
if(otherObejct == null) return false;
比較this與otherObject是否為屬於同一個類。如果equals的語義在每個子類中有所改變,就使用getClass檢測:
if(getClass() != otherObject.getClass()) return false;
如果所有的子類都擁有統一的語義,就使用instanceof檢測:
if(!(otherObejct instanceof ClassName)) return false;
4)將otherObject轉換為相應的類類型變數:
ClassName other = (ClassName)otherObject;
5)現在開始對所有需要比較的域進行比較了。使用==比較基本類型域,使用equals比較對象域。如果所有的域都匹配,就返回true,否則返回false。
return field == other.field&&field.equals(other.field)&&...;
如果在子類中重新定義equals,就要在其中包含調用super.equals(other)。
import java.util.*;public class EqualsTest{public static void main(String[] args){Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);Employee alice2 = alice1;Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);Employee bob = new Employee("Bob Brandson", 50000, 1989, 10, 1);System.out.println("alice1 == alice2: " + (alice1 == alice2));System.out.println("alice1 == alice3: " + (alice1 == alice3));System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));System.out.println("alice1.equals(bob): " + alice1.equals(bob));System.out.println("bob.toString(): " + bob);Manager carl = new Manager("Carl Cracker", 80000, 1987, 12, 15);Manager boss = new Manager("Carl Cracker", 80000, 1987, 12, 15);boss.setBonus(5000);System.out.println("boss.toString(): "+ boss);System.out.println("carl.equals(boss): " + carl.equals(boss));System.out.println("alice1.hashCode(): " + alice1.hashCode());System.out.println("alice3.hashCode(): " + alice3.hashCode());System.out.println("bob.hashCode(): " + bob.hashCode());System.out.println("carl.hashCode(): " + carl.hashCode());}}class Employee{public Employee(String n, double s, int year, int month, int day){name = n;salary = s;GregorianCalendar calendar = new GregorianCalendar(year, month-1, day);hireDay = calendar.getTime();}public String getName(){return name;}public double getSalary(){return salary;}public Date getHireDay(){return hireDay;}public void raiseSalary(double byPercent){double raise = salary*byPercent/100;salary += raise;}public boolean equals(Object otherObject){//a quick test to see if the objects are identicalif(this == otherObject)return true;//must return false if the explicit parameter is nullif(otherObject == null)return false;//if the classes don't match, they can't be equalif(getClass() != otherObject.getClass())return false;//now we know otherObject is a non-null EmployeeEmployee other = (Employee)otherObject;//test whether the fields have identical valuesreturn name.equals(other.name)&& salary == other.salary&& hireDay.equals(other.hireDay);}public int hashCode(){return 7*name.hashCode() + 11*new Double(salary).hashCode()+ 13*hireDay.hashCode();}public String toString(){return getClass().getName() + "[name=" + name+ ",salary=" + salary + ",hireDay=" + hireDay+ "]";}private String name;private double salary;private Date hireDay;}class Manager extends Employee{public Manager(String n, double s, int year, int month, int day){super(n, s, year, month, day);bonus = 0;}public double getSalary(){double baseSalary = super.getSalary();return baseSalary + bonus;}public void setBonus(double b){bonus = b;}public boolean equals(Object otherObject){if(!super.equals(otherObject))return false;Manager other = (Manager)otherObject;//super.equals checked that this and other belong to the same classreturn bonus == other.bonus;}public int hashCode(){return super.hashCode() + 17*new Double(bonus).hashCode();}public String toString(){return super.toString() + "[bonus=" + bonus + "]";}private double bonus;}
運行結果:
--------------------Configuration: <Default>--------------------alice1 == alice2: truealice1 == alice3: falsealice1.equals(alice3): truealice1.equals(bob): falsebob.toString(): Employee[name=Bob Brandson,salary=50000.0,hireDay=Sun Oct 01 00:00:00 CST 1989]boss.toString(): Manager[name=Carl Cracker,salary=80000.0,hireDay=Tue Dec 15 00:00:00 CST 1987][bonus=5000.0]carl.equals(boss): falsealice1.hashCode(): 377780067alice3.hashCode(): 377780067bob.hashCode(): 955285015carl.hashCode(): 386513600Process completed.