提问人:brainydexter 提问时间:9/23/2011 最后编辑:brainydexter 更新时间:4/13/2023 访问量:800080
Java 中的 == 和 equals() 有什么区别?
What is the difference between == and equals() in Java?
答:
一般来说,你的问题的答案是“是”,但是......
.equals(...)
只会比较它所写的东西来比较,不多也不少。- 如果某个类不重写 equals 方法,则它默认为重写此方法的最接近的父类的方法。
equals(Object o)
- 如果没有父类提供重写,则默认为最终父类 Object 中的方法,因此只剩下该方法。根据对象 API,这与 ;也就是说,当且仅当两个变量都引用同一对象时,当且仅当它们的引用是相同的时,它才会返回 true。因此,您将测试对象相等性,而不是功能相等性。
Object#equals(Object o)
==
- 如果覆盖,请始终记住覆盖,以免“破坏合同”。根据 API,如果两个对象的方法显示它们是等效的,则从两个对象的方法返回的结果必须相同。反之则不一定正确。
hashCode
equals
hashCode()
equals
评论
==
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
<br/> (docs.oracle.com/javase/7/docs/api/java/lang/...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.
)
您必须重写 equals 函数(以及其他函数)才能将其与自定义类一起使用。
equals 方法比较对象。
二进制运算符比较内存地址。==
如果您不覆盖 .equals(),则 == 和 .equals() 都引用同一个对象。
这是你的愿望,一旦你覆盖了.equals(),你想做什么。您可以将调用对象的状态与传入对象的状态进行比较,也可以直接调用 super.equals()
请记住,这必须由您尝试比较的类实现。否则,就没有多大意义了;Object 类的方法版本执行与比较操作相同的操作:Object#equals。.equals(...)
您真正想要对对象使用比较运算符的唯一时间是温您正在比较枚举。这是因为一次只有一个枚举值实例。例如,给定枚举
enum FooEnum {A, B, C}
一次永远不会有多个实例,并且 和 相同。这意味着您实际上可以编写如下方法:A
B
C
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
而且你不会有任何问题。
关于 String 类:
equals() 方法比较 String 实例(在堆上)中的“值”,而不管两个对象引用是否引用同一个 String 实例。如果 String 类型的任意两个对象引用引用同一个 String 实例,那就太好了!如果两个对象引用引用两个不同的 String 实例。这没什么区别。它是要比较的每个 String 实例中的“值”(即:字符数组的内容)。
另一方面,“==”运算符比较两个对象引用的值,以查看它们是否引用同一个 String 实例。如果两个对象的值都引用“引用”同一个 String 实例,则布尔表达式的结果将为“true”。咄。另一方面,如果两个对象引用的值“引用”不同的 String 实例(即使两个 String 实例具有相同的“值”,即每个 String 实例的字符数组的内容相同),则布尔表达式的结果将为“false”。
与任何解释一样,让它沉入其中。
我希望这能把事情弄清楚一点。
评论
String
==
String
==
String
String
String constant pool
String s1 = "someString"; String s2 = "someString;"
s1
s2
s1 == s2
String constructor
String s1 = new String("someString"); String s2 = new String("someString");
s1 == s2
==
是一个运算符,也是一个方法。equals()
运算符通常用于基元类型比较,因此用于内存地址比较,方法用于比较对象。==
equals()
评论
根据您谈论的是“基元”还是“对象类型”,存在一些细微的差异;如果您谈论的是“静态”或“非静态”成员,也可以这样说;您也可以混合上述所有内容...
下面是一个示例(您可以运行它):
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 类中的方法)通过以下链接:
- ==: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
- .equals(...): http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)
评论
可能值得补充的是,对于原始类型的包装对象 - 即 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.");
评论
Long a = 128l; Long b = 128l; System.out.println(a == b);
==
可用于许多对象类型,但您可以用于任何类型,尤其是字符串和谷歌地图标记。Object.equals
由于 Java 不支持运算符重载,因此行为相同
对于除 is 方法之外的每个对象,可以在
比较对象的 Java 和逻辑可以根据业务进行更改
规则。==
equals()
Java 中 和 等于之间的主要区别在于用于
比较原语,而建议使用方法检查
对象的相等性。==
"=="
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);
}
}
另请注意,通常包含用于测试的内容,因为如果要测试两个对象是否相等,这是您希望测试的第一件事。.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 对象都包含相同的数据,但引用不相同,因此等于返回 false 和 == 也。 但是如果我们覆盖等于方法比
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,只是我们覆盖了
equals 方法。
它比较对象的基本内容(id)对象
但是 ==
仍然比较对象的引用。
字符串池(又名实习)和整数池进一步模糊了差异,并且可能允许您在某些情况下用于对象而不是==
.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);
两者之间的差异让我困惑了一段时间,直到我决定仔细研究它。
他们中的许多人说,为了比较字符串,您应该使用而不是.希望在这个答案中,我能够说出区别。==
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 - 都具有相同的值,即“mango”,但仍然不完全相同。identityHashCode()
现在尝试取消注释此行并再次运行它,这次您会看到所有三者都不同。
嗯,这是一个有用的提示// mango2 = "mang";
identityHashCode()
我们知道,如果和hashcode(x)=N
hashcode(y)=N
=> x is equal to y
我不确定 java 在内部是如何工作的,但我认为这就是我说的时候发生的事情:
mango = "mango";
Java 创建了一个字符串,该字符串由变量指向(引用),如下所示"mango"
mango
mango ----> "mango"
现在在下一行中,当我说:
mango2 = "mango";
它实际上重用了相同的字符串,如下所示"mango"
mango ----> "mango" <---- mango2
mango 和 mango2 都指向同一个参考 现在当我说
mango3 = new String("mango")
它实际上为“mango”创建了一个全新的引用(字符串)。看起来像这样,
mango -----> "mango" <------ mango2
mango3 ------> "mango"
这就是为什么当我输出 的值时,它输出了 .当我输出 的值时,它会输出(即使值相同)。mango == mango2
true
mango3 == mango2
false
当你取消注释该行时,它实际上创建了一个字符串“mang”,它使我们的图形变成了这样:// mango2 = "mang";
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
这就是为什么 identityHashCode 并非所有人都相同的原因。
希望这对你们有所帮助。
实际上,我想生成一个失败并通过的测试用例。
请随时发表评论,如果我错了,请告诉我。==
equals()
评论
mango == mango2
mango2
"mango"
基本上,如果两个对象在堆上具有相同的引用,则进行比较,因此除非两个引用链接到同一对象,否则此比较将是错误的。==
equals()
是从 Object
类继承的方法。默认情况下,此方法会比较两个对象是否具有相同的引用。这意味着:
object1.equals(object2)
<=> object1 == object2
但是,如果要在同一类的两个对象之间建立相等性,则应重写此方法。如果您已经覆盖了该方法,则覆盖该方法也非常重要。hashCode()
equals()
在建立相等性时实现是 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
如果尚未实现,则会在执行前面的代码后打印。hashCode()
== 运算符测试两个变量是否具有相同的引用 (又名指向内存地址的指针)。
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)
评论
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");
}
}
}
----输出----- 真 假 真
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
评论
当你评估代码时,很明显 (==) 根据内存地址进行比较,而 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
*/
== 和 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
简而言之,答案是“是”。
在 Java 中,运算符比较这两个对象以查看它们是否指向相同的内存位置;而该方法实际上比较了两个对象,以查看它们是否具有相同的对象值。==
.equals()
这是关系运算符 ==
和方法 .equals()
之间区别的一般规则。
object1 == object2
比较 object1 和 object2 引用的对象是否引用堆中的相同内存位置。
object1.equals(object2)
比较 Object1 和 Object2 的值,无论它们在内存中的位置如何。
这可以使用 String 很好地演示
方案 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 类具有 height 和 weight 的实例变量。
因此,创建 person 对象并使用 I need to override the equals 方法比较这两者 person 类,以根据哪个实例变量(heigh 或 weight)来定义比较。person1 and person2
.equals()
但是,.== operator will still return results based on the memory location of the two objects(person1 and 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
这是同一性和等价性的区别。
a == b
意味着 A 和 B 是相同的,也就是说,它们是内存中同一对象的符号。
a.equals( b )
意味着它们是等价的,它们是在某种意义上具有相同价值的对象的符号——尽管这些对象可能在内存中占据不同的位置。
请注意,对于等价性,如何评估和比较对象的问题开始发挥作用——复杂对象可以被视为等价物,即使它们的某些内容不同。有了身份,就没有这样的问题了。
简单来说,检查两个对象是否指向相同的内存位置,同时计算对象中值的比较。==
.equals()
示例 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 方法比较对象内容,那么 class 必须覆盖对象的类 equals() 方法并提供内容比较的实现。在这里,String 类重写了用于内容比较的 equals 方法。所有包装类都具有用于内容比较的重写 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,还有一个用例。在这里,当我们将任何字符串分配给 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
}
}
请注意,每当 hashCode 方法被重写时,通常都需要重写此方法,以便维护 hashCode 方法的通用协定,该方法规定相等的对象必须具有相等的哈希代码。
equals() 方法主要比较对象的原始内容。
如果我们写
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()
Object.Equals()
String
.Equals
String
.equals()