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

发布于 2024-12-06 04:44:17 字数 124 浏览 2 评论 0原文

我想澄清一下我是否理解正确:

  • == 是引用比较,即两个对象都指向相同的内存位置
  • .equals() 计算值的比较在物体中

I wanted to clarify if I understand this correctly:

  • == is a reference comparison, i.e. both objects point to the same memory location
  • .equals() evaluates to the comparison of values in the objects

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

苹果你个爱泡泡 2024-12-13 04:44:18

可能值得补充的是,对于原始类型的包装对象 - 即 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.");

It may be worth adding that for wrapper objects for primitive types - i.e. Int, Long, Double - == will return true if the two values are equal.

Long a = 10L;
Long b = 10L;

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

To contrast, putting the above two Longs into two separate ArrayLists, equals sees them as the same, but == doesn't.

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.");
小忆控 2024-12-13 04:44:18

字符串池(又名实习)和整数池模糊进一步区别,并且可能允许您在某些情况下对对象使用 == 而不是 .equals

这可以为您提供更高的性能(?),但代价是更大的复杂性。

例如:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

复杂性权衡:以下内容可能会让您感到惊讶:

assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

我建议您远离此类微优化,并且始终对对象使用.equals,并且= = 对于原语:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);

The String pool (aka interning) and Integer pool blur the difference further, and may allow you to use == for objects in some cases instead of .equals

This can give you greater performance (?), at the cost of greater complexity.

E.g.:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

Complexity tradeoff: the following may surprise you:

assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

I advise you to stay away from such micro-optimization, and always use .equals for objects, and == for primitives:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);
ぺ禁宫浮华殁 2024-12-13 04:44:18

简而言之,答案是“是”。

在Java中,==运算符比较两个对象,看看它们是否指向相同的内存位置;而 .equals() 方法实际上是比较两个对象以查看它们是否具有相同的对象值。

In short, the answer is "Yes".

In Java, the == operator compares the two objects to see if they point to the same memory location; while the .equals() method actually compares the two objects to see if they have the same object value.

岁月染过的梦 2024-12-13 04:44:18

这是同一等价之间的区别。

a == b 表示 a 和 b 相同,也就是说,它们是内存中完全相同的对象的符号。

a.equals( b ) 意味着它们等价,它们是在某种意义上具有相同值的对象的符号——尽管这些对象可能占据不同的位置记忆。

请注意,对于等价性,如何评估和比较对象的问题就开始发挥作用——复杂的对象在实际用途中可能被视为等价的,即使它们的某些内容不同。有了身份,就不存在这样的问题了。

It is the difference between identity and equivalence.

a == b means that a and b are identical, that is, they are symbols for very same object in memory.

a.equals( b ) means that they are equivalent, that they are symbols for objects that in some sense have the same value -- although those objects may occupy different places in memory.

Note that with equivalence, the question of how to evaluate and compare objects comes into play -- complex objects may be regarded as equivalent for practical purposes even though some of their contents differ. With identity, there is no such question.

×纯※雪 2024-12-13 04:44:18

由于 Java 不支持运算符重载,因此 == 的行为相同
对于每个对象,除了 equals() 都是方法,可以在
Java和比较对象的逻辑可以根据业务进行更改
规则。

Java 中 == 和 equals 的主要区别在于 "==" 用于
比较原语,建议使用 equals() 方法进行检查
对象的平等性。

字符串比较是同时使用 ==equals() 方法的常见场景。由于 java.lang.String 类重写了 equals 方法,因此
如果两个 String 对象包含相同的内容,但 == 将返回 true
仅当两个引用指向同一对象时才返回 true。

这里是一个使用 ==equals() 方法比较 Java 中两个字符串是否相等的示例,这将消除一些疑虑:

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

    }
    }

Since Java doesn’t support operator overloading, == behaves identical
for every object but equals() is method, which can be overridden in
Java and logic to compare objects can be changed based upon business
rules.

Main difference between == and equals in Java is that "==" is used to
compare primitives while equals() method is recommended to check
equality of objects.

