Filling the hole: Java’s String class (1)

Common methods

String construction

Let’s take a look at the String construction method in the source code

Common string

 //"hello" is a string constant, without \0 mark at the end
        String str = "hello";
        System.out.println(str);//hello

        String str2 = new String();
        System.out.println(str2);//No output

        String str3 = new String("pppp");
        System.out.println(str3);//pppp

String array

 char[] array = {'a','b','c'};
        String str4 = new String(array);
        System.out.println(str4);//abc

        char[] array1 = {'a','b','c'};
        String str5 = new String(array1,1,2);
        System.out.println(str5);//bc

?String is a reference type and does not store the string itself internally. String class instance variables

In other words, a String actually looks like this

Let’s try to analyze this code

String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;

Assume that the address of s1 is 0x9. After new String, create a new String in the heap with value 0x8. Throw “hello” to this String. Then the address of “hello” is also 0x8. s1 finds “hello” based on the address of value. “Object

String length

Analysis

 String str4 = "";
        System.out.println(str4.length());
        String str5 = null;
        System.out.println(str5.length());

str4 points to an empty string. An empty string is also a string and has a length, but the length is 0.

str5 does not point to any string, so how can it have a length?

We can also use isEmpty() to check

 String str4 = "";
        System.out.println(str4.isEmpty());
        String str5 = null;
        System.out.println(str5.isEmpty());

Because str4 is an empty string, it will definitely return true, and str5 points to nothing, then it will return a null pointer exception.

,

String comparison

equals()

Analysis: Is this printed result true?

 String s1 = new String("hello");
        String s2 = new String("hello");
        System.out.println(s1 == s2);

The answer is false, == compares the addresses of s1 and s2, because the addresses of s1 and s2 are different when they apply for memory space. How can they be equal?

Then we have to invite .equals(), a method in String, to help with string comparison.

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i + + ;
                }
                return true;
            }
        }
        return false;
    }

We can see from the code that equals compares characters one by one in the string, and the return value is of Boolean type.

compareTo()

Suppose I have two strings and I want to compare which of the two strings is bigger and which is smaller.

 String s1 = new String("abc");
        String s2 = new String("acd");

String implements the Comparable interface, so we can call the compareTo method to easily help us solve the problem.

 System.out.println(s1.compareTo(s2));

The return type of this method is int type. If s1>s2 returns a positive number; s1=s2 returns 0; s1

So we generally use >0 or =0 or <0 for string comparison.

Usually when we enter the verification code, the system ignores case when comparing whether two strings are equal.

In fact, it is to call the compareToIgnoreCase method

String search

charAt()

If the number is too large, the subscript is out of bounds

indexOf()

Find the subscript of the first occurrence of a character from beginning to end

You can also find the position of the substring in the main string

Start searching from the specified location

lastIndexOf()

Look backwards

This can be extended to the BF algorithm and KMP algorithm. I will publish a blog later, everyone is welcome to pay attention.

String conversion

1. Numeric and string conversion

The valueOf() method supports various forms of numerical values and can convert them into strings.

 String s = String.valueOf(19.9);
        System.out.println(s);

How do you convert a string into a number?

 int data = Integer.parseInt("198");
        System.out.println(data);

Which data type corresponds to which parsexx? If 19.8 is passed to parseInt, the program will report a numerical format error.

2. String case conversion

toUpperCase() converts lowercase to uppercase; toLowerCase() converts uppercase to lowercase

 String s1 = "hello";
        //Converting to uppercase is not based on the original
        //After converting to uppercase, it is a new object
        //If you only print s1, it will only be in lowercase
        String ret = s1.toUpperCase();
        System.out.println(ret);

3. Convert string to array

Above we mentioned how to convert an array into a string (direct violent conversion with new String(array)). In fact, a string can also be converted into an array (using toCharArray())

The return value of the toCharArray() method is an array of char type, so we need to use a new array to receive it

4.Formatting

 String s = String.format("%d-%d-%d",2023,11,9);
        System.out.println(s);

String replacement

Let’s take a look at the replace method first

For example, in this string, all ab in the string are replaced by 99

replaceFirst(): Replace the first content

Only the first ab is replaced here, and the other ab are not changed.

String splitting

split(): split string

 String str = "hello abc world";
        String[] ret = str.split(" ");//Split the above string according to spaces
        for (int i = 0; i < ret.length; i + + ) {
            System.out.println(ret[i]);
        }

