请参阅以下代码
class TestToString
{
public static void main(String args[])
{
CheckToString cs = new CheckToString (2);
CheckToString c = new CheckToString (2);
if( cs.equals(c))
System.out.println(" Both objects are equal");
else
System.out.println(" Unequal objects ");
}
}
class CheckToString
{
int i;
CheckToString ()
{
i=10;
}
CheckToString (int a)
{
this.i=a;
}
}
输出: 不平等的对象
但我期待输出
两个对象相等
我知道两个对象都有不同的反思,
System.out.println(cs); //com.sample.personal.checkToString@19821f
System.out.println(c); //com.sample.personal.checkToString@addbf1
但我问,为什么他们有不同的推荐? 而在下面的例子中,对象具有相同的内存位置。
Integer a = new Integer(2);
Integer b = new Integer(2);
System.out.println(a); //2
System.out.println(b); //2
我将用户定义类的对象与预定义类的对象进行比较。 似乎用户定义类的对象与Integer类的对象的行为相同,其值超过-128到127.为什么这两种情况的引用都不同? (对于Integer类,其值在-128到127之间,对于用户定义的类不同)
答案 0 :(得分:6)
equals
的默认实现检查引用。您正在创建2个不同的对象,它们不会在内存中引用相同的内容。
平等的良好实现将是:
public boolean equals(Object o) {
if (!(o instanceof CheckToString)) {
return false;
}
CheckToString other = (CheckToString) o;
return i == other.i;
}
覆盖equals
时,您还需要覆盖hashCode
。
每当你说new CheckToString()
时,你在内存中创建一个新对象,所以与另一个new CheckToString()
完全不同。对象定义中的内容无关紧要。
你提到的有关Integer的内容是正确的,但它适用于Integer
,而不适用于您创建的自定义对象。
答案 1 :(得分:3)
您需要覆盖equals
课程中的CheckToString
方法:
@Override
public boolean equals(Object o){
if(this==o){
return true;
}
if(o instanceof CheckString){
CheckString other = (CheckString) o;
return this.i == other.i;
}
return false;
}
建议您覆盖equals
时覆盖hashCode
,以便在散列集合中使用对象(即HasSet,LinkedHasSet,HashMap)。在这种情况下,因为你的类似乎是原始整数的包装器,我想你可以返回整数本身。
@Override
public int hashCode(){
return i;
}
最后,我们总是建议覆盖toString
,这样每次查看课程实例时,都会看到对象的友好,人类可读的表示形式。
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append(this.getClass().getSimpleName()).append("[");
sb.append("i: ").append(i).append("]");
return sb.toString();
}
答案 2 :(得分:0)
你必须定义自己的toString方法,以返回i
和你自己的等于方法的值。
class checkToString
{
int i;
public checkToString()
{
i=10;
}
public checkToString(int a)
{
this.i=a;
}
public String toString(){ return "" + i;}
public boolean equals(checkToString a){ return a.toString().equals(this.toString());}
}
立即尝试。这也可以在没有toString()的情况下完成。
像这样:public boolean equals(checkToString a){ return (this.i == a.i); }
答案 3 :(得分:0)
默认情况下,equals方法仅检查任何两个对象的哈希码。因此,如果您需要equals方法,则应根据对象中的任何基础属性返回结果,您必须相应地重写equals方法。
答案 4 :(得分:0)
2个对象显然没有指向同一个内存位置(请注意,您正在比较对象引用)。有关详细信息,请参阅对象类的JavaDoc和相应的equals()
方法
要比较它们的字符串表示形式,您可以进行以下修改:
class TestToString
{
public static void main(String args[])
{
CheckToString cs = new CheckToString(2);
CheckToString c = new CheckToString(2);
if( cs.toString().equalsIgnoreCase(c.toString()))
System.out.println(" Both objects are equal");
else
System.out.println(" Unequal objects ");
}
}
class CheckToString
{
int i;
CheckToString()
{
i=10;
}
CheckToString(int a)
{
this.i=a;
}
public String toString(){
return String.valueOf(i);
}
}
ps:还要注意对象案例(Java Conventions)
的变化答案 5 :(得分:0)
equals方法在任何用户定义类中默认基于引用进行比较,但是如果你在当前类中重写equals方法,那么它是基于内容的比较...但是在java.lang.StringClass中它总是基于内容进行比较