【问题标题】:Compare two objects with .equals() and == operator使用 .equals() 和 == 运算符比较两个对象
【发布时间】:2012-11-03 11:24:52
【问题描述】:

我用一个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));
    }


}

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

【问题讨论】:

  • 顺便说一句,看看equalsequals2:任何时候你有if(a) { return true; } else { return false; } 形式的东西,你可能应该写return a
  • @yshavit 你的意思是,从布尔值更改为字符串?
  • 不,您的代码询问布尔值是否为真,如果是则返回true,否则返回false。例如,if(a.equals(object2)) { return true; } else return false 可能只是 return a.equals(object2)

标签: java class object methods equals


【解决方案1】:

你应该覆盖等于

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

【讨论】:

  • 这可以说是最好的答案,但是对于非原始类型,您可能希望使用 this.equals(obj) 而不是 (this == null)
  • 我认为if (this == null) 的情况无论如何都是不必要的;调用nullObject.equals(whatever) 将抛出一个空指针异常,因此我们可以安全地假设this 在我们可能编写的任何Java 方法中都不为空。
  • 我认为if (this == null) 不是不必要的,但检查了错误的对象。在第三行之前,我们需要检查obj,所以第二个 if 应该是if (obj == null)
  • @goonerify 这将导致StackOverflowException,因为它将递归调用相同的equals 方法而没有任何停止条件。
  • this == null 将始终为 false,因为 this 是对当前对象的引用——它永远不能为空!
【解决方案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");
        }
    }
}

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • 欢迎来到stackoverflow bidyadhar。该问题的日期为 2012 年 11 月 14 日,并且已经得到了很好的回应(由 OP 批准)。你得到的那个是正确的,但它没有添加有用的信息。我建议你在做任何事情之前阅读规则
        【解决方案6】:

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

        如果你想比较字符串(看它们是否包含相同的字符),你需要使用equals比较字符串。

        在您的情况下,如果 MyClass 的两个实例在字符串匹配的情况下确实被认为是相等的,那么:

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

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


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

        请注意,当hashCode 方法被重写时,通常需要重写此方法,以维护hashCode 方法的一般约定,即相等的对象必须具有相等的哈希码。

        【讨论】:

        • @TJ 在 == 中比较对象引用,详细来说,是不是表示 == 比较两个对象的hashcode?​​span>
        • @NarendraJaggi - 不,这意味着 JVM 检查两个操作数是否都引用同一个对象。 如何这取决于 JVM,但没有理由认为它会使用哈希码来做到这一点。
        【解决方案7】:

        比较两个对象的最佳方法是将它们转换为 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
        }
        

        【讨论】:

        • 我想称之为:矫枉过正。
        • @Rolfツ 为什么在你看来这太过分了?我一直在寻找解决这个问题的方法,这是迄今为止我找到的最简单的解决方案。欢迎任何更好的建议。
        • 因为使用 Java,您无需先创建 Gson 对象然后调用 toJson 即可比较对象。创建Gson 对象并调用将实际对象转换为平面String (toJson) 所需的逻辑是不必要的开销。您可以在不先将对象转换为 Json 字符串的情况下比较对象(这也更快)。
        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

          你的实现必须是这样的:

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

          有了这个实现,你的两种方法都可以工作。

          【讨论】:

            【解决方案10】:

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

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

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

            【讨论】:

            • 请考虑一下,您的回答几乎没有增加几乎 2 年前没有说过的内容。
            【解决方案11】:

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

            boolean b = objectA.equals(objectB);
            

            b 已经是真或假了。

            【讨论】:

              【解决方案12】:

              语句a == object2a.equals(object2) 都将始终返回false,因为astringobject2MyClass 的一个实例

              【讨论】:

                【解决方案13】:

                在下面的代码中,您正在调用被覆盖的方法 .equals()。

                public boolean equals2(Object object2) { if(a.equals(object2)) { // 这里你调用了被覆盖的方法,这就是你得到 false 2 次的原因。 返回真; } 否则返回假; }

                【讨论】:

                • 不,a.equals 是字符串的方法,它不会在任何地方被覆盖。
                【解决方案14】:

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

                【讨论】:

                • OP 正在调用类成员 String aequals 方法。 equals2 没有调用 equals
                • 好的,谢谢。看起来我完全错过了 MyClass 和 String 之间的混淆,这是真正的问题。
                • 更具体地说,equals2()a(即 String)与 object2(即 Object)和可能的 MyClass 进行比较,在正常使用中总是返回 false。
                【解决方案15】:

                您的equals2() 方法总是返回与equals() 相同的结果!!

                你的代码和我的 cmets:

                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
                }
                

                【讨论】:

                • return a.equals(object2);
                猜你喜欢
                • 1970-01-01
                • 2011-04-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-01-20
                • 1970-01-01
                相关资源
                最近更新 更多