Java = equals

Source: Internet
Author: User

Overview:

A.= Can be used for basic types and reference types: when used for basic types, compare whether the values are the same; when used for reference types, compare whether the objects are the same.

B.For string a = "A"; integer B = 1; this type of special object creation method, the value is the same when it is =.

C.The basic type does not have the equals method. Equals only compares whether the values (content in the object) are the same (true is returned if the values are the same ).

D.If a class does not define the equals method, It inherits the equals method in the object by default. The returned value is the same as the = method.

Details:

= And the essence of equals.

When "=" is used in Java to compare variables, the system uses the values stored in the "stack" as the basis for comparison.

The basic data type stores its content value in the stack, and the object type stores the address in the stack. These addresses point to the objects in the stack.

The object class in the Java. lang package has the public Boolean equals (Object OBJ) method, which compares whether two objects are equal.

The equals () method of other objects returns true only when the content of the two referenced objects to be compared is the same.

In short, "=" and "! = "Compare the address. You can also think of" = "and "! = "Compare the object handle; equals () Compare the object content. Or," = "and "! = "Compare the content in" stack ", and equals () Compare the content in" Heap.

= Operator. It is used to compare whether the values of two variables are equal, that is, to compare whether the values stored in the memory corresponding to the variables are the same, to compare the two basic types of data or whether the two reference variables are the same, only the = operator can be used.

The basic data types of Java are (char, byte, short, Int, long, float, double, Boolean ).

If the data that a variable points to is of the object type, two pieces of memory are involved at this time. The object itself occupies one piece of memory (for memory) and the variable itself also occupies one piece of memory, for example, the object OBJ = new object () variable obj is a memory, and the new object () is a memory, the data stored in the memory corresponding to the variable is the first address of the memory occupied by the object. For variables pointing to the object memory, to compare whether two variables point to the same object, you must check whether the values in the memory corresponding to the two variables are equal, in this case, we need to use the = Operator for comparison.

The difference between constructors.For string and integer, they are unique in object creation methods. Use the constructor and do not use the constructor to get an object. The result of the = Method Comparison is different. String A = "ABC"; string B = "ABC"; at this time, the result of a = B is true. String A = new string ("ABC"); string B = new string ("ABC"); the result of a = B is false. Integer A = 1; integer B = 1; the result of a = B is true. Integer A = new INTEGER (1); integer B = new INTEGER (1); the result of a = B is false.

Through this, we can also better understand = actual operations on the memory. The actual execution is similar to the basic type comparison.

String object and string connection pool:

The text in quotation marks is a special method for creating objects in the string class. However, "=" returns true. Why? Because there is a string pool in the JVM, many string objects are stored in it and can be shared and used, it improves the efficiency. the string pool is maintained by the string class. We can call the intern () method to access the string pool. When an object is created using text in quotation marks, the object is added to the string pool. if you want to create the next String object, JVM first searches for it in the string pool to check whether the corresponding String object exists. If yes, returns the reference of an existing object to the object to be created. if it does not exist, a new object will be created and the object of a new object will be referenced to the object to be created. the above paragraph may be confusing. useCodeIt is understood that str2 and str1 are two object references and point to the same object. Therefore, '=' returns true.

Only text creation objects in quotation marks can be placed into the string pool. String STR = new string ("ABC") The String object created by this method is not placed in the string pool. Therefore, the performance of creating an object with quotes containing text is better than that of creating a String object with that method.

String str1 = "ABC ";

String str2 = "ABC ";

String str3 = str1 + str2; // This creation method is not put into the string pool.

String str4 = str1 + "cd"; // This creation method is not put into the string pool.

String str5 = "AB" + str2; // This creation method is not put into the string pool.

String str6 = "AB" + "cd"; // This creation method is put into the string pool. In this case, an object is actually created, ABCD "1 Object

String str7 = "ABCD ";

System. Out. println (str1 = str2); // returns true.

System. Out. println (str6 = str7); // returns true.

Another problem:

Let's first look at a piece of Java code:

String STR = new string ("ABC ");

This problem is often followed by this Code, that is, how many string objects have been created in this line of code? I believe everyone is familiar with this question, and the answer is also well known. Next, let's start with this question and review some java knowledge related to creating string objects.

