web-dev-qa-db-ja.com

2つのオブジェクトを.equals()と==演算子で比較します

1つのStringフィールドを持つクラスを構築しました。それから2つのオブジェクトを作成し、==演算子と.equals()を使ってそれらを比較しなければなりません。これが私がしたことです:

public class MyClass {

    String a;

    public MyClass(String ab) {
        a = ab;
    }

    public boolean equals(Object object2) {
        if(a == object2) { 
            return true;
        }
        else return false;
    }

    public boolean equals2(Object object2) {
        if(a.equals(object2)) {
            return true;
        }
        else return false;
    }



    public static void main(String[] args) {

        MyClass object1 = new MyClass("test");
        MyClass object2 = new MyClass("test");

        object1.equals(object2);
        System.out.println(object1.equals(object2));

        object1.equals2(object2);
        System.out.println(object1.equals2(object2));
    }


}

コンパイル後、結果として2回falseが表示されます。 2つのオブジェクトに同じフィールドがある場合、なぜそれが間違っているのですか? "test"

73
Fastkowy

==はオブジェクト参照を比較し、2つのオペランドが同じオブジェクトを指しているかどうかを確認します(equivalentobjectsではなくsameオブジェクトではありません)。

(同じ文字が含まれているかどうかを調べるために)文字列を比較したい場合は、equalsを使用して文字列を比較する必要があります。

あなたのケースでは、文字列が一致すればMyClassの2つのインスタンスが本当に等しいとみなされるなら、

public boolean equals(Object object2) {
    return object2 instanceof MyClass && a.equals(((MyClass)object2).a);
}

...しかし、通常あなたがクラスを定義しているならば、単一のフィールド(この場合はa)の同値よりも同値より多くのものがあります。


サイドノート:equalsをオーバーライドする場合は、ほとんどの場合、 hashCode をオーバーライドする必要があります。 equals JavaDoc にあるように、

hashCodeメソッドの一般的な規約を維持するために、このメソッドがオーバーライドされるたびにhashCodeメソッドをオーバーライドする必要があることに注意してください。

124
T.J. Crowder

equalsをオーバーライドするべきです

 public boolean equals (Object obj)
  {
   if (this==obj) return true;
   if (this == null) return false;
   if (this.getClass() != obj.getClass()) return false;
   // Class name is Employ & have lastname
   Employe emp = (Employee) obj ;
   return this.lastname.equals(emp.getlastname());
   }
16
user5119219

equals2equalsを呼び出しているだけなので、同じ結果になります。

5
Hew Wolff

上書き関数equals()が間違っています。オブジェクト "a"はStringクラスのインスタンス、 "object2"はMyClassクラスのインスタンスです。それらは異なるクラスなので、答えは「偽」です。

あなたのequals2()メソッドは常にequals()と同じものを返します。

あなたのコード私のコメントと:

public boolean equals2(Object object2) {  // equals2 method
    if(a.equals(object2)) { // if equals() method returns true
        return true; // return true
    }
    else return false; // if equals() method returns false, also return false
}
4
jlordo

2つのオブジェクトを比較する最良の方法は、それらをJSON文字列に変換して文字列を比較することです。これは、複雑な入れ子になったオブジェクト、フィールド、配列を含むオブジェクトを扱う場合の最も簡単な解決方法です。

サンプル:

import com.google.gson.Gson;


Object a = // ...;
Object b = //...;
String objectString1 = new Gson().toJson(a);
String objectString2 = new Gson().toJson(b); 

if(objectString1.equals(objectString2)){
    //do this
}
3
JoeG

falseaであるのに対してa == object2stringのインスタンスであるため、ステートメントobject2およびa.equals(object2)は常にMyClassを返します。

2
ashish.al

あなたの実装は以下のようにする必要があります。

public boolean equals2(Object object2) {
    if(a.equals(object2.a)) {
        return true;
    }
    else return false;
}

