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


84

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つのオブジェクトが同じフィールド(「テスト」)を持っている場合、なぜそれが間違っているのですか?


7
ところで、見てequalsequals2:あなたが何かの形if(a) { return true; } else { return false; }を持っているときはいつでもあなたはおそらくただ書くべきreturn aです。
yshavit 2012年

@yshavitつまり、ブール値から文字列に変更されたのですか?
fastkowy 2012年

4
いいえ、コードはブール値が真であるかどうかを尋ね、真であるtrueかどうかを返しfalseます。したがって、たとえば、if(a.equals(object2)) { return true; } else return falsereturn a.equals(object2)
yshavit 2012年

回答:


142

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

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

あなたの場合、MyClass文字列が一致する場合、の2つのインスタンスが実際に等しいと見なされると、次のようになります。

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

...しかし、通常、クラスを定義aしている場合、単一のフィールド(この場合)の同等性よりも同等性の方が重要です。


補足:をオーバーライドする場合equals、ほとんどの場合、をオーバーライドする必要がありますhashCodeequalsJavaDocで言うように:

hashCodeメソッドの一般的なコントラクトを維持するために、このメソッドがオーバーライドされるたびにメソッドをオーバーライドする必要があることに注意してくださいhashCode。これは、等しいオブジェクトには等しいハッシュコードが必要であると述べています。


@TJ In ==は、オブジェクト参照を比較して詳しく説明します。つまり、== 2つのオブジェクトのハッシュコードを比較しますか?
ナレンドラジャギ

@ NarendraJaggi-いいえ、JVMが2つのオペランドが両方とも同じオブジェクトを参照しているかどうかを確認することを意味します。それをどのように行うかはJVM次第ですが、ハッシュコードを使用してそれを行うと考える理由はありません。
TJ Crowder

19

等しいをオーバーライドする必要があります

 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());
 }

2
これは間違いなく最良の答えですが、非プリミティブ型の場合は(this == null)の代わりにthis.equals(obj)を使用することをお勧めします
goonerify 2015年

10
if (this == null)とにかくこの事件は不要だと私は主張したい。呼び出しnullObject.equals(whatever)はnullポインター例外をスローするためthis、作成するJavaメソッドではnullではないと安全に想定できます。
マウラ2016年

1
thislastnamenullで、前の条件を満たさない場合、これは失敗し ます。
AhmedRaaj18年


5

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


5

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
}

9
私はこれをやり過ぎと呼びたい。
ロルフツ2017年

@Rolfツなぜこれがあなたの意見ではやり過ぎなのですか?私はこの問題の解決策を探しましたが、これは私がこれまでに見つけた最も簡単な解決策です。より良い提案は大歓迎です。
m5seppal 2017

3
Javaを使用するGsonと、最初にオブジェクトを作成してからを呼び出すことなく、オブジェクトを比較できるためですtoJsonGsonオブジェクトを作成し、実際のオブジェクトをフラットStringtoJson)に変換するために必要なロジックを呼び出すことは、不要なオーバーヘッドです。最初にオブジェクトをJson文字列に変換せずにオブジェクトを比較できます(これも高速です)。
ロルフツ2017

3

あなたの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
}

5
ただreturn a.equals(object2);
mojuba 2018年

2

はしばらくの間はのインスタンスであるため、ステートメントa == object2a.equals(object2)両方は常に返さfalseれますastringobject2MyClass


2

実装は次のようにする必要があります。

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

この実装では、両方の方法が機能します。


2

デフォルトのtoString()関数をカスタマイズする必要がない場合、別の方法は、比較するすべての属性を返すtoString()メソッドをオーバーライドすることです。次に、2つのオブジェクトのtoString()出力を比較します。文字列にクラス名を含むIntelliJIDEA 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

"=="演算子は、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

クラスは、同じ機能を実現するために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");
        }
    }
}

1

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

boolean b = objectA.equals(objectB);

bはすでにtrueまたはfalseのいずれかです。


1

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

C ++にはオーバーロードの演算子があり、Javaにはオーバーロードの演算子がありません。また、Javaでの他の可能性が実装されている比較インタフェースcompareToメソッドを定義.whichを。

コンパレータインターフェースも使用され、2つのオブジェクトを比較します


4
あなたの答えは、ほぼ2年前に言われなかったものを何も追加しないと考えてください。
ホットリック2014

1

ここで、出力はfalseになります。最初のsoplnステートメントでは、Myclassタイプの文字列タイプ変数を他のMyClassタイプと比較しようとしているため、falseになります。どちらもオブジェクトタイプであり、「==」演算子を使用しているためです。メモリ内の実際の文字列ではなく、実際のメモリを保持している参照変数値をチェックします。2番目のsoplnでも、a.equals(object2)を再度呼び出すのと同じです。ここでaはobject1内の変数です。これに関するあなたの発見を私に知らせてください。


2
stackoverflowbidyadharへようこそ。質問の日付は2012年11月14日で、すでに良好な回答が得られています(OPによって承認されています)。あなたが得たものは正しいですが、それは有用な情報を追加していません。何かをする前にルールを読むことをお勧めします
Nikaido

-3

以下のコードでは、オーバーライドされたメソッド.equals()を呼び出しています。

public boolean equals2(Object object2){if(a.equals(object2)){//ここではオーバーライドされたメソッドを呼び出しているため、falseが2回発生します。trueを返します。それ以外の場合はfalseを返します。}


1
いいえ、a.equals文字列のメソッドです。どこでもオーバーライドされません。
タレック2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.