What is the difference between == and equals() in Java?
我想澄清一下我是否理解正确:
== ->是一个引用比较,即两个对象都指向相同的内存位置.equals() ->对对象中的值进行比较
我的理解正确吗?
一般来说,你的问题的答案是"是",但是……
.equals(...) 只会比较它所写的内容,不多也不少。- 如果一个类不重写equals方法,那么它默认为已重写此方法的最近父类的
equals(Object o) 方法。 - 如果没有父类提供覆盖,那么它默认为来自最终父类、对象的方法,因此您只剩下
Object#equals(Object o) 方法。对于对象API,这与== 相同;也就是说,只有当两个变量引用同一个对象(如果它们的引用是一个且相同)时,才会返回true。因此,您将测试对象相等性而不是函数相等性。 - 如果您覆盖
equals ,请务必记住覆盖hashCode ,以免"违反合同"。根据API,如果两个对象的equals 方法表明它们是等效的,则从hashCode() 方法返回的结果必须相同。反过来说不一定是真的。
关于字符串类:
equals()方法比较字符串实例(堆上)中的"value",而不管两个对象引用是否引用同一个字符串实例。如果任何两个字符串类型的对象引用引用同一个字符串实例,那么太好了!如果这两个对象引用引用了两个不同的字符串实例。这没什么区别。它是要比较的每个字符串实例中的"值"(即:字符数组的内容)。
另一方面,"=="运算符比较两个对象引用的值,以查看它们是否引用同一个字符串实例。如果两个对象的值引用"引用"同一个字符串实例,那么布尔表达式的结果将是"true"…duh。另一方面,如果两个对象引用的值"引用"不同的字符串实例(即使两个字符串实例具有相同的"值",即每个字符串实例的字符数组内容相同),则布尔表达式的结果将为"假"。
就像任何解释一样,让它沉入其中。
我希望这能让事情有所改观。
根据您所说的是"原语"还是"对象类型",有一些细微的区别;如果您所说的是"静态"或"非静态"成员,也可以这样说;您还可以混合以上所有内容…
下面是一个示例(您可以运行它):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | public final class MyEqualityTest { public static void main( String args[] ) { String s1 = new String("Test" ); String s2 = new String("Test" ); System.out.println(" 1 - 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(" 2 - 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(" 3 - 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
- 等号(…):http://DOCS.Oracle .COM/JavaSe/ 7 /DOCS/API/Java/Lang/Objult.HTML.YAL(Java.Lang.Object)
有段时间,==和等于之间的差异让我困惑,直到我决定仔细观察它。他们中的许多人说,为了比较字符串,应该使用
回答这个问题的最好方法就是问自己几个问题。那么,让我们开始:
以下程序的输出是什么:
1 2 3 4 |
如果你说,
1 2 | false true |
我会说你是对的,但你为什么这么说?如果你说输出是,
1 2 | true false |
我会说你错了,但我还是会问你,为什么你认为那是对的?
好,让我们试着回答这个问题:
以下程序的输出是什么:
1 2 3 4 |
如果你说,
1 2 | false true |
我会说你错了,但为什么现在是错的?此程序的正确输出是
1 2 | true false |
请比较一下上面的程序并试着思考一下。
好啊。现在这可能有帮助(请阅读:打印对象的地址-不可能,但我们仍然可以使用它。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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打印了这个(你可以在这里检查代码):
1 2 3 4 5 6 7 8 9 10 | false true true false mango mango false true 17225372 17225372 5433634 |
哦!现在您看到IdentityHashCode(mango)等于IdentityHashCode(mango2),但它不等于IdentityHashCode(mango3)
尽管所有字符串变量(mango、mango 2和mango 3)的值都相同,即"mango",但
现在尝试取消对该行的注释
我们知道,如果
我不确定Java是如何内部工作的,但我认为这是我说的:
1 | mango ="mango"; |
Java创建了一个字符串EDCOX1,12,它是由变量EDCOX1,13(例如)指向的(引用)。
1 | mango ---->"mango" |
接下来我说:
1 | mango2 ="mango"; |
它实际上重用了相同的字符串
1 | mango ---->"mango" <---- mango2 |
芒果和芒果2都指向同一参考现在当我说
1 |
它实际上为"芒果"创建了一个全新的引用(字符串)。看起来像这样,
1 2 3 | mango ----->"mango" <------ mango2 mango3 ------>"mango" |
这就是为什么当我给出
当您取消对行EDOCX1的注释时它实际上创建了一个字符串"mang",它将我们的图形转换为如下:
1 2 3 | mango ---->"mango" mango2 ---->"mang" mango3 ----->"mango" |
这就是为什么IdentityHashCode对所有人都不相同的原因。
希望这对你们有帮助。实际上,我想生成一个测试用例,其中==失败,等于()通过。请随时发表评论,如果我错了请告诉我。
The == operator tests whether two variables have the same references
(aka pointer to a memory address).
1 2 3 4 5 6 7 8 9 10 |
Whereas the equals() method tests whether two variables refer to objects
that have the same state (values).
1 2 3 4 5 |
干杯:
您必须重写equals函数(连同其他函数)才能将其与自定义类一起使用。
equals方法比较对象。
如果不重写.equals(),则==和.equals()都引用同一对象。
重写.equals()后,您希望做什么。可以将调用对象的状态与传入对象的状态进行比较,也可以只调用super.equals()。
==运算符:
= =是用于比较两个操作数的Java中的关系运算符。它用于确定两个操作数是否相等。使用==运算符,可以比较任何基元类型,如int、char、float和booleans。比较后,==运算符返回布尔值。如果两个操作数相等,==运算符返回一个真值。但是,如果两个操作数不相等,则返回一个假值。当与对象一起使用时,==运算符比较两个对象引用,并确定它们是否引用同一个实例。
.equals()方法
equals()是字符串类中可用的方法,用于比较两个字符串并确定它们是否相等。此方法返回比较结果的布尔值。如果两个字符串包含相同顺序的相同字符,equals()方法将返回true。否则,它将返回一个错误值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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 |
请记住,
唯一一次真正想对对象使用比较运算符的是Wen You正在比较枚举。这是因为一次只有一个枚举值的实例。例如,给定枚举
1 | enum FooEnum {A, B, C} |
一次最多只能有一个
1 2 3 4 | public boolean compareFoos(FooEnum x, FooEnum y) { return (x == y); } |
你不会有任何问题的。
运算符通常用于原始类型比较,因此
还要注意,
而
当您评估代码时,很明显(=)会根据内存地址进行比较,而equals(object o)会比较实例的hashcode()。这就是为什么人们说,如果以后不遇到意外,就不要破坏equals()和hashcode()之间的契约。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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)==用于比较原语。
例如:
1 2 3 4 5 6 7 |
2)equals()用于比较对象。例如:
1 2 3 |
如果两个值相等,那么对于基本类型(即int、long、double-==的包装器对象)来说,可能值得添加一点。
1 2 3 4 5 6 |
相比之下,将上面的两个long放入两个单独的arraylist中,equals将它们视为相同的,但==不一样。
1 2 3 4 5 6 7 |
==比较运算符始终引用。但万一
equals() method
它依赖于实现,如果我们被重写,它就等于方法,而不是在重写方法中给出的实现的基础上比较对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
在上面的代码中,obj和obj1对象都包含相同的数据,但引用不相同,因此等于返回false和==also。但如果我们重写equals方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
知道吗,签出它将返回正确和错误的同一个案件,只有我们重写
equals method .
它基于对象的内容(ID)比较对象
but ==
仍然比较对象的引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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"); } } } |
----输出——真假真
简而言之,答案是"是"。
在Java中,EDCOX1×0×操作符比较两个对象,以查看它们是否指向相同的内存位置;而EDCOX1×12的方法实际上比较了两个对象,以查看它们是否具有相同的对象值。
字符串池(又称中间池)和整数池进一步模糊了差异,并且在某些情况下允许您对对象使用
这可以给你更好的表现(?)以更大的复杂性为代价。
例如。:
复杂性权衡:以下可能会让您感到惊讶:
我建议您远离这种微观优化,始终使用
1 2 3 4 5 |
基本上,
但是,如果要在同一类的两个对象之间建立相等关系,则应重写此方法。如果您已经覆盖了
实现EDCOX1 5时,建立平等是Java对象契约的一部分。如果您正在处理集合,但尚未实现
1 2 3 4 | 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")); |
如果没有实现
由于Java不支持操作符重载,= =行为相同对于除equals()之外的每个对象,都是方法,可以在Java和比较对象的逻辑可以基于业务来改变。规则。
Java中的==和相等的主要区别是:建议检查equals()方法时比较原语物体相等。
字符串比较是使用==和equals方法的常见情况。因为java.lang.string类重写等于方法,所以如果两个字符串对象包含相同的内容,但==will,则返回true只有当两个引用指向同一对象时才返回true。
下面是一个比较Java中的两个字符串的例子,使用等式= =和等式()方法来消除一些疑虑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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); } } |