この実装ではあなたの両方の方法がうまくいくでしょう。

2
Azhar Khan

"=="演算子は、2つの参照がメモリ内の同じオブジェクトを指している場合にのみtrueを返します。一方、equals()メソッドは、オブジェクトの内容に基づいてtrueを返します。

例:

String personalLoan = new String("cheap personal loans");
String homeLoan = new String("cheap personal loans");

//since two strings are different object result should be false
boolean result = personalLoan == homeLoan;
System.out.println("Comparing two strings with == operator: " + result);

//since strings contains same content , equals() should return true
result = personalLoan.equals(homeLoan);
System.out.println("Comparing two Strings with same content using equals method: " + result);

homeLoan = personalLoan;
//since both homeLoan and personalLoan reference variable are pointing to same object
//"==" should return true
result = (personalLoan == homeLoan);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);

出力:==演算子を使用した2つの文字列の比較:false equalsメソッドを使用した同じ内容の2つの文字列の比較:true ==演算子を使用した同じ文字列を指す2つの参照の比較:true

またリンクからより多くの詳細を得ることができる: http://javarevisited.blogspot.in/2012/12/difference-between-equals-method-and-equality-operator-Java.html?m=1

2
Madhan

あなたのクラスは同じ機能を達成するためにComparableインターフェースを実装するかもしれません。あなたのクラスはインタフェースで宣言されたcompareTo()メソッドを実装するべきです。

public class MyClass implements Comparable<MyClass>{

    String a;

    public MyClass(String ab){
        a = ab;
    }

    // returns an int not a boolean
    public int compareTo(MyClass someMyClass){ 

        /* The String class implements a compareTo method, returning a 0 
           if the two strings are identical, instead of a boolean.
           Since 'a' is a string, it has the compareTo method which we call
           in MyClass's compareTo method.
        */

        return this.a.compareTo(someMyClass.a);

    }

    public static void main(String[] args){

        MyClass object1 = new MyClass("test");
        MyClass object2 = new MyClass("test");

        if(object1.compareTo(object2) == 0){
            System.out.println("true");
        }
        else{
            System.out.println("false");
        }
    }
}
2
tectonicfury

デフォルトのtoString()関数をカスタマイズする必要がない場合、もう1つの方法はtoString()メソッドをオーバーライドすることです。これは比較されるすべての属性を返します。次に、2つのオブジェクトのtoString()出力を比較します。 IntelliJ IDEA IDEを使用してtoString()メソッドを生成しました。これには文字列にクラス名が含まれています。

public class Greeting {
private String greeting;

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    return this.toString().equals(obj.toString());
}

@Override
public String toString() {
    return "Greeting{" +
            "greeting='" + greeting + '\'' +
            '}';
}
}
2
Qinjie

==を使用すると、実際のオブジェクトではなくオブジェクトの参照が比較されます。 Javaオブジェクトを比較するためにequalsメソッドをオーバーライドする必要があります。

C++にはオーバーロード演算子があり、Javaにはオーバーロード演算子はありません。 Javaにおける他の可能性も実装されていますCompare Interface .whoはcompareToメソッドを定義します。

Comparatorインターフェース 2つのオブジェクトを比較するのにも使われます

1
umesh atada

object.equalsの戻り型はすでにブール値です。ブランチでメソッドにラップする必要はありません。 2つのオブジェクトを比較したい場合は、単純にそれらを比較します。

boolean b = objectA.equals(objectB);

bはすでに真か偽です。

1
Cpt. Mirk

ここでの出力はfalseになります。最初のsoplnステートメントでMyclass型の可変の文字列型を他のMyClass型と比較しようとしています。メモリ内の実際のcontnetsではなく実際のメモリを保持している参照変数値をチェックします。 2番目のsoplnでも、aがobject1の中の変数であるa.equals(object2)をもう一度呼び出すのと同じです。これに関するあなたの調査結果を教えてください。

1
Bidyadhar