使用 .equals() 和 == 运算符比较两个对象

Compare two objects with .equals() and == operator

提问人:Fastkowy 提问时间:11/15/2012 最后编辑:HashFastkowy 更新时间:11/21/2023 访问量:433499

问:

我用一个字段构建了一个类。然后我创建了两个对象,我必须使用运算符和来比较它们。这是我所做的:String==.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));
    }


}

编译后,结果显示两次 false。如果两个对象具有相同的字段 - “test”,为什么是假的?

Java 对象 方法 等于

评论

8赞 yshavit 11/15/2012
顺便说一句,看看和:任何时候你有某种形式的东西,你可能应该写。equalsequals2if(a) { return true; } else { return false; }return a
0赞 Fastkowy 11/15/2012
@yshavit 你的意思是,从布尔值更改为字符串?
4赞 yshavit 11/15/2012
不,您的代码正在询问布尔值是否为真,如果为真,则返回。例如,可以只是.truefalseif(a.equals(object2)) { return true; } else return falsereturn a.equals(object2)
1赞 bjb568 4/4/2015
如何比较 Java 中的字符串?

答:

4赞 jlordo 11/15/2012 #1

您的方法将始终返回与 !! 相同的结果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
}

评论

6赞 mojuba 1/23/2018
return a.equals(object2);
6赞 Hew Wolff 11/15/2012 #2

看起来只是调用,所以会给出相同的结果。equals2equals

评论

1赞 Yigit Alparslan 11/18/2020
OP 调用 String 的方法,该方法作为类的成员。 不是在打电话equalsaequals2equals
1赞 Hew Wolff 11/20/2020
是的,谢谢。看起来我完全错过了 MyClass 和 String 之间的混淆,这才是真正的问题。
0赞 Zarremgregarrok 1/19/2021
更具体地说,比较哪个是哪个是,哪个可能在正常用法中总是返回 false。equals2()aStringobject2ObjectMyClass
156赞 T.J. Crowder 11/15/2012 #3

==比较对象引用,它检查两个操作数是否指向同一个对象(不是等效对象,而是同一个对象)。

如果要比较字符串(以查看它们是否包含相同的字符),则需要使用 .equals

在您的例子中,如果两个实例 really 在字符串匹配时被视为相等,则:MyClass

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

...但通常,如果你要定义一个类,那么等价性比单个字段的等价性要多(在本例中)。a


旁注:如果你覆盖,你几乎总是需要覆盖 hashCode。正如它在 equals JavaDoc 中所说:equals

请注意,每当重写此方法时,通常都需要重写该方法,以便维护该方法的一般约定,该约定规定相等的对象必须具有相等的哈希码。hashCodehashCode

评论

0赞 Narendra Jaggi 5/7/2020
@TJ In == 比较对象引用,详细说一下,这是否意味着 == 比较两个对象的哈希码?
0赞 T.J. Crowder 5/7/2020
@NarendraJaggi - 否,这意味着 JVM 会检查两个操作数是否都引用同一个对象。它如何做到这一点取决于 JVM,但没有理由认为它会使用哈希码来做到这一点。
-3赞 Ram 5/14/2014 #4

在下面的代码中,您将调用重写的方法.equals()

public boolean equals2(Object object2) {
    if(a.equals(object2)) { // here you are calling the overriden method, that is why you getting false 2 times.
        return true;
    }
    else return false;
}

评论

1赞 Tarec 5/14/2014
不,是字符串的方法,它不会在任何地方被覆盖。a.equals
2赞 ashish.al 8/1/2014 #5

语句和两者都将始终返回,因为 is a while 是a == object2a.equals(object2)falseastringobject2MyClass

1赞 Cpt. Mirk 8/7/2014 #6

object.equals 的返回类型已经是布尔值。 没有必要用分支将它包装在方法中。因此,如果您想比较 2 个对象,只需比较它们:

boolean b = objectA.equals(objectB);

b 已经是 true 或 false。

1赞 umesh atada 9/8/2014 #7

当我们使用 == 时,比较的是对象的 Reference,而不是实际对象。我们需要重写 equals 方法来比较 Java 对象。

一些附加信息 C++ 有运算符重载,而 Java 不提供运算符重载。 此外,java 中的其他可能性是实现 Compare Interface .,它定义了一个 compareTo 方法。

比较器接口也用于比较两个对象

评论