String comparison is a common scenario of using both == and equals() method. Since java.lang.String class override equals method, It
return true if two String object contains same content but == will
only return true if two references are pointing to same object.

Here is an example of comparing two Strings in Java for equality using == and equals() method which will clear some doubts:

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

    }
    }
揪着可爱 2024-12-13 04:44:18

基本上, == 比较两个对象在堆上是否具有相同的引用,因此除非两个引用链接到同一对象,否则此比较将为 false。

equals() 是从 Object 类继承的方法。默认情况下,此方法会比较两个对象是否具有相同的引用。这意味着:

object1.equals(object2) <=> object1 == object2

但是,如果您想在两个对象之间建立相等性对于同一类,您应该重写此方法。如果您已经重写了 equals(),那么重写方法 hashCode() 也非常重要。

当建立相等性是 Java 对象契约的一部分时,实现 hashCode()。如果您正在使用集合,并且尚未实现 hashCode(),则可能会发生奇怪的坏事情:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

如果您没有实现,则在执行前面的代码后将打印 null t 实现了hashCode()

Basically, == compares if two objects have the same reference on the heap, so unless two references are linked to the same object, this comparison will be false.

equals() is a method inherited from Object class. This method by default compares if two objects have the same referece. It means:

object1.equals(object2) <=> object1 == object2

However, if you want to establish equality between two objects of the same class you should override this method. It is also very important to override the method hashCode() if you have overriden equals().

Implement hashCode() when establishing equality is part of the Java Object Contract. If you are working with collections, and you haven't implemented hashCode(), Strange Bad Things could happen:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

null will be printed after executing the previous code if you haven't implemented hashCode().

末骤雨初歇 2024-12-13 04:44:18

简而言之,== 检查两个对象是否指向同一内存位置,而 .equals() 计算对象中值的比较。

In simple words, == checks if both objects point to the same memory location whereas .equals() evaluates to the comparison of values in the objects.

痴骨ら 2024-12-13 04:44:18

equals()方法主要是比较对象原来的内容。

如果我们 Write

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");

    System.out.println(s1.equals(s2));
    System.out.println(s2.equals(s3));
    System.out.println(s3.equals(s4));

输出将会是

true 
true 
true

因为 equals() 方法比较了对象的内容。
在第一个 System.out.println() 中,s1 和 s2 的内容相同,这就是它打印 true 的原因。
对于其他两个 System.out.println() 也是如此。

同样,

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");
    
    System.out.println(s1 == s2);
    System.out.println(s2 == s3);
    System.out.println(s3 == s4);

输出将是

true
false 
false

因为 == 运算符主要比较对象的引用而不是值。
在第一个 System.out.println() 中,s1 和 s2 的引用相同,这就是它返回 true 的原因。

在第二个System.out.println()中,创建了s3对象,这就是为什么会创建s3的另一个引用,并且s2和s3的引用会有所不同,因此它返回“false”。

第三个System.out.println(),遵循第二个System.out.println()的规则,这就是为什么它会返回“false”。

equals() method mainly compares the original content of the object.

If we Write

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");

    System.out.println(s1.equals(s2));
    System.out.println(s2.equals(s3));
    System.out.println(s3.equals(s4));

The output will be

true 
true 
true

Because equals() method compare the content of the object.
in first System.out.println() the content of s1 and s2 is same that's why it print true.
And it is same for others two System.out.println() is true.

Again ,

    String s1 = "Samim";
    String s2 = "Samim";
    String s3 = new String("Samim");
    String s4 = new String("Samim");
    
    System.out.println(s1 == s2);
    System.out.println(s2 == s3);
    System.out.println(s3 == s4);

The output will be

true
false 
false

Because == operator mainly compare the references of the object not the value.
In first System.out.println(), the references of s1 and s2 is same thats why it returns true.

In second System.out.println(), s3 object is created , thats why another reference of s3 will create , and the references of s2 and s3 will difference, for this reason it return "false".

Third System.out.println(), follow the rules of second System.out.println(), that's why it will return "false".

剑心龙吟 2024-12-13 04:44:18

