Java Interview Alchemy Series | Analysis of common interview questions about String

0x0 basic knowledge

1.'==' operator

Data types in Java are divided into basic data types and reference data types:

  1. Basic type: the smallest granular data type built into the programming language. It includes four categories and eight types
    • 4 kinds of integer bytetypes: short, int, ,long
    • Two kinds of floating-point floattype: ,double
    • 1 character type:char
    • 1 Boolean type:boolean
  2. Reference type: A reference is also called a handle. A reference type is a data form defined in a programming language that stores the address value of the address where the actual content is located in the handle, for example:
    • class
    • interface
    • Array
  • For basic types, the == comparison is their value
  • For reference types, the == comparison is their address in memory (heap memory address)

for example:

    public static void main(String[] args) {
        //基本数据类型
        int num1 = 100;
        int num2 = 100;
        System.out.println("num1 == num2 : " + (num1 == num2) + "\n");

        //引用类型,其中'System.identityHashCode'可以理解为打印对象地址
        String str1 = "mio4";
        String str2 = "mio4";
        System.out.println("str1 address : " + System.identityHashCode(str1));
        System.out.println("str2 address : " + System.identityHashCode(str1));
        System.out.println("str1 == str2 : " + (str1 == str2) + "\n");

        String str3 = new String("mio4");
        String str4 = new String("mio4");
        System.out.println("str3 address : " + System.identityHashCode(str3));
        System.out.println("str4 address : " + System.identityHashCode(str4));
        System.out.println("str3 == str4 : " + (str3 == str4));
    }

Run the above code, you can get the following results:

num1 == num2 : true

str1 address : 1639705018
str2 address : 1639705018
str1 == str2 : true

str3 address : 1627674070
str4 address : 1360875712
str3 == str4 : false

It can be seen that the memory addresses of str1 and str2 are both 1639705018, so the use ==judgment is true,

But the addresses of str3 and str4 are different, so it is judged as false.

2. equals() method

2.1 Object class equals()

In the Java language, all classes inherit from Objectthis super class, and there is also a equals()method in this class , so let's take a look at this method first.

It can be seen that this method is very simple, it is to compare the memory address of the object. Therefore, when the object does not override this method, this method is used by default, that is, the memory address value of the object is compared. But classes like String and Integer have been rewritten equals(). StringTake the following as an example.

2.2 String class equals()

Obviously, the equals() method of String only compares its  data value , not the memory address of the object   .

In order  String for example to test:

public static void main(String[] args) {
        String str1 = "mio4";
        String str2 = "mio4";

        String str3 = new String("mio4");
        String str4 = new String("mio4");

        System.out.println("str1 address : " + System.identityHashCode(str1));
        System.out.println("str2 address : " + System.identityHashCode(str1));
        System.out.println("str1.equals(str2) : " + str1.equals(str2) + "\n");

        System.out.println("str3 address : " + System.identityHashCode(str3));
        System.out.println("str4 address : " + System.identityHashCode(str4));
        System.out.println("str3.equals(str4) : " + str3.equals(str4) + "\n");
    }

The test output is as follows, it can be seen str3and str4the different addresses, but because the same string String content, it is determined that equals true

str1 address : 1639705018
str2 address : 1639705018
str1.equals(str2) : true

str3 address : 1627674070
str4 address : 1360875712
str3.equals(str4) : true

3. hashCode() method

3.1 Why is there this method? scenes to be used

There are three types of collections in Java, one is List, the other is Queue, the elements in the collection are ordered, and the elements can be repeated; the other is Set, the elements in a collection are unordered, but the elements are not repeat.

  • So, here is a more serious problem: if you want to ensure that the elements are not repeated, what should be the basis for judging whether two elements are repeated? This is the  Object.equals  method. However, if the check is performed every time an element is added, when there are many elements, the number of comparisons of the elements added to the set will be very large. In other words, if there are already 1000 elements in the collection, when the 1001st element is added to the collection, it will call the equals method 1000 times. This will obviously greatly reduce efficiency. Therefore, Java uses the principle of hash tables . In this way, we use a hash algorithm to calculate a value for each element to be stored in the set, and then calculate the position of the element in the array based on the value. Therefore, when adding new elements to the collection, it can be divided into two steps:   
    • Call the hashCode method of this element first, and then calculate the position of the element in the array based on the obtained value. If there is no element at this position, then store it directly in this position;
    • If there is already an element at this position, then call its equals method to compare with the new element: if it is the same, it will not be stored, otherwise, it will be stored in the linked list corresponding to this position (the implementation of HashSet, HashMap and Hashtable in Java) Put the element at the head of the linked list).

3.2 hashCode() and equals() association

 Prerequisite: When  talking about hashCode, you have to say equals method, both of which are methods in the Object class. Since the Object class is the base class of all classes, these two methods can be overridden in all classes.

  • Principle 1:  If x.equals(y) returns "true", then the hashCode() of x and y must be equal;
  • Principle 2:  If x.equals(y) returns "false", then the hashCode() of x and y may or may not be equal;
  • Principle 3:  If the hashCode() of x and y are not equal, then x.equals(y) must return "false";
  • Principle 4:  Generally speaking, the equals method is called for users, while the hashcode method is generally not called by users;
  • Principle 5:  When an object type is used as an element of a collection object, then this object should have its own equals() and hashCode() design, and it must comply with the aforementioned principles.

In summary, the things to note are:

  • equals two objects with equal hashCode must be equal
  • For two objects whose equals method is not equal, the hashCode may be equal

0x1 High-frequency interview questions

1. Have you seen the String source code? Why use final modification?

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {}

Core explanation:

1. In order to achieve the string pool

2. In order to thread safety

