对象比较中equals 与 ”==“的差别


要点:
1、String str1 = "1";与 String str2 = new String("1"); 在内存中的表现是不同的。
2、str2 = str2.intern();可以消除这种(str1、str2)不同。

3、"==" 表示引用对象的引用比较,或则值对象的值比较。虽然String是引用对象,但是String的比较不能单纯的通过"=="实现,因为如 "1、"。
4、Integer intObj = 1;Integer intObj2 = 1;int intNative = 1;的equals值是相等的,intNative与intObj比较是会先装箱为object类型,然后再比较其int值;
 public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
 
结论:
对象是否相等要看该对象具体代表的意义是什么,某个对象(Object)引用相等就代表相等(a.equals(b) == true);
可能某个对象(String)引用相等代表相等,如果引用不相等,另外一种比较方式相等也代表相等(a.equals(b) == true);
又可能某个对象(Integer,Float)不同过引用来判定相等,而是通过其对象中某个关键变量的值来判定是否相等(a.equals(b) == true)。
 1 void equalsTest2(){
2 System.out.println("2--------------------");
3 String str1 = "1";
4 String str2 = "1";
5 System.out.println( "str2.hashCode()="+str2.hashCode()+" ; str1.hashCode()="+ str1.hashCode());
6 System.out.println("str1 == str2="+ (str1 == str2));
7 System.out.println("str1.equals(str2)="+str1.equals(str2));
8 }
9
10 void equalsTest3(){
11 System.out.println("3--------------------");
12 String str1 = "1";
13 String str2 = "123".subSequence(0, 1).toString();// subSequence
14 System.out.println( "str2.hashCode()="+str2.hashCode()+" ; str1.hashCode()="+ str1.hashCode());
15 System.out.println("str1 == str2="+ (str1 == str2));
16 System.out.println("str1.equals(str2)="+str1.equals(str2));
17 }
18
19 void equalsTest4(){
20 System.out.println("4--------------------");
21 String str1 = "1";
22 String str2 = new String("1");// new
23 System.out.println( "str2.hashCode()="+str2.hashCode()+" ; str1.hashCode()="+ str1.hashCode());
24 System.out.println("str1 == str2="+ (str1 == str2));
25 System.out.println("str1.equals(str2)="+str1.equals(str2));
26 }
27
28 void equalsTest5(){
29 System.out.println("5--------------------");
30 String str1 = "1";
31 String str2 = new String("1");
32 str2 = str2.intern();// new and intern
33 System.out.println( "str2.hashCode()="+str2.hashCode()+" ; str1.hashCode()="+ str1.hashCode());
34 System.out.println("str1 == str2="+ (str1 == str2));
35 System.out.println("str1.equals(str2)="+str1.equals(str2));
36 }

  

  测试结果:

 1 2--------------------
2 str2.hashCode()=49 ; str1.hashCode()=49
3 str1 == str2=true
4 str1.equals(str2)=true
5 3--------------------
6 str2.hashCode()=49 ; str1.hashCode()=49
7 str1 == str2=false
8 str1.equals(str2)=true
9 4--------------------
10 str2.hashCode()=49 ; str1.hashCode()=49
11 str1 == str2=false
12 str1.equals(str2)=true
13 5--------------------
14 str2.hashCode()=49 ; str1.hashCode()=49
15 str1 == str2=true
16 str1.equals(str2)=true
String str1 = "1";
String str2 = new String("1");
的区别在于,str1是在字符pool中,如果再创建一个变量"String str3 = "1";",str1与str3都在字符pool中,str1,str3不仅在字面上输出相等,而且在内存中的引用也相同,str1,str3就是同一个值。
但是str2是,强制要求在字符pool外创建一个新内存区来存放"1",不管pool中是否有已经存在值为"1"的字符串对象。
str2 = str2.intern(); 也就意味着,要求JVM去字符pool中找找,看是否有相同字面值("1") 的字符对象,如果有,就把引用指向它。

几种不同对象的equals实现:
 1 Object:
2
3 public boolean equals(Object obj) {
4 return (this == obj);
5 }
6
7
8 String:
9
10 public boolean equals(Object anObject) {
11 if (this == anObject) {
12 return true;
13 }
14 if (anObject instanceof String) {
15 String anotherString = (String)anObject;
16 int n = count;
17 if (n == anotherString.count) {
18 char v1[] = value;
19 char v2[] = anotherString.value;
20 int i = offset;
21 int j = anotherString.offset;
22 while (n-- != 0) {
23 if (v1[i++] != v2[j++])
24 return false;
25 }
26 return true;
27 }
28 }
29 return false;
30 }
31
32
33 Integer:
34
35 public boolean equals(Object obj) {
36 if (obj instanceof Integer) {
37 return value == ((Integer)obj).intValue();
38 }
39 return false;
40 }
41
42 java.util.Date:
43
44 public boolean equals(Object obj) {
45 return obj instanceof Date && getTime() == ((Date) obj).getTime();
46 }
1 Float:
2
3 public boolean equals(Object obj) {
4 return (obj instanceof Float)
5 && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
6 }


Java API,中对 equals()与hashCode()的定义:
  • hashCode

    public int hashCode()
    Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided byHashMap.

    The general contract of hashCode is:

    • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCodemethod must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
    • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
    • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling thehashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

    As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)

    Returns:
    a hash code value for this object.
    See Also:
    equals(java.lang.Object)System.identityHashCode(java.lang.Object)

  • equals

    public boolean equals(Object obj)
    Indicates whether some other object is "equal to" this one.

    The equals method implements an equivalence relation on non-null object references:

    • It is reflexive: for any non-null reference value xx.equals(x) should return true.
    • It is symmetric: for any non-null reference values x and yx.equals(y) should return true if and only if y.equals(x)returns true.
    • It is transitive: for any non-null reference values xy, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
    • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
    • For any non-null reference value xx.equals(null) should return false.

    The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the valuetrue).

    Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

    Parameters:
    obj - the reference object with which to compare.
    Returns:
    true if this object is the same as the obj argument; false otherwise.
    See Also:
    hashCode()HashMap
原文地址:https://www.cnblogs.com/tao_/p/2222456.html