Java中的“==”和“equals()”有什么区别?

768

我想澄清一下,如果我理解正确的话:

  • == 是引用比较,即两个对象指向同一内存位置
  • .equals() 则比较对象中的值

62
差不多,没错。 - John Kane
13
可以,.equals() 可以被理解为“有实际意义的等价”。 - vikingsteve
可能是如何在Java中比较字符串?的重复问题。 - TylerH
32
“both objects point to the same memory location”这样的语句表达不够精确,会导致理解困难。您的意思是:“两个变量引用同一个对象”。请注意,变量不是对象;变量是指向对象的引用。 对象不会“指向”任何东西。 - Jesper
1
在C#(以及许多其他语言)中,相等运算符(**==)对应于Object.Equals()方法。派生类,如String,可以通过重写.Equals方法来定义两个字符串是==的含义。Java无法这样做。Java String类(以及Java中的任何类)都没有覆盖==**以使其行为符合预期的方法。这意味着你必须自己手动调用.equals() - Ian Boyd
"==" 用于原始类型,而 ".equals()" 用于比较引用类型(如果在引用类型上使用 "==",则默认比较哈希码)。 - Rishon_JR
26个回答

5
请记住,.equals(...) 必须由您尝试比较的类实现。否则,没有太大意义;对于 Object 类的方法版本执行与比较操作相同的操作:Object#equals
唯一需要使用对象比较运算符的时候是比较枚举(Enums)。这是因为每次只有一个 Enum 值的实例。例如,给定该枚举:
enum FooEnum {A, B, C}

您每次只能同时拥有一个 A 实例,BC 也是如此。这意味着您实际上可以编写以下方法:
public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

您将完全没有任何问题。


4

当你评估代码时,很明显(==)是按照内存地址进行比较,而equals(Object o)则是比较实例的hashCode()。这就是为什么人们说如果不遵守equals()和hashCode()之间的契约,那么以后可能会面临意外情况。

    String s1 = new String("Ali");
    String s2 = new String("Veli");
    String s3 = new String("Ali");

    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s3.hashCode());


    System.out.println("(s1==s2):" + (s1 == s2));
    System.out.println("(s1==s3):" + (s1 == s3));


    System.out.println("s1.equals(s2):" + (s1.equals(s2)));
    System.out.println("s1.equal(s3):" + (s1.equals(s3)));


    /*Output 
    96670     
    3615852
    96670
    (s1==s2):false
    (s1==s3):false
    s1.equals(s2):false
    s1.equal(s3):true
    */

4

“==” 和 “equals()” 的主要区别是:

1) “==” 用于比较基本数据类型。

例如:

        String string1 = "Ravi";
        String string2 = "Ravi";
        String string3 = new String("Ravi");
        String string4 = new String("Prakash");

        System.out.println(string1 == string2); // true because same reference in string pool
        System.out.println(string1 == string3); // false

2) equals() 用于比较对象。 例如:

        System.out.println(string1.equals(string2)); // true equals() comparison of values in the objects
        System.out.println(string1.equals(string3)); // true
        System.out.println(string1.equals(string4)); // false

4

示例1 -

在比较引用时,可以使用“==”和“.equals”方法。它们仅用于参考比较,即判断两个对象是否引用同一对象。

Object类的equals方法实现

public class HelloWorld{
     public static void main(String []args){
       Object ob1 = new Object();
       Object ob2 = ob1;
       System.out.println(ob1 == ob2); // true
       System.out.println(ob1.equals(ob2)); // true
     }    
}

enter image description here

例子2 -

但是,如果我们想使用equals方法比较对象内容,则类必须重写对象类的equals()方法并提供内容比较的实现。在这里,String类已经为内容比较重写了equals方法。所有包装类都已经为内容比较重写了equals方法。

String类equals方法的实现

public class HelloWorld{
     public static void main(String []args){
       String ob1 = new String("Hi");
       String ob2 = new String("Hi");
       System.out.println(ob1 == ob2); // false (Both references are referring two different objects)
       System.out.println(ob1.equals(ob2)); // true
     }
}

enter image description here

例子3 -

在String的情况下,还有一个用例。当我们将任何字符串分配给String引用时,字符串常量会在字符串常量池中创建。如果我们将相同的字符串分配给新的String引用,则不会创建新的字符串常量,而是将引用现有的字符串常量。

