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


84

我建立了一个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));
    }


}

编译后显示两次错误。如果两个对象具有相同的字段-“测试”,为什么会为假?


7
顺便说一句,看看,equals并且equals2:每当您拥有某种形式的表格时if(a) { return true; } else { return false; },都可能应该写return a
yshavit 2012年

@yshavit您的意思是,将布尔值更改为字符串吗?
Fastkowy12年

4
不,你的代码是询问是否一个布尔值,是一个真正的,并返回true如果是和false其他。因此,例如,if(a.equals(object2)) { return true; } else return false可能是return a.equals(object2)
yshavit 2012年

Answers:


142

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

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

在您的情况下,如果MyClass字符串匹配,则确实将两个实例居中相等,则:

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

...但是通常如果您要定义一个类,那么等效性要比单个字段的等效性强(a在这种情况下)。


旁注:如果覆盖equals,则几乎总是需要覆盖hashCode。就像在equalsJavaDoc中所说的:

请注意,通常有必要在重写此hashCode方法时重写该方法,以维护该hashCode方法的常规协定,该协定规定相等的对象必须具有相等的哈希码。


@TJ in ==详细说明对象引用,这是否意味着==比较两个对象的哈希码?
Narendra Jaggi

@NarendraJaggi-不,这意味着JVM将检查两个操作数是否都引用相同的对象。如何它确实是到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.equals(obj)而不是(this == null)
goonerify 2015年

10
我认为if (this == null)无论如何都没有必要。调用nullObject.equals(whatever)将引发null指针异常,因此我们可以放心地假定this在我们可能编写的任何Java方法中,它都不为null。
莫拉

1
如果thislastnamenull并且不满足先前的条件,则此操作将失败 。
艾哈迈德·拉杰

6

看起来好像equals2只是在调用equals,所以它将给出相同的结果。


5

覆盖函数equals()是错误的。对象“ a”是String类的实例,而“ object2”是MyClass类的实例。它们是不同的类,因此答案是“假”。


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
我想这样称呼:过度杀伤力。
罗尔夫(Rolf)2015年

@Rolfツ为什么您认为这太过分了?我一直在寻找解决这个问题的方法,这是到目前为止我发现的最简单的方法。欢迎任何更好的建议。
m5seppal '17

3
因为使用Java您可以比较对象而无需先创建Gson对象然后调用toJson。创建Gson对象并调用将实际对象转换为flat StringtoJson)所需的逻辑是不必要的开销。您可以比较对象而无需先将对象转换为Json字符串(这也更快)。
罗尔夫(Rolfツ)

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
Justreturn a.equals(object2);
mojuba

2

语句a == object2a.equals(object2)两者都将始终返回,false因为a一段string时间object2是的实例MyClass


2

您的实现必须喜欢:

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

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


2

如果不需要自定义默认的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 + '\'' +
            '}';
}
}

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

输出:用==运算符比较两个字符串:false使用equals方法比较两个具有相同内容的字符串:true用==运算符比较两个指向相同字符串的引用: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已经是对或错。


1

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

C ++具有运算符重载的一些附加信息,而Java不提供运算符重载。Java中的其他可能性还包括实现Compare接口的Compare接口方法。

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


4
考虑一下您的答案并没有增加将近2年前没有说过的内容。
热门点击

1

在这里,输出将为false,因为在第一个sopln语句中,您试图将Myclass类型的字符串类型变量与另一个MyClass类型进行比较,并且由于这两个都是Object类型,并且您使用了“ ==” oprerator将会检查保存实际内存而不是内存内部实际内容的参考变量值。在第二个解决方案中,它也与您再次调用a.equals(object2)相同,其中a是object1内部的变量。让我知道你对此的发现。


2
欢迎来到stackoverflow bidyadhar。该问题的日期为2012年11月14日,已经得到了很好的答复(由OP批准)。您得到的是正确的,但是没有添加有用的信息。我建议您在执行任何操作之前先阅读规则
-Nikaido

-3

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

public boolean equals2(Object object2){if(a.equals(object2)){//在这里,您要调用重写方法,这就是为什么您两次虚假的原因。返回true;否则返回false;}


1
不,a.equals是字符串的方法,任何地方都不会覆盖它。
Tarec 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.