4赞 Hot Licks 9/8/2014
考虑到您的答案没有添加任何近 2 年前没有说过的内容。
2赞 Azhar Khan 10/31/2014 #8

您的实现必须满足以下条件:

public boolean equals2(Object object2) {
    return a.equals(object2.a);
}

通过此实现,这两种方法都可以使用。

6赞 Jesús Talavera Portocarrero 7/1/2015 #9

overwrite 函数 equals() 是错误的。 对象“a”是 String 类的实例,“object2”是 MyClass 类的实例。它们是不同的类,所以答案是“假的”。

22赞 user5119219 7/15/2015 #10

您应该覆盖等于

 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赞 goonerify 11/25/2015
这可以说是最好的答案,但是您可能希望对非原始类型使用 this.equals(obj) 而不是 (this == null)
11赞 Maura 10/4/2016
我认为无论如何,这个案子都是不必要的;调用将抛出一个 null 指针异常,因此我们可以放心地假设它在我们可能编写的任何 Java 方法中都不是 null。if (this == null)nullObject.equals(whatever)this
0赞 Zarremgregarrok 1/19/2021
我认为这并非没有必要,而是检查了错误的对象。在第三行之前,我们需要检查,所以第二行 if 应该是if (this == null)objif (obj == null)
0赞 M. Justin 5/27/2021
@goonerify 这将导致一个 ,因为它将递归地调用相同的方法,而没有任何停止条件。StackOverflowExceptionequals
0赞 M. Justin 5/27/2021
this == null将始终为 false,因为 是对当前对象的引用 — 它永远不能为 null!this
7赞 JoeG 2/23/2016 #11

比较 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
}

评论

11赞 Rolf ツ 1/2/2017
我想称之为:矫枉过正。
0赞 m5seppal 12/20/2017
@Rolfツ 为什么在你看来这是矫枉过正?我一直在寻找解决这个问题的方法,这是我迄今为止找到的最简单的解决方案。欢迎任何更好的建议。
4赞 Rolf ツ 12/20/2017
因为使用 Java 可以比较对象,而无需先创建对象然后调用 .创建对象并调用将实际对象转换为平面对象 () 所需的逻辑是不必要的开销。您可以比较对象,而无需先将对象转换为 Json 字符串(这也更快)。GsontoJsonGsonStringtoJson
2赞 tf3 10/10/2016 #12

您的类可能会实现 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");
        }
    }
}
3赞 Madhan 10/20/2016 #13

“==”运算符仅当两个引用指向内存中的同一对象时才返回 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);

输出: 使用 == 运算符比较两个字符串:false 使用 equals 方法比较具有相同内容的两个字符串:true 使用 == 运算符比较指向同一 String 的两个引用:true

您还可以从以下链接获取更多详细信息:http://javarevisited.blogspot.in/2012/12/difference-between-equals-method-and-equality-operator-java.html?m=1

1赞 Bidyadhar 7/6/2017 #14

这里的输出将是 false , false,因为在第一个 sopln 语句中,您尝试将 Myclass 类型的字符串类型变量与其他 MyClass 类型进行比较,并且它将允许,因为两者都是 Object 类型,并且您使用了“==”操作器,它将检查保存实际内存的引用变量值,而不是内存中的实际 contnet。 在第二个 sopln 中,它也与您再次调用 a.equals(object2) 相同,其中 a 是 object1 内部的可变变量。请让我知道你在这方面的发现。

评论

2赞 Nikaido 7/6/2017
欢迎来到stackoverflow bidyadhar。该问题的日期为 2012 年 11 月 14 日,并且已经得到了很好的答复(由 OP 批准)。你得到的那个是正确的,但它没有添加有用的信息。我建议您在做任何事情之前阅读规则
2赞 Qinjie 5/1/2018 #15

如果您不需要自定义默认的 toString() 函数,另一种方法是覆盖 toString() 方法,该方法返回要比较的所有属性。然后比较两个对象的 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 + '\'' +
            '}';
}
}
0赞 user19607514 7/23/2022 #16

简而言之,== 比较两个 POINTERS。

如果两个指针相等,则它们都指向内存中的同一对象(该对象显然与自身具有相同的值)。

但是,.equals 将比较所指向的任何值,如果它们都计算为相同的值,则返回 true。
因此,两个单独的字符串(即,在内存中的不同地址)始终是 !=,但如果它们包含相同的(以 null 结尾的)字符序列,则它们相等。