在Java中,比较对象时,==和equals方法有不同的用途。以下是它们之间差异的简要说明以及示例:

== 运算符:
== 运算符用于引用比较。它检查两个引用是否指向内存中完全相同的对象。

示例:

String str1 = new String("Hello");
String str2 = new String("Hello");
String str3 = str1;

System.out.println(str1 == str2); // false (different objects)
System.out.println(str1 == str3); // true (same object)

在示例中,str1 和 str2 是具有相同内容的不同对象,但 == 返回 false,因为它检查引用相等性。 str3 与 str1 指向同一个对象,因此 str1 == str3 返回 true。

等于方法:
equals方法用于内容或值的比较。它旨在在自定义类中重写,以根据对象的内容提供有意义的比较。

示例:

String str1 = new String("Hello");
String str2 = new String("Hello");

System.out.println(str1.equals(str2)); // true (content-based comparison)

在此示例中,String 类中重写了 equals 来比较字符串的内容。因此,str1.equals(str2) 返回 true,因为字符串的内容相同。

In Java, == and the equals method are used for different purposes when comparing objects. Here's a brief explanation of the difference between them along with examples:

== Operator:
The == operator is used for reference comparison. It checks whether two references point to the exact same object in memory.

Example:

String str1 = new String("Hello");
String str2 = new String("Hello");
String str3 = str1;

System.out.println(str1 == str2); // false (different objects)
System.out.println(str1 == str3); // true (same object)

In the example, str1 and str2 are different objects with the same content, but == returns false because it checks for reference equality. str3 points to the same object as str1, so str1 == str3 returns true.

equals Method:
The equals method is used for content or value comparison. It is meant to be overridden in custom classes to provide a meaningful comparison based on the object's contents.

Example:

String str1 = new String("Hello");
String str2 = new String("Hello");

System.out.println(str1.equals(str2)); // true (content-based comparison)

In this example, equals is overridden in the String class to compare the content of the strings. Therefore, str1.equals(str2) returns true because the content of the strings is the same.

静谧 2024-12-13 04:44:17

一般来说,你的问题的答案是“是”,但是...

  • .equals(...) 只会比较它所写的比较,不多也不少。
  • 如果类没有重写 equals 方法,则它默认使用已重写此方法的最近父类的 equals(Object o) 方法。
  • 如果没有父类提供重写,则默认为最终父类 Object 中的方法,因此您只剩下 Object#equals(Object o) 方法。根据对象 API,这与 == 相同;也就是说,当且仅当两个变量引用同一个对象(且它们的引用相同)时,它才返回 true。因此,您将测试对象相等,而不是功能相等
  • 如果您覆盖 equals,请务必记住覆盖 hashCode,以免“违反合同”。根据 API,如果两个对象的 equals 方法显示它们是相同的,则从两个对象的 hashCode() 方法返回的结果必须相同相等的。反之则不一定成立。

In general, the answer to your question is "yes", but...

  • .equals(...) will only compare what it is written to compare, no more, no less.
  • If a class does not override the equals method, then it defaults to the equals(Object o) method of the closest parent class that has overridden this method.
  • If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality.
  • Always remember to override hashCode if you override equals so as not to "break the contract". As per the API, the result returned from the hashCode() method for two objects must be the same if their equals methods show that they are equivalent. The converse is not necessarily true.
梦屿孤独相伴 2024-12-13 04:44:17

对于 String 类:

equals() 方法比较 String 实例内部(在堆上)的“值”,无论两个对象引用是否引用同一个 String 实例。如果任意两个 String 类型的对象引用引用同一个 String 实例,那就太好了!如果两个对象引用引用两个不同的 String 实例..它没有什么区别。它是正在比较的每个 String 实例内的“值”(即:字符数组的内容)。

另一方面,“==”运算符比较两个对象引用的值,看看它们是否引用同一个String实例。如果两个对象引用的值“引用”同一个 String 实例,则布尔表达式的结果将为“true”..duh。另一方面,如果两个对象引用的值“引用”不同的 String 实例(即使两个 String 实例具有相同的“值”,即每个 String 实例的字符数组的内容)字符串实例相同)布尔表达式的结果将为“false”。