public class HelloWorld{
     public static void main(String []args){
       String ob1 = "Hi";
       String ob2 = "Hi";
       System.out.println(ob1 == ob2); // true
       System.out.println(ob1.equals(ob2)); // true
     }
}

enter image description here

请注意,通常需要覆盖hashCode方法,以便在重写该方法时保持hashCode方法的一般契约,该契约规定相等的对象必须具有相等的哈希码。 Java API equals() 方法契约

3

等号操作符(==)比较的是引用。但是在equals()方法中,实现取决于我们是否重写了equals方法,如果重写了equals方法,则它将根据重写方法中给出的实现来比较对象。

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//fasle
      obj==obj1 // fasle
    }
 }

在上述代码中,obj和obj1对象都包含相同的数据,但引用不同,因此equals方法返回false,==也是如此。 但是,如果我们重写了equals方法,则...
 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }
    public boolean equals(Object obj)
    {
       A a1=(A)obj;
      return this.id==a1.id;
    }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//true
      obj==obj1 // fasle
    }
 }

了解 check out(检查)它将仅针对我们覆盖的相同情况返回 true 和 false。

equals 方法。

它根据对象的内容(id)比较对象。

但是 == 仍然比较对象的引用。


3

需要注意的是,.equals() 方法通常包含 == 的测试,因为如果您想要测试两个对象是否相等,这是您希望测试的第一件事情。

而对于原始类型,== 实际上确实会查看值,但对于对象,它会检查引用。


2
public class StringPool {

public static void main(String[] args) {

    String s1 = "Cat";// will create reference in string pool of heap memory
    String s2 = "Cat";
    String s3 = new String("Cat");//will create a object in heap memory

    // Using == will give us true because same reference in string pool

    if (s1 == s2) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using == with reference and Object will give us False

    if (s1 == s3) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using .equals method which refers to value

    if (s1.equals(s3)) {
        System.out.println("true");
    } else {
        System.out.println("False");
    }

    }
  }

----输出----- 真 假 真


2
值得一提的是,对于基本类型的包装对象 - 即Int、Long、Double等 - 如果两个值相等,==将返回true。
Long a = 10L;
Long b = 10L;

if (a == b) {
    System.out.println("Wrapped primitives behave like values");
}

相比之下,将上述两个Long放入两个单独的ArrayList中,equals方法认为它们是相同的,但是==操作符不认为它们是相同的。
ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();

c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is true.");

基本类型的包装对象 - 即 Integer、Long、Double == 即使两个值相等,也可能不返回 true。它纯粹取决于包装器的缓存。下面的代码将打印 false,因为默认缓存限制为 -128 到 127。 Long a = 128l; Long b = 128l; System.out.println(a == b); - Neetesh Bhardwaj

2

== 可以用于许多对象类型,但是对于任何类型,特别是字符串和 Google 地图标记,都可以使用 Object.equals


1
由于Java不支持操作符重载,因此 == 对于每个对象都表现相同,但 equals()是一个可以在Java中被重写的方法,可以根据业务规则改变比较对象的逻辑。
Java中 == 和equals之间的主要区别在于“==”用于比较原始类型,而建议使用equals()方法来检查对象的相等性。
字符串比较是同时使用 == equals()方法的常见情况。由于java.lang.String类覆盖了equals方法,如果两个String对象包含相同的内容,则返回true,但 == 仅在两个引用指向同一对象时才返回true。
以下是在Java中使用 == equals()方法进行相等性比较的示例,这将消除一些疑惑。
 public class TEstT{

        public static void main(String[] args) {
            
    String text1 = new String("apple");
    String text2 = new String("apple");
          
    //since two strings are different object result should be false
    boolean result = text1 == text2;
    System.out.println("Comparing two strings with == operator: " + result);
          
    //since strings contains same content , equals() should return true
    result = text1.equals(text2);
    System.out.println("Comparing two Strings with same content using equals method: " + result);
          
    text2 = text1;
    //since both text2 and text1d reference variable are pointing to same object
    //"==" should return true
    result = (text1 == text2);
    System.out.println("Comparing two reference pointing to same String with == operator: " + result);

    }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接