Java 中 == 和 equals() 有什么区别?
我想澄清一下我是否理解正确:
==
是引用比较,即两个对象都指向相同的内存位置.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(27)
可能值得补充的是,对于原始类型的包装对象 - 即 Int、Long、Double - 如果两个值相等,== 将返回 true。
相比之下,将上述两个 Long 放入两个单独的 ArrayList 中, equals 认为它们是相同的,但 == 则不然。
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.
To contrast, putting the above two Longs into two separate ArrayLists, equals sees them as the same, but == doesn't.
字符串池(又名实习)和整数池模糊进一步区别,并且可能允许您在某些情况下对对象使用
==
而不是.equals
这可以为您提供更高的性能(?),但代价是更大的复杂性。
例如:
复杂性权衡:以下内容可能会让您感到惊讶:
我建议您远离此类微优化,并且始终对对象使用
.equals
,并且= =
对于原语: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.:
Complexity tradeoff: the following may surprise you:
I advise you to stay away from such micro-optimization, and always use
.equals
for objects, and==
for primitives:简而言之,答案是“是”。
在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.这是同一和等价之间的区别。
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.
由于 Java 不支持运算符重载,因此
==
的行为相同对于每个对象,除了
equals()
都是方法,可以在Java和比较对象的逻辑可以根据业务进行更改
规则。
Java 中
==
和 equals 的主要区别在于"=="
用于比较原语,建议使用
equals()
方法进行检查对象的平等性。
字符串比较是同时使用
==
和equals()
方法的常见场景。由于 java.lang.String 类重写了 equals 方法,因此如果两个 String 对象包含相同的内容,但
==
将返回 true仅当两个引用指向同一对象时才返回 true。
这里是一个使用
==
和equals()
方法比较 Java 中两个字符串是否相等的示例,这将消除一些疑虑:Since Java doesn’t support operator overloading,
==
behaves identicalfor every object but
equals()
is method, which can be overridden inJava and logic to compare objects can be changed based upon business
rules.
Main difference between
==
and equals in Java is that"=="
is used tocompare primitives while
equals()
method is recommended to checkequality of objects.
String comparison is a common scenario of using both
==
andequals()
method. Since java.lang.String class override equals method, Itreturn true if two String object contains same content but
==
willonly return true if two references are pointing to same object.
Here is an example of comparing two Strings in Java for equality using
==
andequals()
method which will clear some doubts:基本上,
==
比较两个对象在堆上是否具有相同的引用,因此除非两个引用链接到同一对象,否则此比较将为 false。equals()
是从Object
类继承的方法。默认情况下,此方法会比较两个对象是否具有相同的引用。这意味着:object1.equals(object2)
<=>object1 == object2
但是,如果您想在两个对象之间建立相等性对于同一类,您应该重写此方法。如果您已经重写了
equals()
,那么重写方法hashCode()
也非常重要。当建立相等性是 Java 对象契约的一部分时,实现
hashCode()
。如果您正在使用集合,并且尚未实现hashCode()
,则可能会发生奇怪的坏事情:如果您没有实现,则在执行前面的代码后将打印
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 fromObject
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 overridenequals()
.Implement
hashCode()
when establishing equality is part of the Java Object Contract. If you are working with collections, and you haven't implementedhashCode()
, Strange Bad Things could happen:null
will be printed after executing the previous code if you haven't implementedhashCode()
.简而言之,
==
检查两个对象是否指向同一内存位置,而.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.equals()方法主要是比较对象原来的内容。
如果我们 Write
输出将会是
因为 equals() 方法比较了对象的内容。
在第一个 System.out.println() 中,s1 和 s2 的内容相同,这就是它打印 true 的原因。
对于其他两个 System.out.println() 也是如此。
同样,
输出将是
因为 == 运算符主要比较对象的引用而不是值。
在第一个 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
The output will be
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 ,
The output will be
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".
在Java中,比较对象时,==和equals方法有不同的用途。以下是它们之间差异的简要说明以及示例:
== 运算符:
== 运算符用于引用比较。它检查两个引用是否指向内存中完全相同的对象。
示例:
在示例中,str1 和 str2 是具有相同内容的不同对象,但 == 返回 false,因为它检查引用相等性。 str3 与 str1 指向同一个对象,因此 str1 == str3 返回 true。
等于方法:
equals方法用于内容或值的比较。它旨在在自定义类中重写,以根据对象的内容提供有意义的比较。
示例:
在此示例中,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:
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:
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.
一般来说,你的问题的答案是“是”,但是...
.equals(...)
只会比较它所写的比较,不多也不少。equals(Object o)
方法。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.equals(Object o)
method of the closest parent class that has overridden this method.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.hashCode
if you overrideequals
so as not to "break the contract". As per the API, the result returned from thehashCode()
method for two objects must be the same if theirequals
methods show that they are equivalent. The converse is not necessarily true.对于 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.
根据您谈论的是“基元”还是“对象类型”,存在一些细微的差异;如果您谈论“静态”或“非静态”成员,也可以这样说;你也可以混合以上所有...
这是一个例子(你可以运行它):
你可以比较“==”(相等运算符)和“.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):
You can compare the explanations for "==" (Equality Operator) and ".equals(...)" (method in the java.lang.Object class) through these links:
==
和equals
之间的区别让我困惑了一段时间,直到我决定仔细研究它。他们中的许多人说,为了比较字符串,您应该使用
equals
而不是==
。希望在这个答案中我能够说出区别。回答这个问题的最好方法是问自己几个问题。那么让我们开始吧:
以下程序的输出是什么:
如果你说,
我会说你是对的但是你为什么这么说 ?
如果你说输出是,
我会说你错了,但我仍然会问你,为什么你认为这是对的?
好吧,让我们尝试回答这个问题:
以下程序的输出是什么:
现在如果你说,
我会说你错了但是为什么会这样现在错了?
该程序的正确输出是
请比较上面的程序并尝试思考它。
好的。现在这可能会有所帮助(请阅读以下内容:打印对象的地址 - 不可能,但我们仍然可以使用它。)
您可以尝试考虑一下上面代码中最后三行的输出:
对我来说 ideone 打印了这个(你可以在这里查看代码):
哦!现在您看到identityHashCode(mango) 等于identityHashCode(mango2) 但它不等于identityHashCode(mango3)
即使所有字符串变量 - mango、mango2 和 mango3 - 都有 相同值,即“芒果”,
identityHashCode()
对于所有人来说仍然不一样。现在尝试取消注释此行
// mango2 = "mang";
并再次运行它,这次您将看到所有三个identityHashCode()
都不同。嗯,这是一个有用的提示,
我们知道如果
hashcode(x)=N
和hashcode(y)=N
=>x 等于 y
我不确定 java 内部是如何工作的,但我假设这就是当我说:
java 创建了一个被指向的字符串
"mango"
时发生的情况(引用)由变量mango
这样的东西现在在下一行,当我说:
它实际上重用了相同的字符串
“mango”
,它看起来像这样Mango和mango2都指向到相同的参考
现在,当我说它
实际上为“芒果”创建了一个全新的引用(字符串)。看起来像这样,
这就是为什么当我输出
mango == mango2
的值时,它输出true
。当我输出mango3 == mango2
的值时,它输出false
(即使值相同)。当您取消注释行
// mango2 = "mang";
它实际上创建了一个字符串“mang”,它使我们的图表变成这样:
这就是为什么identityHashCode对于所有人来说都不相同的原因。
希望这对你们有帮助。
实际上,我想生成一个测试用例,其中
==
失败而equals()
通过。如果我错了,请随时发表评论并告诉我。
The difference between
==
andequals
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:
if you say,
I will say you are right but why did you say that?
and If you say the output is,
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:
Now If you say,
I will say you are wrong but why is it wrong now?
the correct output for this program is
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.)
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):
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 threeidentityHashCode()
are different.Hmm that is a helpful hint
we know that if
hashcode(x)=N
andhashcode(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:
java created a string
"mango"
which was pointed(referenced) by the variablemango
something like thisNow in the next line when I said:
It actually reused the same string
"mango"
which looks something like thisBoth mango and mango2 pointing to the same reference
Now when I said
It actually created a completely new reference(string) for "mango". which looks something like this,
and that's why when I put out the values for
mango == mango2
, it put outtrue
. and when I put out the value formango3 == mango2
, it put outfalse
(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:
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 andequals()
pass.Please feel free to comment and let me know If I am wrong.
您必须重写 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.==
是一个运算符,equals()
是一个方法。运算符通常用于原始类型比较,因此
==
用于内存地址比较,equals()
方法用于比较 >对象。==
is an operator andequals()
is a method.Operators are generally used for primitive type comparisons and thus
==
is used for memory address comparison andequals()
method is used for comparing objects.如果您不重写 .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()
这里是关于
关系运算符 ==
和方法 .equals()
之间差异的一般规则。 /strong>.object1 == object2
比较 object1 和 object2 引用的对象是否引用堆中的相同内存位置。object1.equals(object2)
比较object1 和object2 的值,无论它们位于内存中的位置。可以很好地证明这一点。
使用字符串场景1
场景2
该字符串比较可以用作比较其他类型对象的基础。
例如,如果我有一个 Person 类,我需要定义比较两个人的标准。假设这个 person 类有身高和体重的实例变量。
因此创建 person 对象
person1 和 person2
并使用.equals()
比较这两个对象 code> 我需要重写 person 类的 equals 方法 来定义基于哪些实例变量(身高或体重)进行比较。但是,
== 运算符仍会根据两个对象(person1 和 person2)的内存位置返回结果
。为了便于概括此人对象比较,我创建了以下测试类。 对这些概念进行实验将揭示大量事实。
该类的执行结果为:
Here is a general thumb of rule for the difference between
relational operator ==
andthe 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
Scenario 2
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.
Result of this class execution is:
请记住
.equals(...)
必须由您要比较的类实现。否则,就没有什么意义了; Object 类的方法版本与比较操作执行相同的操作: 对象#equals。您真正想要对对象使用比较运算符的唯一时间是在比较枚举时。这是因为 Enum 值一次只有一个实例。例如,给定枚举,
您永远不会同时拥有多个
A
实例,对于B
和C
也是如此。这意味着您实际上可以编写如下方法:而且您不会有任何问题。
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
You will never have more than one instance of
A
at a time, and the same forB
andC
. This means that you can actually write a method like so:And you will have no problems whatsoever.
当你评估代码时,很明显,(==)根据内存地址进行比较,而equals(Object o)则比较实例的hashCode()。
这就是为什么说如果你以后不会遇到意外,就不要破坏 equals() 和 hashCode() 之间的契约。
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.
== 和 equals() 之间的主要区别是
1) == 用于比较基元。
例如:
2) equals() 用于比较对象。
例如 :
The major difference between == and equals() is
1) == is used to compare primitives.
For example :
2) equals() is used to compare objects.
For example :
示例 1 -
== 和 .equals 方法仅供参考比较。这意味着两个对象是否引用同一个对象。
对象类等于方法实现
示例 2 -
但是如果我们想使用 equals 方法比较对象内容,则类必须覆盖对象的内容类 equals() 方法并提供内容比较的实现。这里,String类重写了equals方法来进行内容比较。所有包装类都重写了 equals 方法来进行内容比较。
String类equals方法实现
示例 3 -
如果是字符串,则有一个更多用例。这里,当我们将任何字符串分配给 String 引用时,就会在字符串常量池中创建字符串常量。如果我们将相同的字符串分配给新的字符串引用,则不会创建新的字符串常量,而是会引用现有的字符串常量。
请注意,每当重写 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
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
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.
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
另请注意,
.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.== 运算符总是比较引用。但如果是
如果我们重写 equals 方法,它取决于实现,而不是根据重写方法中给出的实现的基础来比较对象。
在上面的代码中, obj 和 obj1 对象都包含相同的数据,但引用不同,因此 equals 返回 false 且 == 也返回。
但是如果我们重写 equals 方法而不是
知道检查它会返回 true 和 false 对于相同的情况只有我们重写
它根据对象的内容(id)来比较对象
仍然比较对象的引用。
== operator always reference is compared. But in case of
it's depends's on implementation if we are overridden equals method than it compares object on basic of implementation given in overridden method.
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
know check out it will return true and false for same case only we overridden
it compare object on basic of content(id) of object
still compare references of object.
==
可用于许多对象类型,但您可以将Object.equals
用于任何类型,尤其是字符串和 Google 地图标记。==
can be used in many object types but you can useObject.equals
for any type , especially Strings and Google Map Markers.- - 输出 - - -
真的
错误的
真的
----Output-----
true
false
true