与任何解释一样,让它深入人心。

我希望这能让事情变得更清楚。

With respect to the String class:

The equals() method compares the "value" inside String instances (on the heap) irrespective if the two object references refer to the same String instance or not. If any two object references of type String refer to the same String instance then great! If the two object references refer to two different String instances .. it doesn't make a difference. Its the "value" (that is: the contents of the character array) inside each String instance that is being compared.

On the other hand, the "==" operator compares the value of two object references to see whether they refer to the same String instance. If the value of both object references "refer to" the same String instance then the result of the boolean expression would be "true"..duh. If, on the other hand, the value of both object references "refer to" different String instances (even though both String instances have identical "values", that is, the contents of the character arrays of each String instance are the same) the result of the boolean expression would be "false".

As with any explanation, let it sink in.

I hope this clears things up a bit.

尘曦 2024-12-13 04:44:17

根据您谈论的是“基元”还是“对象类型”,存在一些细微的差异;如果您谈论“静态”或“非静态”成员,也可以这样说;你也可以混合以上所有...

这是一个例子(你可以运行它):

public final class MyEqualityTest
{
    public static void main( String args[] )
    {
        String s1 = new String( "Test" );
        String s2 = new String( "Test" );

        System.out.println( "\n1 - PRIMITIVES ");
        System.out.println( s1 == s2 ); // false
        System.out.println( s1.equals( s2 )); // true

        A a1 = new A();
        A a2 = new A();

        System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
        System.out.println( a1 == a2 ); // false
        System.out.println( a1.s == a2.s ); // true
        System.out.println( a1.s.equals( a2.s ) ); // true

        B b1 = new B();
        B b2 = new B();

        System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
        System.out.println( b1 == b2 ); // false
        System.out.println( b1.getS() == b2.getS() ); // false
        System.out.println( b1.getS().equals( b2.getS() ) ); // true
    }
}

final class A
{
    // static
    public static String s;
    A()
    {
        this.s = new String( "aTest" );
    }
}

final class B
{
    private String s;
    B()
    {
        this.s = new String( "aTest" );
    }

    public String getS()
    {
        return s;
    }

}

你可以比较“==”(相等运算符)和“.equals(...)”(java中的方法)的解释.lang.Object 类)通过这些链接:

There are some small differences depending whether you are talking about "primitives" or "Object Types"; the same can be said if you are talking about "static" or "non-static" members; you can also mix all the above...

Here is an example (you can run it):

public final class MyEqualityTest
{
    public static void main( String args[] )
    {
        String s1 = new String( "Test" );
        String s2 = new String( "Test" );

        System.out.println( "\n1 - PRIMITIVES ");
        System.out.println( s1 == s2 ); // false
        System.out.println( s1.equals( s2 )); // true

        A a1 = new A();
        A a2 = new A();

        System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
        System.out.println( a1 == a2 ); // false
        System.out.println( a1.s == a2.s ); // true
        System.out.println( a1.s.equals( a2.s ) ); // true

        B b1 = new B();
        B b2 = new B();

        System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
        System.out.println( b1 == b2 ); // false
        System.out.println( b1.getS() == b2.getS() ); // false
        System.out.println( b1.getS().equals( b2.getS() ) ); // true
    }
}

final class A
{
    // static
    public static String s;
    A()
    {
        this.s = new String( "aTest" );
    }
}

final class B
{
    private String s;
    B()
    {
        this.s = new String( "aTest" );
    }

    public String getS()
    {
        return s;
    }

}

You can compare the explanations for "==" (Equality Operator) and ".equals(...)" (method in the java.lang.Object class) through these links:

画离情绘悲伤 2024-12-13 04:44:17

==equals 之间的区别让我困惑了一段时间,直到我决定仔细研究它。
他们中的许多人说,为了比较字符串,您应该使用 equals 而不是 ==。希望在这个答案中我能够说出区别。

