我想澄清一下我的理解是否正确:
==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较
我想澄清一下我的理解是否正确:
==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较
当前回答
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类的方法。默认情况下,如果两个对象具有相同的引用,则此方法进行比较。它的意思是:
object1.equals(object2) <=> object1 == object2
但是,如果您希望在同一类的两个对象之间建立相等性,则应该重写此方法。如果已经重写了equals(),重写hashCode()方法也是非常重要的。
当建立平等是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"));
如果您没有实现hashCode(),则在执行前面的代码后将打印null。
String池(又名实习池)和Integer池进一步模糊了区别,并允许您在某些情况下对对象使用==而不是.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而不是==。希望在这个回答中我能说出区别。
回答这个问题的最好方法就是问自己几个问题。让我们开始吧:
下面程序的输出是什么:
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(芒果2)但它不等于identityHashCode(芒果3)
即使所有的字符串变量芒果,芒果2和芒果3都有相同的值,即“芒果”,identityHashCode()对所有变量仍然不相同。
现在尝试取消注释这一行// mango2 = "mang";并再次运行它,这一次你将看到所有三个identityHashCode()是不同的。 嗯,这是个有用的提示
我们知道如果hashcode(x)=N并且hashcode(y)=N => x等于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(即使值是相同的)。
当你取消注释// mango2 = "mang"; 它实际上创建了一个字符串“mang”,将我们的图形变成这样:
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
这就是为什么identityHashCode对所有人来说都不一样。
希望这对你们有帮助。 实际上,我想生成一个测试用例,其中==失败而equals()通过。 如果我错了,请随意评论并让我知道。
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()方法比较对象的内容。 在first System.out.println()中,s1和s2的内容是相同的,这就是为什么它打印为真。 另外两个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
因为==运算符主要比较对象的引用,而不是对象的值。 在first System.out.println()中,s1和s2的引用是相同的,这就是为什么它返回true。
在第二个System.out.println()中,创建了s3对象,这就是为什么会创建另一个s3的引用,并且s2和s3的引用会有所不同,因此它返回“false”。
Third System.out.println(),遵循second System.out.println()的规则,这就是为什么它会返回"false"。
如果不重写.equals(), ==和.equals()都指向同一个对象。
一旦你重写了.equals(),你想要做的就是你的愿望。你可以比较调用对象的状态和传入对象的状态或者你可以调用super。equals()