我想澄清一下我是否理解这一点:
==
- >是一个参考比较,即两个对象都指向相同的内存位置.equals()
- >评估对象中值的比较我的理解是否正确?
答案 0 :(得分:563)
一般来说,你的问题的答案是“是”,但是......
.equals(...)
只会比较它所写的比较,不多也不少。equals(Object o)
方法。 Object#equals(Object o)
方法。根据Object API,这与==
相同;也就是说,当且仅当两个变量引用同一个对象时,如果它们的引用是同一个,它返回true 。因此,您将测试对象平等而非功能相等。hashCode
以便不“违反合同”,请务必覆盖equals
。根据API,如果hashCode()
方法显示它们是等效的,则equals
方法为两个对象返回的结果必须相同。相反,不必然是真的。 答案 1 :(得分:98)
关于String类:
equals()方法比较String实例(在堆上)中的“值”,而不管两个对象引用是否引用相同的String实例。如果任何两个String类型的对象引用引用相同的String实例那么太棒了!如果两个对象引用引用两个不同的String实例,则它没有区别。它是正在比较的每个String实例中的“值”(即:字符数组的内容)。
另一方面,“==”运算符会比较两个对象引用的值,以查看它们是否引用相同的字符串实例。如果两个对象引用的值“引用”相同的String实例,则布尔表达式的结果将为“true”.. duh。另一方面,如果两个对象引用的值“引用”不同的String实例(即使两个String实例具有相同的“值”,即每个字符数组的内容)字符串实例是相同的)布尔表达式的结果将是“false”。
与任何解释一样,让它沉入其中。
我希望这可以解决一些问题。
答案 2 :(得分:54)
根据您是在谈论“原语”还是“对象类型”,存在一些小差异;如果你在谈论“静态”或“非静态”成员,也可以这样说;你也可以混合以上所有......
这是一个例子(你可以运行它):
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;
}
}
您可以通过以下链接比较“==”(Equality Operator)和“.equals(...)”(java.lang.Object类中的方法)的解释:
答案 3 :(得分:41)
==和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
请比较上述程序并尝试考虑它。
确定。现在这可能有所帮助(请阅读:print the address of object - 不可能,但我们仍然可以使用它。)
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));
你可以试着考虑上面代码中最后三行的输出: 对我来说,意思是打印出来的(you can check the code here):
false
true
true
false
mango mango
false
true
17225372
17225372
5433634
哦!现在你看到 identityHashCode(mango)等于identityHashCode(mango2)但它不等于identityHashCode(mango3)
即使所有字符串变量 - 芒果,芒果2和芒果3 - 都具有相同值,即“芒果”,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
芒果和芒果2都指向相同的参考 现在,当我说
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()通过。 如果我错了,请随时发表评论并告诉我。
答案 4 :(得分:29)
== 运算符测试两个变量是否具有相同的引用 (也就是指向内存地址的指针)。
<table id="app">
<tr v-for="(i, row) in rows">
<td v-for="(j, cell) in row", @click="getCell(i, j)">
{{cell}}
</td>
</tr>
</table>
new Vue({
el: '#app',
data: {
rows: [
[11, 12, 13],
[21, 22, 23]
]
},
methods: {
getCell: (i, j) => console.log(i, j)
}
})
而 equals()方法测试两个变量是否引用对象 具有相同状态(值)。
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)
干杯: - )
答案 5 :(得分:12)
您必须覆盖equals函数(以及其他函数)才能将其与自定义类一起使用。
equals方法比较对象。
==
二元运算符比较内存地址。
答案 6 :(得分:7)
如果不覆盖.equals(),则==和.equals()都指向同一个对象。
一旦你覆盖.equals(),你希望你想做什么。您可以将调用对象的状态与传入的对象的状态进行比较,或者您可以调用super.equals()
答案 7 :(得分:5)
==运算符:
==是Java中的关系运算符,用于比较两个操作数。它用于确定两个操作数是否相等。使用==运算符,您可以比较任何基本类型,如int,char,float和Booleans。比较后,==运算符返回一个布尔值。如果两个操作数相等,则==运算符返回一个真值。但是,如果两个操作数不相等,则返回false值。 与对象一起使用时,==运算符会比较两个对象引用,并确定它们是否引用同一个实例。
.equals()方法
equals()是String类中可用的方法,用于比较两个字符串并确定它们是否相等。作为比较的结果,此方法返回布尔值。如果两个字符串包含相同顺序的相同字符,则equals()方法返回true。否则,它返回一个假值。
答案 8 :(得分:5)
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
答案 9 :(得分:5)
==
是运算符,equals()
是方法。
运算符通常用于原语类型比较,因此==
用于内存地址比较,equals()
方法用于比较对象 。
答案 10 :(得分:5)
请记住,.equals(...)
必须由您要比较的类实现。否则,没有太大意义; Object类的方法版本与比较操作的作用相同:Object#equals。
您真正想要使用对象的比较运算符的唯一时间是您要比较枚举。这是因为一次只有一个枚举值的实例。例如,给定枚举
enum FooEnum {A, B, C}
您一次不会有多个A
个实例,B
和C
也相同。这意味着您实际上可以编写如下方法:
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
你没有任何问题。
答案 11 :(得分:3)
另请注意,.equals()
通常包含==
进行测试,因为如果您想测试两个对象是否相等,这是您希望测试的第一件事。
==
实际上会查看基本类型的值,对于检查引用的对象。
答案 12 :(得分:3)
当您评估代码时,很明显(==)根据内存地址进行比较,而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
*/
答案 13 :(得分:3)
==和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
答案 14 :(得分:2)
==
可用于多种对象类型,但您可以将Object.equals
用于任何类型,尤其是字符串和Google地图标记。
答案 15 :(得分:2)
==运算符始终引用进行比较。但是在
的情况下如果我们被覆盖的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和==。 但如果我们覆盖等于方法而不是
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)基础上的对象
但==
仍然比较对象的引用。
答案 16 :(得分:2)
对于基本类型的包装器对象,可能值得添加 - 即Int,Long,Double - ==如果两个值相等则返回true。
Long a = 10L;
Long b = 10L;
if (a == b) {
System.out.println("Wrapped primitives behave like values");
}
相比之下,将上面两个Longs放到两个独立的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.");
答案 17 :(得分:2)
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");
}
}
}
---- -----输出 真正 假 真
答案 18 :(得分:2)
以下是 relational operator ==
与 the method .equals()
之间差异的一般规则。
object1 == object2
比较由object1和object2引用的对象是否引用了 Heap中相同的内存位置。
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类,则需要定义我将比较两个人的标准。假设此人类具有身高和体重的实例变量。
因此,创建人员对象person1 and person2
并使用.equals()
比较这两个对象,我需要覆盖人员类的 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
答案 19 :(得分:0)
示例 1 -
== 和 .equals 方法仅供参考比较。表示两个对象是否指向同一个对象。
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
}
}
示例 2 -
但是如果我们想使用 equals 方法比较对象内容,那么 class 必须覆盖对象的 class equals() 方法并提供内容比较的实现。在这里,String 类覆盖了内容比较的 equals 方法。所有包装类都覆盖了用于内容比较的 equals 方法。
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
}
}
示例 3 -
对于字符串,还有一个用例。在这里,当我们将任何字符串分配给 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 方法的一般约定,即相等的对象必须具有相等的哈希码。
答案 20 :(得分:0)
简单来说,==
检查两个对象是否指向相同的内存位置,而 .equals()
评估对象中值的比较。
答案 21 :(得分:0)
这是身份和等效性之间的区别。
a == b
表示a和b是相同,即它们是内存中同一对象的符号。
a.equals( b )
表示它们是等效的,它们是在某种意义上具有相同值的对象的符号-尽管这些对象可能在内存中占据不同的位置。
请注意,等效时,如何评估和比较对象的问题就开始发挥作用-出于实际目的,复杂的对象可能被认为是等效的,即使它们的某些内容有所不同。有了身份,就没有这样的问题。
答案 22 :(得分:0)
简而言之,答案是“是”。
在Java中,==
运算符比较两个对象以查看它们是否指向相同的内存位置;而.equals()
方法实际上是比较两个对象以查看它们是否具有相同的对象值。
答案 23 :(得分:0)
基本上,==
比较两个对象在堆上是否具有相同的引用,因此除非两个引用链接到同一个对象,否则此比较将为false。
equals()
是从 Object
类继承的方法。默认情况下,此方法会比较两个对象是否具有相同的引用。这意味着:
object1.equals(object2)
&lt; =&gt; object1 == object2
但是,如果要在同一个类的两个对象之间建立相等性,则应覆盖此方法。如果您覆盖hashCode()
,则覆盖方法equals()
也非常重要。
在建立相等性时实现hashCode()
是Java对象契约的一部分。如果您正在使用馆藏,但尚未实施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()
。
答案 24 :(得分:0)
String pool(又名interning)和Integer pool 进一步模糊差异,可能允许您在某些对象中使用==
案例代替.equals
这可以为您带来更高的性能(?),代价是更复杂。
E.g:
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);
答案 25 :(得分:0)
由于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);
}
}