回答这个问题的最好方法是问自己几个问题。那么让我们开始吧:

以下程序的输出是什么:

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

如果你说,

false
true

我会说你是对的但是你为什么这么说
如果你说输出是,

true
false

我会说你错了,但我仍然会问你,为什么你认为这是对的?

好吧,让我们尝试回答这个问题:

以下程序的输出是什么:

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

现在如果你说,

false
true

我会说你错了但是为什么会这样现在错了?
该程序的正确输出是

true
false

请比较上面的程序并尝试思考它。

好的。现在这可能会有所帮助(请阅读以下内容:打印对象的地址 - 不可能,但我们仍然可以使用它。)

String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);
 
System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));

您可以尝试考虑一下上面代码中最后三行的输出:
对我来说 ideone 打印了这个(你可以在这里查看代码):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

哦!现在您看到identityHashCode(mango) 等于identityHashCode(mango2) 但它不等于identityHashCode(mango3)

即使所有字符串变量 - mango、mango2 和 mango3 - 都有 相同值,即“芒果”,identityHashCode()对于所有人来说仍然不一样。

现在尝试取消注释此行 // mango2 = "mang"; 并再次运行它,这次您将看到所有三个 identityHashCode() 都不同。
嗯,这是一个有用的提示,

我们知道如果 hashcode(x)=Nhashcode(y)=N => x 等于 y

我不确定 java 内部是如何工作的,但我假设这就是当我说:

mango = "mango";

java 创建了一个被指向的字符串 "mango" 时发生的情况(引用)由变量mango这样的东西

mango ----> "mango"

现在在下一行,当我说:

mango2 = "mango";

它实际上重用了相同的字符串“mango”,它看起来像这样

mango ----> "mango" <---- mango2

Mango和mango2都指向到相同的参考
现在,当我说它

mango3 = new String("mango")

实际上为“芒果”创建了一个全新的引用(字符串)。看起来像这样,

mango -----> "mango" <------ mango2

mango3 ------> "mango"

这就是为什么当我输出 mango == mango2 的值时,它输出 true。当我输出 mango3 == mango2 的值时,它输出 false (即使值相同)。

当您取消注释行 // mango2 = "mang";
它实际上创建了一个字符串“mang”,它使我们的图表变成这样:

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

这就是为什么identityHashCode对于所有人来说都不相同的原因。

希望这对你们有帮助。
实际上,我想生成一个测试用例,其中 == 失败而 equals() 通过。
如果我错了,请随时发表评论并告诉我。

The difference between == and equals confused me for sometime until I decided to have a closer look at it.
Many of them say that for comparing string you should use equals and not ==. Hope in this answer I will be able to say the difference.

The best way to answer this question will be by asking a few questions to yourself. so let's start:

What is the output for the below program:

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

if you say,

false
true

I will say you are right but why did you say that?
and If you say the output is,

true
false

I will say you are wrong but I will still ask you, why you think that is right?

Ok, Let's try to answer this one:

What is the output for the below program:

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

Now If you say,

false
true

I will say you are wrong but why is it wrong now?
the correct output for this program is

true
false

Please compare the above program and try to think about it.

Ok. Now this might help (please read this : print the address of object - not possible but still we can use it.)

String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);
 
System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));

can you just try to think about the output of the last three lines in the code above:
for me ideone printed this out (you can check the code here):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

Oh! Now you see the identityHashCode(mango) is equal to identityHashCode(mango2) But it is not equal to identityHashCode(mango3)

Even though all the string variables - mango, mango2 and mango3 - have the same value, which is "mango", identityHashCode() is still not the same for all.

Now try to uncomment this line // mango2 = "mang"; and run it again this time you will see all three identityHashCode() are different.
Hmm that is a helpful hint

we know that if hashcode(x)=N and hashcode(y)=N => x is equal to y

I am not sure how java works internally but I assume this is what happened when I said:

mango = "mango";

java created a string "mango" which was pointed(referenced) by the variable mango something like this

mango ----> "mango"

Now in the next line when I said:

mango2 = "mango";

It actually reused the same string "mango" which looks something like this