3. In order to achieve String can create HashCode immutability

  • The final modified String represents the non-inheritability of String, and the final modified char[] represents the unchangeability of the stored data. But: Although final represents immutability, but just the reference address is immutable, it does not mean that the array itself will not change.
  • Final can also change the array itself. At this time, private is also useful , because the two guarantee the immutability of String.
  • So why ensure that String is immutable, because only when the string is immutable, the string pool can be realized . The implementation of string pool can save a lot of heap space at runtime, because different string variables all point to the same string in the pool. But if the string is variable, then String.intern() will not be implemented, because in this case, if the variable changes its value, the values ​​of other variables pointing to this value will also change.
  • Because the string is immutable, the HashCode is cached when it is created and does not need to be recalculated. This makes the string very suitable as a key in the Map, and the processing speed of the string is faster than other key objects. This is that the keys in HashMap often use strings.

2. What are the initialization methods for String?

StringType initialization is divided into two categories in Java:

  • One type is initialized by wrapping a character in double quotes;
  • The other is newto initialize an Stringinstance like a normal object through keywords .

The former opens up a constant in the constant pool l and returns the corresponding reference, while the latter opens up a constant in the heap and then returns the corresponding object. Therefore, the reference of the two is definitely different:

public static void main(String... args) {
    String s1 = "abcd";
    String s2 = new String("abcd");
    System.out.println(s1 == s2);   // false
}

The constants in the constant pool can be shared to save memory overhead and creation time overhead (this is also the reason for the introduction of the constant pool), for example:

public static void main(String... args) {
    String s1 = "abcd";
    String s2 = "abcd";
    System.out.println(s1 == s2);   // true
}

Combining the two, you can actually answer another common interview question:

public static void main(String... args) {
    String s = new String("abcd");
}

How many objects does this sentence create?

First of all, there is no doubt that "abcd"it is an object itself, which is placed in the constant pool. And because of the newkeywords used here , the sresulting object must be created in the heap. So, there are actually 2 objects created here.

It should be noted that if there is already "abcd"this string somewhere else before this function is called , then it has been created in the constant pool in advance. At this time, only one object will be created here, that is, the new String("abcd")object created in the heap .

3. Is String thread safe?

String is an immutable class. Once a String object is created, we cannot change its value. Therefore, it is thread-safe and can be safely used in a multi-threaded environment.

4. Why do we often use String as the key when using HashMap?

Because a string is immutable, when a string is created, its hashcode is cached and does not need to be calculated again. Because the internal implementation of HashMap uses the hashcode of the key to determine the storage location of the value, it is faster than other objects. This is why we usually use String as the HashMap object.

5. What is the intern() method of String?

String.intern()Method, constants can be added to the constant pool (constant pool) during runtime. The way it works is:

  1. If there is a constant in the constant pool that is exactly equal to the value of this string, the intern()method returns a reference to the constant that exists in the constant pool.
  2. If there is no constant in the constant pool that happens to be equal to the value of this string, a new constant is created in the constant pool and the value of this string is assigned to the newly created constant in the constant pool. intern()The method returns a reference to this newly created constant.

Example:

public static void main(String... args) {
    String s1 = "abcd";
    String s2 = new String("abcd");

    /**
     * s2.intern() will first search String constant pool,
     * of which the value is the same as s2.
     */
    String s3 = s2.intern();
    // As s1 comes from constant pool, and s3 is also comes from constant pool, they're same.
    System.out.println(s1 == s3);
    // As s2 comes from heap but s3 comes from constant pool, they're different.
    System.out.println(s2 == s3); 
}

/**
 * Output:
 *  true
 *  false
 */

Recalling the first part of the beginning, why should we introduce intern()this function? It is because although it "abcd"is allocated in the constant pool, once it is used new String("abcd"), a new abcdobject with a value will be created in the heap . Just imagine, if there are 100 such sentences, isn't it necessary to create 100 objects of the same value in the heap? ! This results in inefficient operation and waste of space.

Therefore, if intern()it is introduced, it will go directly to the constant pool to find whether there are String objects with the same value, which greatly saves space and improves operating efficiency.

6. Some programming questions about the constant pool (1)

String s1 = "ab";
String s2 = "abc";
String s3 = s1 + "c";

System.out.println(s3 == s2);        //false  不相等,s1是变量,编译的时候确定不了值,在内存中会创建值,s3在堆内存中,。s2在常量池,所以不相等。
System.out.println(s3.equals(s2));    //true  比较两个对象的值相等。

Explanation of the above code:

String s1 = "abc"; String s2 = "abc";

s1 will be created in the constant pool, s2 will first check if there is any in the constant pool, if so, point to it, if not, create one in the constant pool and point to it. So the two comparisons of s1 and s2 are the same.

7. Some programming questions about the constant pool (2)

String s1 = new String("Hello");  
String s2 = new String("Hello");

The answer is 3 objects.

First, line 1 is the "hello" object in the string pool.

Second, line 1, a new string with the value "hello" in the heap memory.

Third, line 2, a new string with "hello" in the heap memory. Here the strings in the "hello" string pool are reused.

8. Talk about the difference between String, StringBuffer and StringBuilder?

  • String is an immutable class. Whenever we operate on String, a new string is always created. Operating String is very resource intensive, so Java provides two tool classes to manipulate String: StringBuffer and StringBuilder.
  • StringBuffer and StringBuilder are mutable classes, StringBuffer is thread-safe, StringBuilder is not thread-safe. Therefore, when multiple threads operate on the same string, we should choose StringBuffer. Because there is no need to deal with multithreading, StringBuilder is more efficient than StringBuffer.
  • Extended question: Why is StringBuffer thread safe? —All methods in StringBuffer are synchronized modified:

Guess you like

Origin blog.csdn.net/a159357445566/article/details/108587358