オブジェクトクラスのequalsメソッドは、オブジェクトが別のオブジェクトに等しいかどうかを検出するために使用されます。オブジェクトクラスでは、このメソッドは2つのオブジェクトが同じ参照を持っているかどうかを決定します。 2つのオブジェクトに同じ参照がある場合、それらは等しくなければなりません。この観点から、デフォルトの操作として使用することは合理的です。ただし、ほとんどのクラスでは、この判断は無意味です。たとえば、2つのプリントストリームがこの方法で等しいかどうかを比較することは完全に意味がありません。ただし、多くの場合、2つのオブジェクトの状態の平等を検出する必要があります。 2つのオブジェクトの状態が等しい場合、2つのオブジェクトは等しいと見なされます。したがって、一般に、等しい比較はカスタムクラスで書き直す必要があります。
完璧なequals()メソッドを書くためのいくつかの提案を以下に示します。
(1)明示的なパラメーターにはotherObjectという名前が付けられており、後で他の変数と呼ばれる変数に変換する必要があります
(2)これとその他のオブジェクトが同じオブジェクトを参照するかどうかを検出します。
if(this == otherObject)trueを返します。
このステートメントは単なる最適化です。実際、これはしばしば採用される形式です。この方程式の計算は、クラスのフィールドを1つずつ比較するよりもはるかに安価であるためです。
(3)他のオブジェクトがnullであるかどうかを確認し、nullの場合はfalseを返します。このテストが必要です。
if(otherObject == null)falseを返します。
(4)これとその他のオブジェクトが同じクラスに属しているかどうかを比較します。等しいサブクラスの変化のセマンティクスがgetClass()を使用してそれを検出します。
if(getClass()!= otherObject.getClass())falseを返します。
すべてのサブクラスに同じセマンティクスがある場合は、検出のインスタンスを使用してください
if(!(otherObject instanceof className))falseを返します。
(5)他のオブジェクトを対応するタイプの変数に変換します。
className other =(className)otherObject;
(6)比較する必要があるすべてのドメインの比較を開始します。 ==を使用して、基本型ドメインを比較し、等しいものを使用してオブジェクトドメインを比較します。すべてのフィールドが一致する場合はtrueを返し、それ以外の場合はfalseを返します。
return field1 == other.field1 && field2.equals(other.field2)
Equalsがサブクラスで再定義されている場合、Call Super.equals(その他)を含める必要があります。検出が失敗した場合、平等になることは不可能です。スーパークラスのドメインが等しい場合は、サブクラスのインスタンスドメインを比較します。
配列タイプのフィールドの場合、static arrays.equalsメソッドを使用して、対応する要素が等しいかどうかを検出できます。
文字列の比較例を見てみましょう。
文字列a = "abc";文字列b = "abc";文字列c = new String( "ABC");文字列d = new String( "ABC"); System.out.println(a == b); // true文字列定数はJavaで共有されているため、コピーシステムは1つだけです。out.println(a == c); // false aおよびcは2つの異なるオブジェクトSystem.out.println(a.equals(c))に属します。 // true文字列オブジェクトの等式方法はオブジェクトの値を比較するため、trueを返します。 (オブジェクトの等式とは異なります)system.out.println(c == d); // falseオブジェクトの値は同じですが、それらは2つの異なるオブジェクトに属します。 // 真実
簡単に言えば、文字列定数を比較すると、結果がequalsで返されるのと同じです。文字列オブジェクトの値を比較する場合は、等しいものを使用します。
平等を使用する例を参照してください。
パッケージChapter055。equalStest; Java.util。*をインポートします。 public class equalstest {public static void main(string [] args){従業員Alice1 = new Employee( "Alice Adams"、75000、1987、12、15);従業員Alice2 = Alice1; //同じオブジェクトを参照してください従業員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;給与= s;グレゴリアンカレンダーカレンダー=新しいグレゴリアンカレンダー(年、月、日); hireday = calendar.getTime(); } public string getname(){return name; } public double getSalary(){return Salary; } public date gethireday(){return hireday; } public void raisearary(double by percent){double raise = salary * by percent / 100;給与 +=昇給; } @Override public boolean equals(object other object){//クイックテスト(this == otherObject)がtrueを返す場合、オブジェクトが識別されるかどうかを確認します。 //明示的なパラメーターがnullの場合、falseを返す必要があります(otherObject == null)falseを返します。 //分類されたものが一致しない場合、(getClass()!= otherObject.getClass())falseを返す場合、それらは等しくなりません。 //他のオブジェクトは非ヌルの従業員従業員であることがわかりますother =(Employee)otherObject; //フィールドhavaが値を識別したかどうかをテストします。 } @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 + "]"; }プライベート文字列名;プライベートダブルサラリー;プライベートデート雇用; } class Managerは従業員{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();バースラリー +バウンを返します。 } public void setBouns(double b){bouns = b; } @Override public boolean equals(Object otherObject){if(!super.equals(other object))return false;マネージャーその他=(マネージャー)otherObject; // Super Equalsは、これと他の人が同じクラスの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 + "]"; }プライベートダブルバウン; } 「クラスがequals()メソッドを上書きするかどうかに従って、より深く進み、2つのカテゴリに分割します。
(1)クラスがequals()メソッドをオーバーライドしない場合、2つのオブジェクトをequals()を介して比較する場合、実際には2つのオブジェクトが同じオブジェクトであるかどうかを比較しています。現時点では、これら2つのオブジェクトを「==」で比較することと同等です。
(2)クラスのequals()メソッドをオーバーライドして、2つのオブジェクトが他の方法で等しいかどうかを比較()することができます。通常のプラクティスは次のとおりです。2つのオブジェクトの内容が等しい場合、equals()メソッドはtrueを返します。それ以外の場合、それはファーズを返します。
次に、上記の2つの状況を説明するための例を挙げましょう。
1.「Equals()メソッドを無効にしない」の場合
コードは次のとおりです(equaltest1.java):
Import java.util。*; Import Java.lang.comParable;/*** @desc equals()テストプログラム。 */public class equalttest1 {public static void main(string [] args){//同じコンテンツを持つ2つの新しい人オブジェクトを作成します。人P2 =新しい人( "eee"、100); System.out.printf( "%s/n"、p1.equals(p2)); } /*** @desc personクラス。 */ private staticクラスの人{int age;文字列名; public Person(string name、int age){this.name = name; this.age = age; } public string toString(){return name + " - " + age; }}}実行結果:
次のようにコードをコピーします:false
結果分析P1.Equals(P2)を使用して、「P1とP2が等しいかどうかを比較します」。実際、object.javaのequals()メソッド、つまり(p1 == p2)と呼ばれる方法が呼ばれます。 「P1とP2が同じオブジェクトであるかどうか」を比較することです。
P1とP2の定義から、コンテンツは同じですが、2つの異なるオブジェクトであることがわかります!したがって、戻り結果はfalseです。
2。「上書き()方式」の状況
上記のEquartStest1.javaを変更します。Equals()メソッドをオーバーライドします。
コードは次のとおりです(equaltest2.java):
Import java.util。*; Import Java.lang.comParable;/*** @desc equals()テストプログラム。 */public class equalttest2 {public static void main(string [] args){//同じコンテンツを持つ2つの新しい人オブジェクトを作成します。人P2 =新しい人( "eee"、100); System.out.printf( "%s/n"、p1.equals(p2)); } /*** @desc personクラス。 */ private staticクラスの人{int age;文字列名; public Person(string name、int age){this.name = name; this.age = age; } public string toString(){return name + " - " + age; } / *** @desc override equals method* / @override public boolean equals(object obj){if(obj == null){return false; } //それが同じオブジェクトの場合、trueを返し、それ以外の場合はfalseを返します(this == obj){return true; } //タイプが同じであるかどうかを判断} person person =(person)obj; return name.equals(person.name)&& age == person.age; }}}実行結果:
次のようにコードをコピーします:true
結果分析:
equalTest2.javaで人の等しい()関数をオーバーライドします:2人のオブジェクトの名前と年齢が等しい場合、それは真実です。
したがって、実行結果はtrueを返します。
そうは言っても、JavaのEquals()の要件について話しましょう。次のポイントがあります:
対称性:X.Equals(Y)が「True」を返す場合、Y.Equals(x)も「true」を返す必要があります。
反射率:x.equals(x)は「true」を返す必要があります。
アナロジー:X.Equals(Y)が「True」を返し、Y.Equals(Z)が「True」を返す場合、Z.Equals(X)も「True」を返す必要があります。
一貫性:x.equals(y)が「true」を返す場合、xとyの内容が変化しない限り、x.equals(y)を何回繰り返しても、リターンは「真」になります。
非空白、x.equals(null)は、常に「false」を返します。 x.equals(異なるタイプとxのオブジェクト)は常に「false」を返します。
次に、equals()の役割を確認しましょう。2つのオブジェクトが等しいかどうかを判断します。 equals()を書き直すと、その関数を変更することは不可能です!
equals()と==の違いは何ですか?
==:その関数は、2つのオブジェクトのアドレスが等しいかどうかを判断することです。つまり、2つのオブジェクトが同じオブジェクトであるかどうかを判断します。
equals():その関数は、2つのオブジェクトが等しいかどうかを判断することです。ただし、通常、2つの使用条件があります(前のパート1で詳細に説明されています):
ケース1、クラスはequals()メソッドをオーバーライドしません。次に、このクラスの2つのオブジェクトをequals()を介して比較する場合、これら2つのオブジェクトを「==」で比較することに相当します。
ケース2、クラスはequals()メソッドをオーバーライドします。一般に、2つのオブジェクトの内容を等しくするために、equals()メソッドをオーバーライドします。それらの内容が等しい場合、それはtrueを返します(つまり、2つのオブジェクトは等しいと見なされます)。
以下に、例で違いを比較してください。
コードは次のとおりです。
Import java.util。*; Import Java.lang.comParable;/*** @desc equals()テストプログラム。 */public class equalttest3 {public static void main(string [] args){//同じコンテンツを持つ2つの新しい人オブジェクトを作成します。人P2 =新しい人( "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クラスの人{int age;文字列名; public Person(string name、int age){this.name = name; this.age = age; } public string toString(){return name + " - " + age; } / *** @desc override equals method* / @override public boolean equals(object obj){if(obj == null){return false; } //それが同じオブジェクトの場合、trueを返し、それ以外の場合はfalseを返します(this == obj){return true; } //タイプが同じであるかどうかを判断} person person =(person)obj; return name.equals(person.name)&& age == person.age; }}}実行結果:
P1.Equals(P2):TRUEP1 == P2:FALSE
結果分析:
equalstest3.javaで:
(1)P1.Equals(P2)
これは、P1とP2の含有量が等しいかどうかを判断するためです。人はequals()メソッドをオーバーライドし、これはequals()を使用してP1とP2の内容が等しいかどうかを判断するため、P1とP2の内容は正確に等しくなります。したがって、trueを返します。
(2)P1 == P2
これは、P1とP2が同じオブジェクトであるかどうかを判断するためです。それらはそれぞれ2つの新しい人物であるためです。したがって、falseを返します。