mango ----> "mango" <---- mango2

Both mango and mango2 pointing to the same reference
Now when I said

mango3 = new String("mango")

It actually created a completely new reference(string) for "mango". which looks something like this,

mango -----> "mango" <------ mango2

mango3 ------> "mango"

and that's why when I put out the values for mango == mango2, it put out true. and when I put out the value for mango3 == mango2, it put out false (even when the values were the same).

and when you uncommented the line // mango2 = "mang";
It actually created a string "mang" which turned our graph like this:

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

This is why the identityHashCode is not the same for all.

Hope this helps you guys.
Actually, I wanted to generate a test case where == fails and equals() pass.
Please feel free to comment and let me know If I am wrong.

做个少女永远怀春 2024-12-13 04:44:17

== 运算符测试两个变量是否具有相同的引用
(又名指向内存地址的指针)

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (objects are identical but not same)

bar = foo;

if(foo==bar)
// True (Now, objects are identical and same)

equals()方法测试两个变量是否引用对象
具有相同的状态(值)

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

The == operator tests whether two variables have the same references
(aka pointer to a memory address)
.

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (objects are identical but not same)

bar = foo;

if(foo==bar)
// True (Now, objects are identical and same)

Whereas the equals() method tests whether two variables refer to objects
that have the same state (values).

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)
烈酒灼喉 2024-12-13 04:44:17

您必须重写 equals 函数(以及其他函数)才能将其与自定义类一起使用。

equals 方法比较对象。

== 二元运算符比较内存地址。

You will have to override the equals function (along with others) to use this with custom classes.

The equals method compares the objects.

The == binary operator compares memory addresses.

随遇而安 2024-12-13 04:44:17

== 是一个运算符equals() 是一个方法

运算符通常用于原始类型比较,因此==用于内存地址比较,equals()方法用于比较 >对象

== is an operator and equals() is a method.

Operators are generally used for primitive type comparisons and thus == is used for memory address comparison and equals() method is used for comparing objects.

请叫√我孤独 2024-12-13 04:44:17
 String w1 ="Sarat";
 String w2 ="Sarat";
 String w3 = new String("Sarat");

 System.out.println(w1.hashCode());   //3254818
 System.out.println(w2.hashCode());   //3254818
 System.out.println(w3.hashCode());   //3254818

 System.out.println(System.identityHashCode(w1)); //prints 705927765
 System.out.println(System.identityHashCode(w2)); //prints 705927765
 System.out.println(System.identityHashCode(w3)); //prints 366712642


 if(w1==w2)   //  (705927765==705927765)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true

 if(w2==w3)   //  (705927765==366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints false


 if(w2.equals(w3))   //  (Content of 705927765== Content of 366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true
 String w1 ="Sarat";
 String w2 ="Sarat";
 String w3 = new String("Sarat");

 System.out.println(w1.hashCode());   //3254818
 System.out.println(w2.hashCode());   //3254818
 System.out.println(w3.hashCode());   //3254818

 System.out.println(System.identityHashCode(w1)); //prints 705927765
 System.out.println(System.identityHashCode(w2)); //prints 705927765
 System.out.println(System.identityHashCode(w3)); //prints 366712642


 if(w1==w2)   //  (705927765==705927765)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true

 if(w2==w3)   //  (705927765==366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints false


 if(w2.equals(w3))   //  (Content of 705927765== Content of 366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true
阳光下的泡沫是彩色的 2024-12-13 04:44:17

如果您不重写 .equals(),则 == 和 .equals() 都引用同一个对象。

一旦你重写 .equals(),你想要做什么就是你的愿望。您可以将调用对象的状态与传入对象的状态进行比较,也可以只调用 super.equals()

Both == and .equals() refers to the same object if you don't override .equals().

Its your wish what you want to do once you override .equals(). You can compare the invoking object's state with the passed in object's state or you can just call super.equals()

浮生未歇 2024-12-13 04:44:17

这里是关于关系运算符 ==方法 .equals() 之间差异的一般规则。 /strong>.