question:

Why is there no result when printing after splitting a string with “.”?

?1. The characters “|”, “*”, and ” + ” must be escape characters, preceded by “”.

2. And if it is “”, then it must be written as “\”.

3. If there are multiple delimiters in a string, you can use “|” as a hyphen.

Given this string, split each word out

String str = "name=zhangsan & amp;age=18" ;

The first way of writing is to use | to separate the two segmentation judgment symbols.

 String[] ret = str.split("=| & amp;");
        for (int i = 0; i < ret.length; i + + ) {
            System.out.println(ret[i]);
        }

The second way of writing: multiple division method

 String[] ret = str.split(" & amp;");
        for (int i = 0; i < ret.length; i + + ) {
            System.out.println(ret[i]);
            String x = ret[i];
            //Based on the first division, perform the second division according to "="
            String[] ret2 = x.split("=");
            for (int j = 0; j < ret2.length; j + + ) {
                System.out.println(ret2[j]);
            }
        }

String interception

substring(): Two parameters represent the interval, and one parameter represents where to start cutting.

 String str = "ababc";
        String ret = str.substring(0,3);//Intercept string range [0,3)
        System.out.println(ret);

 String ret1 = str.substring(2);
        System.out.println(ret1);

Other methods

Immutability of strings

The String class is immutable by design

String is modified by final, indicating that this class cannot be inherited

The two instance variables of String are both modified by private. These two values cannot be obtained externally and cannot be modified.

?String is immutable not because the value is modified by final. The final modified reference type indicates thatthe reference variable cannot refer to other objects, but the content of the referenced object can be modified. Next, let’s talk about how Modified.

String modification

Take a look at the following example

 String str = "hello";
        //System.out.println(str);//hello
        str = str + "abc";
        System.out.println(str);//helloabc

The process of adding abc to helloabc does not mean modifying the value of str (because you cannot get the value after being modified by private), but creating a new object “helloabc” and letting str point to this new object.

However, if you simply use the method of String to generate new objects to modify the string, the efficiency is very low because a bunch of new objects will be created. In fact, the java editor uses another method

Let’s take the above code to peek into its underlying layer

Can’t understand the bottom layer? Let me translate it using code

 public static void main(String[] args) {
        String str = "hello";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(str);
        stringBuilder.append("abc");
        str = stringBuilder.toString();
        System.out.println(str);
    }

The underlying code constructs a new object stringBuilder. The traditional String object is immutable, but with the mutable object StringBuilder, the string can be modified, and it is very efficient (see the reasons below). Then let’s talk about the StringBuilder object next.

StringBuilder and StringBuffer

Let’s first compare the efficiency of String’s own creation of String objects and the efficiency of using StringBuilder or StringBuffer.

 public static void main(String[] args) {
        long start = System.currentTimeMillis();
        String s = "";
        for(int i = 0; i < 10000; + + i){
            s + = i;
        }
        long end = System.currentTimeMillis();
        System.out.println("String: " + (end - start));

        start = System.currentTimeMillis();
        StringBuffer sbf = new StringBuffer("");
        for(int i = 0; i < 10000; + + i){
            sbf.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer: " + (end - start));
        
        start = System.currentTimeMillis();
        StringBuilder sbd = new StringBuilder();
        for(int i = 0; i < 10000; + + i){
            sbd.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder: " + (end - start));
    }

look at the inner layer

StringBuilder always exists in every loop in the inner layer, which means that this object has been used to modify strings after it was created. Compared with String’s method of constantly creating new objects and then destroying old objects, this method is obviously more efficient.

The same is true for StringBuffer

The difference between StringBuilder and StringBuffer

The bottom layer of the append method of StringBuilder

The bottom layer of the append method of Stringbuffer

StringBuffer has one more synchronized, which means thread safety is ensured. In other words, StringBuffer is a thread-safe class.

What is thread safety?

You can refer to this article. What is thread safety? Do you really understand it? – Know almost

Here we can simply use a toilet example to explain. Suppose a person wants to go to the toilet. A toilet can only accommodate one person. This person can be regarded as a thread. The toilet must have a door lock to ensure the safety of the people inside. This lock is the so-called thread security, which can ensure that people outside (other threads) cannot enter. When this person comes out after using the toilet, the lock is opened, and the next person enters and the lock is closed again.

The synchronized above can actually be used as a lock to prevent other threads from entering.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 139,299 people are learning the system