我想澄清一下我的理解是否正确:
==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较
我想澄清一下我的理解是否正确:
==是一个引用比较,即两个对象都指向相同的内存位置 .equals()计算为对象中值的比较
当前回答
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()通常包含==用于测试,因为如果您想测试两个对象是否相等,这是您希望测试的第一个东西。
而==实际上查看的是基本类型的值,对于对象,它检查引用。
简单地说,==检查两个对象是否指向相同的内存位置,而.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
例1 -
==和.equals方法只用于引用比较。它表示两个对象是否引用同一个对象。
对象类等于方法实现
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必须重写对象的类equals()方法并提供内容比较的实现。这里,String类重写了用于内容比较的equals方法。所有包装器类都覆盖了用于内容比较的equals方法。
字符串类等于方法实现
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引用时,字符串常量就会在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方法的一般契约,该契约规定相等的对象必须具有相等的散列码。
Java API equals()方法契约
可能值得添加的是,对于基本类型的包装器对象,例如Int, Long, Double - ==如果两个值相等将返回true。
Long a = 10L;
Long b = 10L;
if (a == b) {
System.out.println("Wrapped primitives behave like values");
}
相比之下,将上述两个long放入两个单独的数组列表中,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.");