object1 == object2 比较 object1 和 object2 引用的对象是否引用堆中的相同内存位置。

object1.equals(object2) 比较object1 和object2 的值,无论它们位于内存中的位置

可以很好地证明这一点。

使用字符串场景1

 public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = new String("Hello");
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

 }



The result is
      is str1 == str2 ? false
      is str1.equals(str2) ? true 

场景2

public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = "Hello";
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

}

The result is 
  is str1 == str2 ? true
  is str1.equals(str2) ? true

该字符串比较可以用作比较其他类型对象的基础。

例如,如果我有一个 Person 类,我需要定义比较两个人的标准。假设这个 person 类有身高和体重的实例变量。

因此创建 person 对象 person1 和 person2 并使用 .equals() 比较这两个对象 code> 我需要重写 person 类的 equals 方法 来定义基于哪些实例变量(身高或体重)进行比较。

但是,== 运算符仍会根据两个对象(person1 和 person2)的内存位置返回结果

为了便于概括此人对象比较,我创建了以下测试类。 对这些概念进行实验将揭示大量事实

package com.tadtab.CS5044;

public class Person {

private double height;
private double weight;

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}


@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(height);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}

@Override
/**
 * This method uses the height as a means of comparing person objects.
 * NOTE: weight is not part of the comparison criteria
 */
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
        return false;
    return true;
}

public static void main(String[] args) {
    
    Person person1 = new Person();
    person1.setHeight(5.50);
    person1.setWeight(140.00);
    
    Person person2 = new Person();
    person2.setHeight(5.70);
    person2.setWeight(160.00);
    
    Person person3 = new Person();
    person3 = person2;
    
    Person person4 = new Person();
    person4.setHeight(5.70);
    
    Person person5 = new Person();
    person5.setWeight(160.00);
    
    System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
    System.out.println("is person2 == person3 ? " + (person2 == person3)); // true 
    //this is because perosn3 and person to refer to the one person object in memory. They are aliases;
    System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;
    
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;
    
    // even if the person2 and person5 have the same weight, they are not equal.
    // it is because their height is different
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}

}

该类的执行结果为:

is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false

Here is a general thumb of rule for the difference between relational operator == and the method .equals().

object1 == object2 compares if the objects referenced by object1 and object2 refer to the same memory location in Heap.

object1.equals(object2) compares the values of object1 and object2 regardless of where they are located in memory.

This can be demonstrated well using String

Scenario 1

 public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = new String("Hello");
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

 }



The result is
      is str1 == str2 ? false
      is str1.equals(str2) ? true 

Scenario 2

public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = "Hello";
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

}

The result is 
  is str1 == str2 ? true
  is str1.equals(str2) ? true

This string comparison could be used as a basis for comparing other types of object.

For instance if I have a Person class, I need to define the criteria base on which I will compare two persons. Let's say this person class has instance variables of height and weight.

So creating person objects person1 and person2 and for comparing these two using the .equals() I need to override the equals method of the person class to define based on which instance variables(heigh or weight) the comparison will be.

However, the == operator will still return results based on the memory location of the two objects(person1 and person2).

For ease of generalizing this person object comparison, I have created the following test class. Experimenting on these concepts will reveal tons of facts.

package com.tadtab.CS5044;

public class Person {

private double height;
private double weight;

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}


@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(height);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}

@Override
/**
 * This method uses the height as a means of comparing person objects.
 * NOTE: weight is not part of the comparison criteria
 */
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
        return false;
    return true;
}

public static void main(String[] args) {
    
    Person person1 = new Person();
    person1.setHeight(5.50);
    person1.setWeight(140.00);
    
    Person person2 = new Person();
    person2.setHeight(5.70);
    person2.setWeight(160.00);
    
    Person person3 = new Person();
    person3 = person2;
    
    Person person4 = new Person();
    person4.setHeight(5.70);
    
    Person person5 = new Person();
    person5.setWeight(160.00);
    
    System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
    System.out.println("is person2 == person3 ? " + (person2 == person3)); // true 
    //this is because perosn3 and person to refer to the one person object in memory. They are aliases;
    System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;
    
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;
    
    // even if the person2 and person5 have the same weight, they are not equal.
    // it is because their height is different
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}

}

