English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
The comparison problem in Java is a very basic and easily confusing issue. Today, I will make a detailed summary and organization of several easily mistaken points, hoping it will be helpful to everyone's learning and interview.
First, the difference between == and equals()
Firstly, we need to know the difference between == and equals(). The == operator always compares address values. For basic data types, the == comparison is actually whether the variable values are equal, while for reference data types, the comparison is the address value. Here, it is especially necessary to pay attention to the String type, which is easy to use == casually and may cause errors. The equals() method is a method in the Object class. We know that all classes in Java will default to inherit the Object class, so class objects will have the equals() method. The equals() method in the Object class is shown in the figure below:
From the source code, we can see that the equals() method in the Object class also uses == at the bottom, so what it actually compares is the address value. Therefore, if we want to use the equals() method for other comparisons, we need to override the equals() method.
Second, basic data types and their wrapper classes
We all know that byte, short, int, long, boolean, char, double, float are the eight basic data types, and the variables declared by them are stored in stack memory. While the corresponding wrapper types (Byte, Short, Integer, Long, Boolean, Character, Double) define variables that exist in heap memory. For basic data types, their comparison is relatively simple, that is, use == to judge whether they are equal, and use <, >, <=, >= to compare their sizes. However, for wrapper types, it is somewhat different.
Firstly, for the judgment of equality, see the execution results of the following code:
package dailytest; import org.junit.Test; /** * Summary of comparisons in Java * @author yrr */ public class JavaCompareTest { /** * Integer type equality judgment */ @Test public void test01() { int n3 = 48; System.out.println("--------When using new objects, when the value is in [-127,128between---------"); Integer n7 = new Integer(48); Integer n8 = new Integer(48); System.out.println(n7 == n8); //false System.out.println(n7 == n3); //true System.out.println("--------For the direct assignment method, when the value is in [-128,127between---------"); Integer n1 = 48; Integer n2 = 48; System.out.println(n3 == n1); //true System.out.println(n1 == n2); //true System.out.println(n1.equals(n2)); //true System.out.println(n1.equals(n3)); //true System.out.println(n1.intValue() == n2.intValue()); //true System.out.println("--------For the direct assignment method, when the value is not in [-127,128between---------"); Integer n4 = 128; Integer n5 = 128; int n6 = 128; System.out.println(n4 == n5); //false System.out.println(n4 == n6); //true System.out.println(n4.equals(n5)); //true System.out.println(n4.equals(n6)); //true System.out.println(n4.intValue() == n5.intValue()); //true //When using the Integer.intValue() method, attention should be paid to verify whether it is null to prevent NullPointException from occurring } /** * Long type equality judgment */ @Test public void test02() { //Here, it should be noted that when defined with long, it is not necessary to add L or l, but when using Long, it must be added, otherwise an error will occur //The construction should be added with, to show the difference long n3 = 48L; System.out.println("--------When using new objects, when the value is in [-127,128between---------"); Long n7 = new Long(48); Long n8 = new Long(48); System.out.println(n7 == n8); //false System.out.println(n7 == n3); //true System.out.println("--------For the direct assignment method, when the value is in [-127,128between---------"); Long n1 = 48L; Long n2 = 48L; System.out.println(n3 == n1); //true System.out.println(n1 == n2); //true System.out.println(n1.equals(n2)); //true System.out.println(n1.equals(n3)); //true System.out.println(n1.intValue() == n2.intValue()); //true System.out.println("--------For the direct assignment method, when the value is not in [-127,128between---------"); Long n4 = 128L; Long n5 = 128L; long n6 = 128; System.out.println(n4 == n5); //false System.out.println(n4 == n6); //true System.out.println(n4.equals(n5)); //true System.out.println(n4.equals(n6)); //true System.out.println(n4.intValue() == n5.intValue()); //true //When using the Long.intValue() method, attention should be paid to verify whether it is null to prevent NullPointException from occurring } }
For the above execution results, the following explanations are made:
Firstly, for the new method to declare an Integer or Long object, because new objects are all allocated a space in the heap, so even if the values are the same, the comparison with == compares the address value, so it will return false. For the wrapper classes of primitive data types, the equals() method is overridden to compare the size of the values, so the equals() method can be used to judge according to the size of the values. For the comparison of Integer variables with int variables, it will be found that it is also based on the comparison value of the size of the values, because when comparing, the Integer type does automatic unboxing and turns into an int type. The explanations of the above three points are applicable to all wrapper types For the direct assignment method, the value is48for the two Integer variables, the comparison with == is true, while when the value is128after, is false. This is because at the bottom level, for the two Integer variables of n1 = 48;This direct assignment method actually calls the Integer.value() method. We can simply take a look at the source code of the Integer.value() method, as shown in the figure below:
We can see that there is an if judgment here, when the input i is in [-128,127], so for values within this range, they are directly returned from the IntegerCache array. Therefore, for values within this range, the array's corresponding address value is returned, so the == operator will return true. For values outside this range, they are new objects, so they will return false. This conclusion is also true for Byte, Short, Integer, Long types (those interested can check the source code of their corresponding value() methods), because the range of Byte types is [-128,127], so for Byte types, there is no difference between == and equals().
For size comparison, the use of >, <, <=, >= is not a problem, as they will perform automatic unboxing. However, we usually recommend the following two methods for size comparison:
Use the xxxValue() method to convert to a basic data type for comparison. Use the compareTo() method for comparison. In wrapper classes, the compareTo() method is overwritten. By checking the source code of compareTo(), it can be seen that it actually uses automatic unboxing to convert to the corresponding basic data type for comparison.
II. Comparison of Java Objects
After the above introduction, the comparison of objects is relatively easy. The principles are the same.
1. Comparison of String types
It should be noted that String types cannot be directly used with >, <=, >=, <, as it will report a compilation exception.
package dailytest; import org.junit.Test; /** * Summary of comparisons in Java * @author yrr */ public class JavaCompareTest { @Test public void test03() { String s1 = new String("123"); String s2 = new String("123"); System.out.println(s1 == s2); //false System.out.println(s1.equals(s2)); String s3 = "234"; String s4 = "234"; System.out.println(s3 == s4); //true System.out.println(s3.equals(s4)); //true //System.out.println(s1 <= s3); //The operator < is undefined for the argument type(s) java.lang.String, java.lang.String System.out.println(s1.compareTo(s3) < 0); //true } }
2. Comparison of class objects
The comparison conclusion of class objects is also the same, but it is more complex compared to basic data types and String types.
According to a certain rule, to determine whether two objects are equal, it is necessary to overwrite the equals() method in the class being judged, as shown in the following example code:
package dailytest; import org.junit.Test; /** * Summary of comparisons in Java * @author yrr */ public class JavaCompareTest { @Test public void test04() { Person p1 = new Person("yrr",18); Person p2 = new Person("yrr",18); System.out.println(p1 == p2); //false System.out.println(p2.equals(p1)); //true } } class Person{ private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } @Override public boolean equals(Object obj) { Person person = (Person) obj; return name.equals(person.getName()) && age.equals(person.getAge()); } }
If you want to compare the size of two objects (this is also a frequently asked interview question), there are two ways:
The compared class implements the Comparable interface and overrides the compareTo() method. Define a class that implements the Comparator interface or use an inner class to override the compare() method. The difference between the two is that the former is defined on the compared class, while the latter is defined outside the compared class. Through this distinction, the advantages and disadvantages of both are also very obvious. The former is simple, but it requires modification of the compared class, while the latter does not require modification of the original code and is more flexible.
The first method, the example code is as follows:
package dailytest; import org.junit.Test; /** * Summary of comparisons in Java * @author yrr */ public class JavaCompareTest { @Test public void test5() { Person p1 = new Person("yrr",18); Person p2 = new Person("wx",19); System.out.println(p1.compareTo(p2) < 0); } } class Person implements Comparable<Person>{ private String name; private Integer age; public Person() { } public Person(String name, Integer age) { this.name = name; this.age = age; } public Integer getAge() { return age; } @Override public int compareTo(Person o) { return this.getAge(); - o.getAge(); } }
The second method, the example code is as follows:
package comparator; import java.util.Arrays; import java.util.Comparator; public class MyComparator { public static void main(String[] args) { User[] users = new User[] { new User("u")}1001", 25),}} new User("u1002", 20), new User("u1003", 21) }; Arrays.sort(users, new Comparator<User>() { @Override public int compare(User o1, User o2) { return o1.getAge() - o2.getAge(); } }); for (int i = 0; i < users.length; i++) { User user = users[i]; System.out.println(user.getId()) + " " + user.getAge()); } } } class User { private String id; private int age; public User(String id, int age) { this.id = id; this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
That's all about the related content of comparison issues in Java that we have introduced to you this time. If you have any other questions, you can discuss them in the comment area below. Thank you for your support.
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)