Thinking logic of computer programs (30), thinking Logic

Source: Internet
Author: User

Thinking logic of computer programs (30), thinking Logic

The previous section introduced the String, and mentioned that if String modification operations are frequent, StringBuilder and StringBuffer classes should be used. The methods of these two classes are basically the same, and their implementation code is almost the same, the only difference is that StringBuffer is thread-safe, while StringBuilder is not.

The concept of thread and thread security will be detailed in subsequent sections. Here, we need to know that thread security is costly and affects performance. In most cases, there is no thread security problem for string objects and operations, and StringBuilder is suitable. Therefore, this section only discusses StringBuilder.

The basic usage of StringBuilder is also very simple. Let's take a look.

Basic usage

Create StringBuilder

StringBuilder sb = new StringBuilder();

Add a string using the append Method

Sb. append (""); sb. append (", exploring the nature of programming ");

Obtain the constructed string using the toString method.

System.out.println(sb.toString());

Output:

Ma Lao said programming, exploring the essence of Programming

In most cases, it is easy to use. Create a StringBuilder through new, add a string through append, and then obtain the constructed string through toString.

How is StringBuilder implemented?

Basic implementation principle

Internal composition and constructor

Similar to String, the StringBuilder class also encapsulates a character array, which is defined as follows:

char[] value;

Unlike String, it is not final and can be modified. In addition, unlike String, the character array does not necessarily have all locations in use. It has an instance variable that indicates the number of characters already used in the array, which is defined as follows:

int count;

StringBuilder inherits from AbstractStringBuilder. Its default constructor is as follows:

public StringBuilder() {    super(16);}

Call the constructor of the parent class. The constructor of the parent class is:

AbstractStringBuilder(int capacity) {    value = new char[capacity];}

That is to say, in the Code new StringBuilder (), an array of 16 characters is created internally, and the default value of count is 0.

Append implementation

Let's look at the append code:

public AbstractStringBuilder append(String str) {    if (str == null) str = "null";    int len = str.length();    ensureCapacityInternal(count + len);    str.getChars(0, len, value, count);    count += len;    return this;}

Append directly copies the characters to the internal character array. If the length of the character array is insufficient, it will be extended. The actual length is represented by count. Specifically, ensureCapacityInternal (count + len) ensures that the array length is sufficient to accommodate the newly added characters, str. getChars copies the new characters to the character array, and count + = len increases the actual length.

The Code of ensureCapacityInternal is as follows:

private void ensureCapacityInternal(int minimumCapacity) {    // overflow-conscious code    if (minimumCapacity - value.length > 0)        expandCapacity(minimumCapacity);}

If the length of the character array is smaller than the required length, you can call expandCapacity to extend the value. The Code of expandCapacity is:

void expandCapacity(int minimumCapacity) {    int newCapacity = value.length * 2 + 2;    if (newCapacity - minimumCapacity < 0)        newCapacity = minimumCapacity;    if (newCapacity < 0) {        if (minimumCapacity < 0) // overflow            throw new OutOfMemoryError();        newCapacity = Integer.MAX_VALUE;    }    value = Arrays.copyOf(value, newCapacity);}

The extended logic is to allocate a new array of sufficient length, copy the original content to the new array, and finally point the internal character array to the new array, this logic is implemented by the following code:

value = Arrays.copyOf(value, newCapacity);

In the next section, we will discuss the Arrays class. This section will not introduce it. We will mainly look at how newCapacity is calculated.

The minimumCapacity parameter indicates the minimum length required. Is it okay to allocate the minimum length? No, because it is the same as String. Memory Allocation is performed every append time, which is inefficient. Here, the extension policy is related to the current length. The current length is multiplied by 2, plus 2. If the length is not the minimum length, minimumCapacity is used.

For example, if the default length is 16 and the length is not enough, it is first expanded to 16*2 + 2, that is, 34, and then expanded to 34*2 + 2, that is, 70, then 70*2 + 2 is 142, which is an exponential scaling policy. Why add 2? It is probably because it can work the same way when the original length is 0.

Why is it so scalable? This is a compromise strategy. On the one hand, we need to reduce the number of memory allocations and avoid space waste. Exponential expansion is a common strategy that is widely used in computer programs related to memory allocation without knowing how long it will eventually take.

How long does it take to know in advance? You can call another StringBuilder constructor:

public StringBuilder(int capacity)

ToString implementation

After the string is constructed, let's look at the toString code:

public String toString() {    // Create a copy, don't share the array    return new String(value, 0, count);}

A new String is created based on the internal array. Note that this String constructor does not directly use the value array, but creates a new String to ensure the non-variability of the String.

More constructor methods and append Methods

There are two constructor methods for String and CharSequence parameters. Their codes are as follows:

public StringBuilder(String str) {    super(str.length() + 16);    append(str);}public StringBuilder(CharSequence seq) {    this(seq.length() + 16);    append(seq);}

The logic is also very simple. allocate 16 characters more and then call append to add the parameter characters.

Append has multiple reloads. You can accept various types of parameters, convert them to characters, and add them. These reload methods include:

public StringBuilder append(boolean b)public StringBuilder append(char c)public StringBuilder append(double d)public StringBuilder append(float f)public StringBuilder append(int i)public StringBuilder append(long lng)public StringBuilder append(char[] str)public StringBuilder append(char[] str, int offset, int len)public StringBuilder append(Object obj)public StringBuilder append(StringBuffer sb)public StringBuilder append(CharSequence s)public StringBuilder append(CharSequence s, int start, int end)

The specific implementation is direct and will not be described in detail.

There is also an append method that can add a Code Point:

public StringBuilder appendCodePoint(int codePoint) 

If codePoint is a BMP character, add a char; otherwise, add two char. If you are not clear about the concept of Code Point, see the profiling packaging class (below ).

Other modification methods

In addition to append, StringBuilder has some other modification methods. Let's take a look.

Insert

public StringBuilder insert(int offset, String str)

Insert the str string at the specified index offset. The original character is removed. If the offset is 0, it indicates that the string is inserted at the beginning, and the length () indicates that the string is inserted at the end. For example:

StringBuilder sb = new StringBuilder (); sb. append ("programming"); sb. insert (0, "Follow"); sb. insert (sb. length (), "Ma and you explore the essence of programming"); sb. insert (7, ","); System. out. println (sb. toString ());

The output is

Focus on programming, and explore the essence of programming with you.

Let's take a look at the insert implementation code:

public AbstractStringBuilder insert(int offset, String str) {    if ((offset < 0) || (offset > length()))        throw new StringIndexOutOfBoundsException(offset);    if (str == null)        str = "null";    int len = str.length();    ensureCapacityInternal(count + len);    System.arraycopy(value, offset, value, offset + len, count - offset);    str.getChars(value, offset);    count += len;    return this;}

The idea is to first move the content starting from offset in the original array to n positions after ensuring that there is enough length, and n is the length of the string to be inserted, then copy the string to be inserted to the offset position.

The System. arraycopy method is called to move the location. This is a common method and its declaration is as follows:

public static native void arraycopy(Object src,  int  srcPos,                                        Object dest, int destPos,                                        int length);

Copy the length elements starting with srcPos in the array src to the destPos in the array dest. This method has the following advantages: Even if src and dest are the same array, it can be correctly processed. For example, see the following code:

int[] arr = new int[]{1,2,3,4};System.arraycopy(arr, 1, arr, 0, 3);System.out.println(arr[0]+","+arr[1]+","+arr[2]);

Here, both src and dest are arr, srcPos is 1, destPos is 0, and length is 3, which indicates that the three elements starting with the second element are moved to the beginning, so the output is:

2,3,4

The declaration of arraycopy has a modifier native, indicating that its implementation is implemented through the Java Local interface, and the Java Local interface is a technology provided by Java, it is used to call non-Java code in Java. In fact, arraycopy is implemented in C ++. Why is it implemented in C ++? This function is very common, and the implementation efficiency of C ++ is much higher than that of Java.

Other insertion Methods

Similar to append, insert also has many reload methods, as listed below:

public StringBuilder insert(int offset, double d)public StringBuilder insert(int offset, Object obj)

Delete

Delete characters in the specified range

public StringBuilder delete(int start, int end) 

The implementation code is as follows:

public AbstractStringBuilder delete(int start, int end) {    if (start < 0)        throw new StringIndexOutOfBoundsException(start);    if (end > count)        end = count;    if (start > end)        throw new StringIndexOutOfBoundsException();    int len = end - start;    if (len > 0) {        System.arraycopy(value, start+len, value, start, count-end);        count -= len;    }    return this;}

It is also implemented through System. arraycopy. System. arraycopy is widely used in the internal implementation of StringBuilder.

Delete a character

public StringBuilder deleteCharAt(int index)

Replace

public StringBuilder replace(int start, int end, String str)

For example

StringBuilder sb = new StringBuilder (); sb. append ("programming"); sb. replace (3, 5, "Java"); System. out. println (sb. toString ());

Program output:

Ma Lao said Java

Replace one character

public void setCharAt(int index, char ch)

 Flip string

public StringBuilder reverse()

This method is not just a simple flip of the char in the array. For the supplementary characters, the character after the simple flip is invalid. This method can ensure that the characters are still valid. This is done by checking the supplementary characters separately, implement secondary flip. For example:

StringBuilder sb = new StringBuilder (); sb. append ("a"); sb. appendCodePoint (0x2F81A); // additional characters:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.