Comparative problems in Java are a very basic and easy to confuse. Today I will summarize and organize a more detailed summary and arrangement of a few error-prone points, hoping that it will be helpful for everyone's study and interview.
1. The difference between == and equals()
First of all, we need to know the difference between == and equals(). The == sign is always compared with the address value. For basic data types, == comparison is actually whether the variable values are equal, while for reference data types, the address value is compared. What you need to pay special attention to here is the String type, which is easy to take for granted == and is easy to make mistakes. The equals() method is a method in the Object class. We know that all classes in Java will inherit the Object class by default, so the class objects will have the equals() method. The equals() method in the Object class is shown in the figure below:
As can be seen from the source code, the underlying layer of the equals() method in the Object class also uses ==, so it is actually the address value. So if we want to use the equals() method for other comparisons, we need to override the equals() method.
2. Basic data types and packaging types
We all know that byte, short, int, long, boolean, char, double, and float are basic data types, and the variables they declare are stored in the stack memory. The variables defined by their corresponding packaging types (Byte, Short, Integer, Long, Boolean, Character, Double) exist in the heap memory. For basic data types, their comparison is relatively simple, that is, use == to determine whether they are equal, and use <, >, <=, >= to compare sizes. But for packaging types, it is a bit different.
First, for determining whether it is equal, see the execution result of the following code:
package dailytest;import org.junit.Test;/** * Comparative summary in Java* @author yrr */public class JavaCompareTest { /** * Integer type judgment is equal*/ @Test public void test01() { int n3 = 48; System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- n8); //false System.out.println(n7 == n3); //true System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- System.out.println(n1.intValue() == n2.intValue()); //true System.out.println("---------------------------------------"); 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, you need to pay attention to verify whether it is null to prevent NullPointException } /** * Long type judgment is equal*/ @Test public void test02() { //Note here that when using long definition, L or l is not required, but when using long, otherwise an error will be reported//Add it in construction to indicate the difference long n3 = 48L; System.out.println("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 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("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 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, you need to pay attention to verify whether it is null to prevent NullPointException }}For the above execution results, the following explanation is made:
First, for the new method, we declare an Integer or Long object. Because the new object opens up a piece of space in the heap, even if the values of the two are the same, for ==, the address value is compared, so false will be returned. For the wrapper classes of basic data types, the equals() method has been rewritten, and the numerical size will be compared, so the equals() method can be used to judge based on the numerical size. Regarding the problem of comparing Integer variables with int variables, we will find that the comparison value is also based on the numerical size. This is because when comparing, the Integer type is automatically unboxed and converted to the int type. The explanation of the first three points is applicable to all packaging types. For the direct assignment method, the two Integer variables with a value of 48 are judged to be true by the == sign, but when the value is 128, it is false. This is because at the bottom, for Integer n1 = 48;, the method of direct assignment actually calls the Integer.value() method. We can take a brief 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 within the range of [-128, 127], it is returned directly from the IntegerCache array. Therefore, for values in this range, the address values corresponding to this array are returned, so using the == sign to judge true will be returned. What is not within this range is the object that is new, so false will be returned. This conclusion is true for Byte, Short, Integer, and Long types (if you are interested, you can check the source code of their corresponding value() method), because the scope of Byte type is [-128, 127], so for Byte type, using == is no different from equals().
For size comparison, there is no problem using >, <, <=, >=, and they will be automatically unboxed. But we usually recommend using the following two ways to compare sizes:
Call the xxxValue() method to convert it into the basic data type for comparison. In the wrapper class, the compareTo() method is rewritten. By looking at the compareTo() source code, you can see that in fact, the underlying usage is also converted into the corresponding basic data type by automatically unboxing and then comparing it.
2. Comparison of Java objects
With the above introduction, it is easier to compare objects. The principles are the same.
1. Comparison of String Types
It should be noted that String type cannot be used directly >, <=, >=, and <, and will report a compilation exception.
package dailytest;import org.junit.Test;/** * Comparative summary 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 conclusion of class objects is the same, but compared with basic data types and String types, it is a bit more complicated.
According to a certain rule, to determine whether the two objects are equal, the equals() method needs to be rewrite in the judged class. The example code is as follows:
package dailytest;import org.junit.Test;/** * Comparative summary 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()); } }And if you want to compare the sizes of two objects (this is also a common interview question), there are two ways:
The comparable class implements the Comparable interface, and overrides the compareTo() method to define the class that implements a Comparator interface or use the internal class to override the compare() method: the former is defined on the comparable class, while the latter is defined outside the comparable class. Through this difference, the advantages and disadvantages of the two are also obvious. The former is simple, but requires modification of the compared class, while the latter does not need to modify the original code, which is more flexible.
The first method, the sample code is as follows:
package dailytest;import org.junit.Test;/** * Comparative summary 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 sample 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("u1001", 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; } }The above is the relevant content of the Java comparison questions I have told you this time. If you have other questions, you can discuss them in the comment area below. Thank you for your support.