我想澄清一下我的理解是否正确:
==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较
我想澄清一下我的理解是否正确:
==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较
当前回答
只需记住.equals(…)必须由您试图比较的类实现。否则,就没有什么意义了;Object类的方法版本所做的事情与比较操作相同:
唯一需要对对象使用比较运算符的时候是比较枚举的时候。这是因为一次只有一个Enum值的实例。例如,给定枚举
enum FooEnum {A, B, C}
你永远不会同时拥有一个以上的A实例,对于B和c也是如此。这意味着你实际上可以像这样编写一个方法:
public boolean compareFoos(FooEnum x, FooEnum y)
{
return (x == y);
}
你就不会有任何问题了。
其他回答
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而不是==。希望在这个回答中我能说出区别。
回答这个问题的最好方法就是问自己几个问题。让我们开始吧:
下面程序的输出是什么:
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(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()之间区别的一般规则。
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类,我需要定义比较两个Person的标准。假设person类有身高和体重的实例变量。
因此,创建person对象person1和person2,并使用.equals()来比较这两个对象,我需要重写person类的equals方法,以定义基于哪个实例变量(高度或重量)的比较。
但是,==操作符仍然会根据两个对象(person1和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
一般来说,你问题的答案是“是的”,但是……
.equals(...) will only compare what it is written to compare, no more, no less. If a class does not override the equals method, then it defaults to the equals(Object o) method of the closest parent class that has overridden this method. If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality. Always remember to override hashCode if you override equals so as not to "break the contract". As per the API, the result returned from the hashCode() method for two objects must be the same if their equals methods show that they are equivalent. The converse is not necessarily true.