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

我想澄清,如果我正确地理解这一点:

  • == – >是参考比较,即两个对象指向相同的内存位置
  • .equals() – >计算对象中值的比较

我的理解是否正确?

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

  • 等于只比较它所写的比较,不多也不less。
  • 如果一个类没有重写equals方法,那么它默认为已经重写了这个方法的最接近父类的equals(Object o)方法。
  • 如果没有父类提供覆盖,则默认为来自最终父类Object的方法,因此剩下Object#equals(Object o)方法。 根据对象API,这与==相同; 也就是说, 当且仅当两个variables引用相同的对象时,它们才返回true,如果它们的引用是相同的。 因此,你将testing对象的平等,而不是function的平等
  • 一定要记住重写hashCode以覆盖equals以免“破坏合约”。 根据API,从两个对象的hashCode()方法返回的结果必须是相同的,如果它们的equals方法显示它们是等价的。 反过来不一定是对的。

对于String类:

equals() 方法比较String实例(堆中)的“value”,而不pipe这两个对象引用是否引用相同的String实例。 如果任何两个Stringtypes的对象引用指向相同的String实例,那么太棒了! 如果这两个对象引用引用了两个不同的String实例,则不会有所作为。 它是每个正在比较的string实例中的“值”(即:字符数组的内容)。

另一方面,“==” 运算符比较两个对象引用的值,以查看它们是否引用相同的String实例 。 如果两个对象引用的值“引用”相同的string实例,那么布尔expression式的结果将是“真正的”.. duh。 另一方面,如果两个对象引用的值“引用” 不同的String实例 (即使两个String实例具有相同的“值”,即每个String实例的字符数组的内容相同),布尔expression式的结果将是“false”。

就像任何解释一样,让它沉入其中。

我希望这个清理一下。

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

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

 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 )

==和equals之间的区别让我困惑了一段时间,直到我决定仔细看看它。 他们中的许多人说,比较string,你应该使用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)

即使所有的stringvariables – 芒果,芒果2和芒果3具有相同的值“芒果”。 但是identityHashCode()仍然是不一样的。

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

我们知道如果hashcode(x)=Nhashcode(y)=N => x is equal to y

我不知道java如何在内部工作,但我认为这是发生在我说:

 mango = "mango"; 

java创build了一个string"mango" ,并被variablesmango指出(引用)这样的东西

 mango ----> "mango" 

现在在接下来的一行中,我说:

 mango2 = "mango"; 

它实际上重用了这个看起来像这样的string"mango"

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

当我说时,芒果和芒果都指向相同的参考

 mango3 = new String("mango") 

它实际上为“芒果”创build了一个全新的参考(string)。 看起来像这样,

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

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

而当你取消注释行// mango2 = "mang"; 它实际上创build了一个string“mang”,它把我们的graphics变成这样:

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

这就是为什么identityHashCode对所有人都不一样。

希望这可以帮助你们。 其实我想生成一个testing用例==失败和等于()通过。 请随时发表评论,让我知道如果我错了。

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

 String foo = new String("abc"); String bar = new String("abc"); if(foo==bar) // False (The objects are not the same) bar = foo; if(foo==bar) // True (Now the objects are the same) 

equals()方法testing两个variables是否引用具有相同状态(值)的对象

 String foo = new String("abc"); String bar = new String("abc"); if(foo.equals(bar)) // True (The objects are identical but not same) 

干杯:-)

您将不得不重写equals函数(以及其他函数)以将其与自定义类一起使用。

equals方法比较对象。

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

如果您不覆盖.equals(),则==和.equals()指向相同的对象。

一旦你覆盖.equals(),你希望你想做什么。 您可以将调用对象的状态与传入的对象状态进行比较,也可以调用super.equals()

“==”是一个运算符,“equals”是一个方法。 运算符用于原始types比较,因此“==”用于内存地址比较,“equals”方法用于比较对象。

请记住, .equals(...)必须由您正在比较的类实现。 否则,没有太大的意义。 Object类的方法的版本与比较操作完全相同: Object#equals 。

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

 enum FooEnum {A, B, C} 

你一次不会有一个以上的A实例, BC也是一样的。 这意味着你可以写一个像这样的方法:

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

而且你将没有任何问题。

==运算符:

==是Java中的一个关系运算符,用于比较两个操作数。 它用于确定两个操作数是否相等。 使用==运算符,可以比较任何基本types,如int,char,float和Booleans。 比较之后,==运算符返回一个布尔值。 如果两个操作数相等,则==运算符返回一个真值。 但是,如果两个操作数不相等,则返回一个假值。 当与对象一起使用时,==运算符会比较两个对象引用,并确定它们是否引用同一个实例。

.equals()方法

equals()是String类中可用的方法,用于比较两个string并确定它们是否相等。 作为比较的结果,此方法返回一个布尔值。 如果两个string按相同的顺序包含相同的字符,则equals()方法返回true。 否则,它返回一个错误的值。

例如:

http://goo.gl/Sa3q5Y

  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 */ 

==可以在许多对象types中使用,但是您可以使用Object.equals作为任何types,特别是Strings和Google Map Markers。

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

==实际上是看原始types的值,对于它检查引用的对象。

==运算符总是参考比较。 但是如果

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和==。 但如果我们重写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)的对象

但==

仍然比较对象的引用。

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

—-输出—–真假假

可能值得添加的是,对于原始types的包装器对象(即Int,Long,Double – ==)将返回true,如果两个值相等。

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

相比之下,将上述两个Long分成两个独立的ArrayLists,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."); 

由于Java不支持运算符重载,所以==对于每个对象都是相同的,但equals()是方法,可以在Java中重写,并且逻辑比较对象可以根据业务规则进行更改。

Java中的==和equals的主要区别在于“==”用于比较原语,而build议使用equals()方法检查对象是否相等。

string比较是使用==和equals方法的常见scheme。 由于java.lang.String类覆盖了equals方法,所以如果两个String对象包含相同的内容,则返回true,但如果两个引用指向同一个对象,==将只返回true。

下面是使用==和equals()方法比较Java中两个string是否相等的示例 ,它将清除一些疑问:

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

string池 (又名interning )和整数池进一步模糊了区别,并且可能允许您在某些情况下使用==而不是.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; 

我build议你远离这样的微观优化, 总是使用.equals作为对象, ==对于原语:

 assert (new String("a")).equals(new String("a")); Integer i = 128; Integer j = 128; assert i.equals(j); 

基本上, ==比较两个对象是否在堆上具有相同的引用,所以除非两个引用链接到同一个对象,否则这个比较将是错误的。

equals()是从Object类inheritance的方法。 这个方法默认比较两个对象是否具有相同的引用。 它的意思是:

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

但是,如果要在同一个类的两个对象之间build立平等,则应该重写此方法。 如果覆盖equals() ,重写hashCode()方法也很重要。

当build立相等时,实现hashCode()是Java Object Contract的一部分。 如果你正在使用集合,并且你还没有实现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")); 

如果你还没有实现hashCode()那么在执行前面的代码之后将会打印null

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

“==”实际上是比较两个对象引用,看他们是否指向同一个对象。

“等于”是一个比较实际string值的“深度比较”。