Result of this class execution is:

is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false
恋竹姑娘 2024-12-13 04:44:17

请记住 .equals(...) 必须由您要比较的类实现。否则,就没有什么意义了; Object 类的方法版本与比较操作执行相同的操作: 对象#equals

您真正想要对对象使用比较运算符的唯一时间是在比较枚举时。这是因为 Enum 值一次只有一个实例。例如,给定枚举,

enum FooEnum {A, B, C}

您永远不会同时拥有多个 A 实例,对于 BC 也是如此。这意味着您实际上可以编写如下方法:

public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

而且您不会有任何问题。

Just remember that .equals(...) has to be implemented by the class you are trying to compare. Otherwise, there isn't much of a point; the version of the method for the Object class does the same thing as the comparison operation: Object#equals.

The only time you really want to use the comparison operator for objects is wen you are comparing Enums. This is because there is only one instance of an Enum value at a time. For instance, given the enum

enum FooEnum {A, B, C}

You will never have more than one instance of A at a time, and the same for B and C. This means that you can actually write a method like so:

public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

And you will have no problems whatsoever.

深海少女心 2024-12-13 04:44:17

当你评估代码时,很明显,(==)根据内存地址进行比较,而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
    */

When you evaluate the code, it is very clear that (==) compares according to memory address, while equals(Object o) compares hashCode() of the instances.
That's why it is said do not break the contract between equals() and hashCode() if you do not face surprises later.

    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
    */
子栖 2024-12-13 04:44:17

== 和 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

The major difference between == and equals() is

1) == is used to compare primitives.

For example :

        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() is used to compare objects.
For example :

        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
—━☆沉默づ 2024-12-13 04:44:17

示例 1 -

== 和 .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
     }    
}

在此处输入图像描述

示例 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
     }
}

在此处输入图像描述

示例 3 -

如果是字符串,则有一个更多用例。这里,当我们将任何字符串分配给 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
     }
}

输入图片description here

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

Java API 等于() 方法契约

Example 1 -

Both == and .equals methods are there for reference comparison only. It means whether both objects are referring to same object or not.

Object class equals method implementation

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

Example 2 -

But if we wants to compare objects content using equals method then class has to override object's class equals() method and provide implementation for content comparison. Here, String class has overrided equals method for content comparison. All wrapper classes have overrided equals method for content comparison.

String class equals method implementation

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

Example 3 -

In case of String, there is one more usecase. Here when we assign any string to String reference then string constant is created inside String constant pool. If we assign same string to new String reference then no new string constant is created rather it will refer to existing string constant.

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

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

Java API equals() method contract

┼── 2024-12-13 04:44:17

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

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

Also note that .equals() normally contains == for testing as this is the first thing you would wish to test for if you wanted to test if two objects are equal.

And == actually does look at values for primitive types, for objects it checks the reference.

晚风撩人 2024-12-13 04:44:17

== 运算符总是比较引用。但如果是

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

知道检查它会返回 true 和 false 对于相同的情况只有我们重写

等于方法。

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

但是==

仍然比较对象的引用。

== operator always reference is compared. But in case of

equals() method

it's depends's on implementation if we are overridden equals method than it compares object on basic of implementation given in overridden method.

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

in above code both obj and obj1 object contains same data but reference is not same so equals return false and == also.
but if we overridden equals method than

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

know check out it will return true and false for same case only we overridden

equals method .

it compare object on basic of content(id) of object

but ==

still compare references of object.

梦里°也失望 2024-12-13 04:44:17

== 可用于许多对象类型,但您可以将 Object.equals 用于任何类型,尤其是字符串和 Google 地图标记。

== can be used in many object types but you can use Object.equals for any type , especially Strings and Google Map Markers.

神经暖 2024-12-13 04:44:17
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");
    }

    }
  }

- - 输出 - - -
真的
错误的
真的

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

    }
  }

----Output-----
true
false
true

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文