Stop asking me for strings in interviews

Strings are widely used in Java programming. In Java, strings are objects, and Java provides the String class to create and manipulate strings.

Introduction of the String

String definition:

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

Why design immutable classes?

String is designed to be immutable for the following reasons: efficiency and security.

  • Efficiency: 1. In earlier JVM implementations, methods modified by final were converted to inline calls to improve execution efficiency. Since Java SE5/6, this approach has been gradually abandoned. Therefore, in the current version of Java SE, there is no need to consider using final to improve method invocation efficiency. Make the method final only if you are sure that you do not want the method to be overridden. 2. Cache hashCode, String is immutable, so hashcode does not change, so cache is meaningful, do not need to recalculate.
  • Security: String is often used as a parameter type for network connection, file operation, etc., which can have unexpected results if it can be changed.

Test mastery

In order not to waste your time, take a look at the following topics, if you are clear, you can skip this article.

public class Test {
    public static void main(String[] args) {
        String str1 = "HelloFlyapi";
        String str2 = "HelloFlyapi";
        String str3 = new String("HelloFlyapi");
        String str4 = "Hello";
        String str5 = "Flyapi";
        String str6 = "Hello" + "Flyapi";
        String str7 = str4 + str5;

        System.out.println("str1 == str2 result: " + (str1 == str2));

        System.out.println("str1 == str3 result: " + (str1 == str3));

        System.out.println("str1 == str6 result: " + (str1 == str6));

        System.out.println("str1 == str7 result: " + (str1 == str7));

        System.out.println("str1 == str7.intern() result: " + (str1 == str7.intern()));

        System.out.println("str3 == str3.intern() result: "+ (str3 == str3.intern())); }}Copy the code

String creation method

As you can see from the above, there are two ways to create a String:

Direct assignment

  • This method creates objects in the string constant pool in the method area
    String str = "flyapi";
    Copy the code

The constructor

  • This creates objects in heap memory

    String str = new String();
    Copy the code

Analysis of the

To understand String, you need to understand the stack, heap, and method areas in JVM memory. The brief picture is as follows:

! [JVM memory map](images/JVM memory.png)

  • str1 == str2

    String str1 = "HelloFlyapi";
    String str2 = "HelloFlyapi";
    
    System.out.println(str1 == str2); // true
    Copy the code

When executing the first sentence, the JVM looks for the presence of the HelloFlyapi in the constant pool and returns a reference from the constant pool if it does. When it does not exist, an object is created in the character creation constant pool and a reference is returned.

When executing the second sentence, the same goes for returning the reference to the object created in the first sentence, since the first sentence has already been created in the constant pool.

  • str1 == str3

    String str1 = "HelloFlyapi";
    String str3 = new String("HelloFlyapi");
    
    System.out.println(str1 == str3); // false
    Copy the code

Execute the first sentence as above.

When the second sentence is executed, an object is created in the heap, and an object is created in the constant pool when there is no ‘HelloFlyapi’ in the character creation constant pool; When a constant pool already exists, no new one is created.

  • str1 == str6

    String str1 = "HelloFlyapi";
    String str6 = "Hello" + "Flyapi";
    
    System.out.println(str1 == str6); // true
    Copy the code

Since “Hello” and “Flyapi” are constants, the second sentence is automatically compiled to ‘String str6 = “HelloFlyapi”; ‘

  • str1 == str7

    String str1 = "HelloFlyapi";
    String str4 = "Hello";
    String str5 = "Flyapi";
    String str7 = str4 + str5;
    
    System.out.println(str1 == str7); // false
    Copy the code

The first three variables store reference addresses in the constant pool.

When the fourth sentence is executed, the JVM creates a StringBuilder object based on STR4 in the heap, and then calls the StringBuilder append() method to merge with STR5. The toString() method is then called to create a String in the heap and assign a reference to the String to STR7.

Commonly used method

Here are the methods supported by the String class. For more details, see the Java String API documentation:

methods describe
char charAt(int index) Returns the char value at the specified index.
int compareTo(Object o) Compare this string to another object.
int compareTo(String anotherString) Compares two strings in lexicographical order.
boolean endsWith(String suffix) Tests whether the string ends with the specified suffix.
boolean equals(Object anObject) Compares this string to the specified object.
boolean equalsIgnoreCase(String anotherString) Compares this String with another String, regardless of case.
byte[] getBytes() Encode this String as a byte sequence using the platform’s default character set, and store the result in a new byte array.
byte[] getBytes(String charsetName) Encodes this String as a byte sequence using the specified character set and stores the result in a new byte array.
int indexOf(int ch) Returns the index at the first occurrence of the specified character in this string.
int indexOf(int ch, int fromIndex) Returns the index at the first occurrence of the specified character in this string, starting the search from the specified index.
int indexOf(String str) Returns the index at the first occurrence of the specified substring in this string.
int indexOf(String str, int fromIndex) Returns the index of the specified substring at its first occurrence in this string, starting with the specified index.
String intern() Returns the normalized representation of a string object.
int lastIndexOf(int ch) Returns the index at the last occurrence of the specified character in this string.
int lastIndexOf(int ch, int fromIndex) Returns the index of the last occurrence of the specified character in this string, starting at the specified index for a reverse search.
int lastIndexOf(String str) Returns the index of the rightmost occurrence of the specified substring in this string.
int lastIndexOf(String str, int fromIndex) Returns the index of the last occurrence of the specified substring in this string, starting with the specified index in a reverse search.
int length() Returns the length of this string.
boolean matches(String regex) Tells whether this string matches the given regular expression.
String replace(char oldChar, char newChar) Returns a new string obtained by replacing all occurrences of oldChar in this string with newChar.
String replaceAll(String regex, String replacement) Replaces all substrings of this string that match the given regular expression with the given replacement.
String replaceFirst(String regex, String replacement) Replaces the first substring matching the given regular expression with the given replacement.
String[] split(String regex) Split this string based on the match of the given regular expression.
String[] split(String regex, int limit) Splits the string based on the regular expression matching the given.
boolean startsWith(String prefix) Tests whether this string starts with the specified prefix.
boolean startsWith(String prefix, int toffset) Tests whether substrings of this string starting with the specified index start with the specified prefix.
String substring(int beginIndex) Returns a new string that is a substring of this string.
String substring(int beginIndex, int endIndex) Returns a new string that is a substring of this string.
char[] toCharArray() Converts this string to a new character array.
String toLowerCase() Convert all characters in this String to lowercase using the rules of the default locale.
String toUpperCase() Convert all characters in this String to uppercase using the default locale rules.
String trim() Returns a copy of the string, ignoring leading and trailing whitespace.

String related

Because of the immutability of strings, String changes were inefficient, and StringBuilder and StringBuffer appeared in later JDK versions.

class variability Thread safety
String immutable security
StringBuffer variable security
StringBuilder variable The security
  • Used to choose
  1. String is used when there are a few connections
  2. Use StringBuilder when there is a large number of connection operations under a single thread
  3. Use StringBuffer when there is a large number of connection operations in multiple threads

Common String interview questions

  • String STR = new String(” ABC “) How many instances have been created?

This question is actually not rigorous, but the interview will generally encounter, so we want to add to explain.

Classes are loaded and executed separately: two are created

  1. When the class is loaded, “ABC” is created and resides in the character creation constant pool (if not previously created in the load).
  2. When this statement is executed, because the String instance corresponding to “ABC” already exists in the String constant pool, the JVM copies the instance to the heap and returns the reference address.

Bytecode we can see:

STR = new String(” ABC “)

Byte code:

    Code:
       0: new           #2 // class java/lang/String
       3: dup
       4: ldc           #3 // String abc
       6: invokespecial #4 // Method java/lang/String."
      
       ":(Ljava/lang/String;)
      
       9: astore_1
      10: return
Copy the code

Only one object is created at execution time (#2).

Questions about the interview, can see the answer: a large cattle rednaxelafx.iteye.com/blog/774673

I have arranged some interview documents and videos for you. The official account replies: Architect or interview video

This article is first published in the wechat public number: code combat