We can divide the above line of code into four parts: String STR, =, "ABC", and new string. String STR only defines a variable of the string type named STR, so it does not create an object; = is to initialize the variable STR, reference an object (or handle) assign a value to it, and apparently no object is created; now only new string ("ABC") is left. So why can new string ("ABC") be regarded as "ABC" and new string? Let's take a look at the string constructor we called:

Java code

Public String (string original ){
// Other code...
}
As we all know, we often use the following methods to create a class instance (object:
We use new to call the constructor method of the string class to create an object and assign its reference to the STR variable. At the same time, we noticed that the parameter accepted by the called constructor method is also a String object, which is exactly "ABC ".

Using new to create an object is to call the newinstance method of the class and use the reflection mechanism to create an object.

Equals Method. It is used to compare whether the content of two independent objects is the same. It is like comparing two objects with the same looks. The two objects are independent. For example, for the following code:

String A = new string ("foo ");

String B = new string ("foo ");

Two new statements create two objects, and use the and B variables to point to one of them. These two variables are two different objects whose first addresses are different, that is, the values stored in expression A and expression B are different. Therefore, expression A = B returns false, and the content of the two objects is the same. Therefore, expression. equals (B) returns true.

In actual development, we often need to compare whether the content of the passed string is equal. Many people use = for comparison without looking at it. This is wrong, and there are a lot of such errors. Remember, strings are compared using the equals method.

If a class does not define the equals Method. It inherits the equals method of the object class. The implementation code of the equals method of the object class is as follows:

Boolean equals (Object O ){

Return this = O;

}

This indicates that if a class does not define its own equals method, its default equals method (inherited from the object class) uses the = Operator, it also compares whether the objects pointed to by two variables are the same object. In this case, using equals and using = will get the same result. If two independent objects are compared, false is always returned. If you want to write a class to compare whether the content of the two instance objects created by the class is the same, you must overwrite the equals method, it is up to you to write your own code to determine when the content of the two objects is the same.

 

Sample Code:

  1. Public Class Test {
  2. Public Static Void Main (string [] ARGs ){
  3. Integer p = 1;
  4. Integer q = 1;
  5. Integer I = New INTEGER (1 );
  6. Integer J = New INTEGER (1 );
  7. If(P = q ){
  8. System. Out. println ("INTEGER: P = Q"); // Actual result
  9. }Else{
  10. System. Out. println ("INTEGER: P ! = Q");
  11. }
  12. If (P. Equals (Q)){
  13. System. Out. println ("INTEGER:P. Equals (Q)"); // Actual result
  14. }Else{
  15. System. Out. println ("INTEGER:P. Equals (Q)");
  16. }
  17. If(I = J ){
  18. System. Out. println ("Int: I = J");
  19. }Else{
  20. System. Out. println ("Int: I! = J"); // Actual result
  21. }
  22. If(I. Equals (j )){
  23. System. Out. println ("INTEGER:I. Equals (j)"); // Actual result
  24. }Else{
  25. System. Out. println ("INTEGER :!I. Equals (j)");
  26. }
  27. String A ="ABC";
  28. String B ="ABC";
  29. String c =New String ("ABC");
  30. String d =New String ("ABC");
  31. If(A = B ){
  32. System. Out. println ("ABC objects are equal"); // Actual result
  33. }Else{
  34. System. Out. println ("ABC objects are not equal");
  35. }
  36. If(A. Equals (B )){
  37. System. Out. println ("AB equal"); // Actual result
  38. }Else{
  39. System. Out. println ("AB is not equal");
  40. }
  41. If(C. Equals (D )){
  42. System. Out. println ("CD equal"); // Actual result
  43. }Else{
  44. System. Out. println ("CD not equal");
  45. }
  46. If(C = d ){
  47. System. Out. println ("CD objects are equal");
  48. }Else{
  49. System. Out. println ("Inconsistent CD objects"); // Actual result
  50. }
  51. }
  52. }

    The importance of the equals method does not need to be repeated. If you want to compare whether two objects are the same object, you should implement the equals method so that the objects can be compared using conditions that you think are equal.

    The following content is only the API specification, which has no profound significance. But I listed it first because these specifications are not guaranteed in reality.

    1. For any reference type, O. Equals (o) = true is true.

    2. If O. Equals (O1) = true is true, o1.equals (o) = true must also be true.

    3. If O. Equals (O1) = true and O. Equals (O2) = true, then

    O1.equals (O2) = true is also true.

    4. If the first call o. Equals (O1) = true is true, any subsequent call will be valid if O and O1 are not changed.

    5. O. Equals (null) = true is not true at any time.

    The above rules are not the most complete statement. For details, see the API documentation. for the object class, it provides the most rigorous implementation, that is, the equals method returns true only when it is the same object, that is, the reference comparison that people often say is not the value comparison. this strict implementation has no practical significance, so in the specific subclass (relative to the object), if we want to compare the object values, we must implement our own equals method. let's take a look at the following section.Program:

    Public Boolean equals (Object OBJ)

    {

    If (OBJ = NULL) return false;

    If (! (OBJ instanceof fieldposition ))

    Return false;

    Fieldposition Other = (fieldposition) OBJ;

    If (attribute = NULL ){

    If (other. Attribute! = NULL ){

    Return false;

    }

    }

    Else if (! Attribute. Equals (other. Attribute )){

    Return false;

    }

    Return (beginindex = Other. beginindex

    & Amp; endindex = Other. endindex

    & Field = Other. Field );

    }

    This is Java in JDK. text. there seems to be nothing to say about the Standard Implementation of fieldposition. I believe that most or most programmers believe that this is the correct and legal equals implementation. after all, it is the jdk api implementation. let's talk about it as a matter of fact:

    Package debug

    ; Import java. Text .*;

    Public class test {

    Public static void main (string [] ARGs ){

    Fieldposition fp = new fieldposition (10 );

    Fieldposition FP1 = new mytest (10 );

    System. Out. println (FP. Equals (FP1 ));

    System. Out. println (fp1.equals (FP ));

    }

    }

    Class mytest extends fieldposition {

    Int x = 10;

    Public mytest (int x ){

    Super (X );

    This. x = X;

    }

    Public Boolean equals (Object O ){

    If (O = NULL) return false;

    If (! (O instanceof mytest) return false;

    Return (mytest) O). x = This. X;

    }

    }

    Run the command to see what will be printed:

    System. Out. println (FP. Equals (FP1); print true

    System. Out. println (fp1.equals (FP); print flase

    Two objects with asymmetric equalsAlgorithm. Where is the problem? (brain teasers: Of course, the JDK implementation bug )? I believe there are too many programmers (except those who do not know how to implement the equals method) who have used the instanceof operator to perform short-circuit optimization when implementing the equals method, I have used it for a long time.

    Too many tutorials and documents are misleading. Some programmers who have a better understanding may know that such optimization may be wrong but cannot find the key to the problem. Another extreme is that hardcore experts who know this technical defect propose not to apply it like this. We know that "normally" to compare two objects, they "should" be of the same type. Therefore, short-circuit optimization is implemented using the instanceof operator. If the compared object is not of the same type as the current object, false is returned without comparison.

    But in fact, "The subclass is an instance of the parent class", so if the subclass o instanceof parent class always returns true, then there will certainly be no short-circuit optimization, the following comparison may result in multiple situations: one is that an exception cannot be thrown when it is modeled as a parent class, and the other is that the private member of the parent class cannot be compared without the inheritance of the quilt class, in addition, the above asymmetry comparison is formed. There may be too many cases.

    So, isn't it possible to use the instanceof operator for optimization? The answer is no. There are still many implementations in JDK that are correct. If a class is final, knowing that it cannot have sub-classes, why not use instanceof for optimization? In order to maintain Sun's development team's reputation, I do not describe which class, but a team member added the following comment when using this method for optimization:

    If (this = OBJ) // quick check

    Return true;

    If (! (OBJ instanceof xxxxclass) // (1) same object?

    Return false;

    There may be some questions, but I don't know how to do it (I don't know why I didn't call me...). So for non-final classes, how do I perform quick check?

    If (obj. getclass ()! = Xxxclass. Class) return false;

    Compared with the Class Object of the compared object and the class of the current object, it seems that there is no problem. However, if the subclass of this class does not implement the equals method again, when the subclass is compared, OBJ. getclass () is certainly not equal to xxxcalss. class, that is, the equals of the subclass will be invalid, so

    If (obj. getclass ()! = This. getclass () return false;

    Is the correct comparison. Another quick check is if (this = OBJ) return true;

    Do two objects compared by the equals method must be of the same type? I used "regular" above, which is also the wish of the vast majority of programmers, but in some special cases, we can compare different types, which does not violate the rules. However, this special case is very rare. an inappropriate example is that the equals of the integer class can be compared with sort to compare whether their values are of the same mathematical value. (In fact, this is not the case in JDK APIs, so I am saying it is not an appropriate example.) After completing quick check, we need to truly implement what you think is "equal ". There is no high requirement for implementing object equality. For example, if you implement the "person" class, you can think that they are equal as long as the names are the same, and other sex, can be ignored. This is not fully implemented, but if it is fully implemented, that is, all attributes must be the same, how to implement the equals method?

    Class human {

    Private string name;

    Private int ago;

    Private string sex;

    ....................

    Public Boolean equals (Object OBJ ){

    Quick check .......

    Human Other = (human) OJB;

    Return this. Name. Equals (other. Name) & this. ago = ohter. ago & this. Sex. Equals (other. Sex );

    }

    }

    This is a complete implementation. However, sometimes the equals implementation is implemented in the parent class, and equals can be correctly implemented after the quilt class inherits.

    At this time, you do not know what attributes the subclass has extended, so the above method cannot fully implement equals.

    A good method is to use reflection to fully implement equals:

    Public Boolean equals (Object OBJ ){

    Quick check .......

    Class C = This. getclass ();

    Filed [] FDS = C. getdeclaredfields ();

    For (filed F: FDs ){

    If (! F. Get (this). Equals (F. Get (OBJ )))

    Return false;

    }

    Return true;

    }

    For convenience of illustration, the above implementation omitted the exception. Such implementation is placed in the parent class, which ensures that the equals of your subclass can work correctly as you wish. The last point about the equals method is: If you overwrite the equals method yourself (it should be a crawler), you must overwrite the hashcode () at the same time (). this is a specification, otherwise .............

    Let's take a look at this example:

    Public final class phonenumber {

    Private Final int areacode;

    Private Final int exchange;

    Private Final int extension;

    Public phonenumber (INT areacode, int exchange, int extension ){

    Rangecheck (areacode, 999, "Area Code ");

    Rangecheck (exchange, 99999999, "Exchange ");

    Rangecheck (extension, 9999, "extension ");

    This. areacode = areacode;

    This. Exchange = exchange;

    This. Extension = extension;

    }

    Private Static void rangecheck (INT Arg, int Max, string name ){

    If (ARG <0 | arg> MAX)

    Throw new illegalargumentexception (name + ":" + Arg );

    }

    Public Boolean equals (Object O ){

    If (O = This)

    Return true;

    If (! (O instanceof phonenumber ))

    Return false;

    Phonenumber Pn = (phonenumber) O;

    Return Pn. Extension = extension & Pn. Exchange = exchange & Pn. areacode = areacode;

    }

    }

    Note that this class is final, so there is no problem with this equals implementation. Let's test:

    Public static void main (string [] ARGs ){

    Map Hm = new hashmap ();

    Phonenumber Pn = new phonenumber (123,389 42, 230 );

    Hm. Put (Pn, "I love you ");

    Phonenumber pn1 = new phonenumber (123,389 42, 230 );

    System. Out. println (PN );

    System. Out. println ("Pn. Equals (pn1) is" + Pn. Equals (pn1 ));

    System. Out. println (Hm. Get (pn1 ));

    System. Out. println (Hm. Get (PN ));

    }

    Since Pn. Equals (pn1), why is get (pn1) null after I put (Pn, "I love you?

    the answer is that their hashcode is different, and hashmap uses hashcode as the primary key. Therefore, the specification requires that if two objects return true when performing equals comparison, their hashcode requires that they return equal values.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.