在java中,equals()方法用於偵測一個物件是否等於另一個對象,語法「Object.equals(Object2)」;該方法判斷兩個物件是否具有相同的引用,如果兩個物件具有相同的引用,它們一定是相等的。 equals()方法不能作用於基本資料型別的變數。
本教學操作環境:windows7系統、java8版、DELL G3電腦。
java equals()方法判斷物件是否相等
#equals方法用來偵測一個物件是否等於另一個物件。注意:equals方法不能作用於基本資料型別的變數
在Object類別中,這個方法判斷兩個物件是否有相同的引用,如果兩個物件有相同的引用,它們一定是相等的。
從這一點上看,將其作為預設操作也是合乎情理的。然而,對於多數類來說,這種判斷並沒有什麼意義,例如,採用這種方式比較兩個PrintStream是否相等就完全沒有意義。然而,經常需要偵測兩個物件狀態的相等性,如果兩個物件的狀態相等,就認為這兩個物件是相等的。所以一般在自訂類別都要重寫equals比較。
下面給出寫一個完美equals()方法的建議:
(1)明確參數命名為otherObject,稍後需要將轉換成一個叫other的變數
(2)偵測this與otherObject是否引用同一個物件:
if(this==otherObject) return true;
這句話只是一個最佳化。實際上,這是一種經常採用的形式。因為計算這個等式要比一個一個比較類中的域所付出的代價小的多。
(3)偵測otherObject是否為null,如果為null,回傳false。這項檢測是很有必要的。
if(otherObject==null) return false;
(4)比較this和otherObject是否屬於同一個類,如果equals的語義在每個子類中有所改變,就使用getClass()檢測,它將自己作為目標類
if(getClass()!=otherObject.getClass()) return false;
如果所有的子類別都擁有相同的語義,就使用instanceof檢測
if(!(otherObject instanceof ClassName)) return false;
(5)將otherObject轉換為對應類型的變數:
ClassName other=(ClassName)otherObject;
(6)現在開始對所有需要比較的領域進行比較。使用==比較基本型域,使用equals比較物件域。如果所有網域都匹配,就回傳true,否則回傳false;
return field1==other.field1&&field2.equals(other.field2)
如果在子類別中重新定義equals,就要在其中包含呼叫super.equals(other)。如果偵測失敗,就不可能相等。如果超類別中的域相等,就比較子類別中的實例域。
對於陣列類型的網域,可以使用靜態的Arrays.equals方法來偵測對應的元素是否相等。
來看幾個字串比較例子:
String a = "abc"; String b = "abc"; String c = new String("abc"); String d = new String("abc"); System.out.println(a == b); // true 因为JAVA中字符串常量是共享的,只有一个拷贝 System.out.println(a == c); // false a和c属于2个不同的对象 System.out.println(a.equals(c)); // true 由于String对象的equals方法比较的是对象中的值,所以返回true。(和Object的equals方法不同) System.out.println(c==d); // false c和d虽然对象内的值相同,但属于2个不同的对象,所以不相等 System.out.println(c.equals(d)); // true
簡單的說,當比較字串常數時,等於和equals回傳的結果一樣,當想比較字串物件的值時用equals。
看一個equals的使用範例:
package chapter05.EqualsTest; 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; // reference the same object 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()); } } class Employee { public Employee(String n, double s, int year, int month, int day) { name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month, 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; } @Override public boolean equals(Object otherObject) { // a quick test to see if the objects are identical if (this == otherObject) return true; // must return false if the explicit parameter is null if (otherObject == null) return false; // if the classed don't match,they can't be equal if (getClass() != otherObject.getClass()) return false; // now we know otherObject is a non-null Employee Employee other = (Employee) otherObject; // test whether the fields hava identical values return name.equals(other.name) && salary == other.salary && hireDay.equals(other.hireDay); } @Override public int hashCode() { return 7 * name.hashCode() + 11 * new Double(salary).hashCode() + 13 * hireDay.hashCode(); } @Override 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); bouns = 0; } @Override public double getSalary() { double baseSalary = super.getSalary(); return baseSalary + bouns; } public void setBouns(double b) { bouns = b; } @Override 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 class return bouns == other.bouns; } @Override public int hashCode() { return super.hashCode() + 17 * new Double(bouns).hashCode(); } @Override public String toString() { return super.toString() + "[bouns=" + bouns + "]"; } private double bouns; }
equals() 與 == 的差別是什麼?
== : 它的作用是判斷兩個物件的位址是不是相等。即,判斷兩個物件是不是同一個物件。
equals() : 它的作用也是判斷兩個物件是否相等。但它一般有兩種使用情況:
情況1,類別沒有覆寫equals()方法。則透過equals()比較該類別的兩個物件時,等價於透過「==」比較這兩個物件。
情況2,類別覆寫了equals()方法。一般,我們都覆寫equals()方法來兩個物件的內容相等;若它們的內容相等,則傳回true(即,認為這兩個物件相等)。
下面,透過範例比較它們的差異。
程式碼如下:
import java.util.*; import java.lang.Comparable; /** * @desc equals()的测试程序。 */ public class EqualsTest3{ public static void main(String[] args) { // 新建2个相同内容的Person对象, // 再用equals比较它们是否相等 Person p1 = new Person("eee", 100); Person p2 = new Person("eee", 100); System.out.printf("p1.equals(p2) : %s\n", p1.equals(p2)); System.out.printf("p1==p2 : %s\n", p1==p2); } /** * @desc Person类。 */ private static class Person { int age; String name; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return name + " - " +age; } /** * @desc 覆盖equals方法 */ @Override public boolean equals(Object obj){ if(obj == null){ return false; } //如果是同一个对象返回true,反之返回false if(this == obj){ return true; } //判断是否类型相同 if(this.getClass() != obj.getClass()){ return false; } Person person = (Person)obj; return name.equals(person.name) && age==person.age; } } }
執行結果:
p1.equals(p2) : true p1==p2 : false
#結果分析:
在EqualsTest3.java 中:
(1) p1.equals(p2)
這是判斷p1和p2的內容是否相等。因為Person覆蓋equals()方法,而這個equals()是用來判斷p1和p2的內容是否相等,恰恰p1和p2的內容又相等;因此,傳回true。
(2) p1==p2
這是判斷p1和p2是否是同一個物件。由於它們是各自新建的兩個Person物件;因此,傳回false。
更多程式相關知識,請造訪:程式設計教學! !
以上是java equals()方法怎麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!