Shy, there are so many positions for Java string stitching

Second Brother, when I was a sophomore this year, I read a passage in the Alibaba Java Development Manual that you shared that said, "In a loop, it is better to use StringBuilder's append method for stitching strings than the + operator."Why on earth, I always use the'+'operator!Can I write an article to analyze when my brother is free?

Just yesterday, a reader named Xiaocai tweeted me about this.

My first feeling when I saw this WeChat was: You're too delicious for a side dish. I don't know what to do.I guess you'll feel the same way when you're reading this article.

But ask yourself, in I For the first two years as a programmer, I didn't know what to do.encounter Character string Stitching on the "+" operator, whether or not in the circulation.I wasn't as lucky as he was when compared to pickles, and there was an enthusiastic Second Brother who could share this valuable development manual.

Since I'm so eager to share, it's not as good as being nice, is it?I'll write a serious article to confuse the dishes.

01,'+'operator

To say posture, the'+'operator must be one of the most common types of string stitching, not one.

String chenmo = "silent";
String wanger = "WangTwo";

System.out.println(chenmo + wanger);

Let's decompile this code using JAD.

String chenmo = "\u6C89\u9ED8"; // silent
String wanger = "\u738B\u4E8C"; // WangTwo
System.out.println((new StringBuilder(String.valueOf(chenmo))).append(wanger).toString());

I went and replaced the'+'operator with StringBuilder's append method when it was originally compiled.That is to say, the'+'operator is just a formalism when splicing strings, making it easier for developers to use, simpler looking code, and smoother to read.It's a grammatical sugar for Java.

02,StringBuilder

StringBuilder's append method is the second commonly used string stitching position, except for the'+'operator.

Let's first look at the source code for the append method of the StringBuilder class:

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Nothing to see in these three lines of code is the append method of the parent AbstractStringBuilder:

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

1) Determine whether the stitched string is null or not, and if so, treat it as a string "null".The source code for the appendNull method is as follows:

private AbstractStringBuilder appendNull() {
    int c = count;
    ensureCapacityInternal(c + 4);
    final char[] value = this.value;
    value[c++] = 'n';
    value[c++] = 'u';
    value[c++] = 'l';
    value[c++] = 'l';
    count = c;
    return this;
}

2) Whether the length of the stitched character array exceeds the current value, if it exceeds, expand and copy.The source code for the ensureCapacityInternal method is as follows:

private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    if (minimumCapacity - value.length > 0) {
        value = Arrays.copyOf(value,
                newCapacity(minimumCapacity));
    }
}

3) Copy the stitched string str into the target array value.

str.getChars(0, len, value, count)

03,StringBuffer

StringBuffer followed by StringBuilder, both like twins, and both, but Big Brother StringBuffer is thread safe because he breathes two more breaths of fresh air.

public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}

The append method of the StringBuffer class has one more keyword synchronized than StringBuilder, ignoring toStringCache = null for now.

synchronized is a very familiar Java keyword and a synchronization lock.The method it modifies is called synchronization and thread-safe.

04. Conat method of String class

In terms of posture alone, the concat method of the String class is like an append of the StringBuilder class.

String chenmo = "silent";
String wanger = "WangTwo";

System.out.println(chenmo.concat(wanger));

At this point in the article, a wonderful idea suddenly came to me.If there are two lines of code like this:

chenmo += wanger
chenmo = chenmo.concat(wanger)

How different are they?

Previously, we learned that chenmo += wanger is actually equivalent to (new StringBuilder (String.valueOf (chenmo)). append (wanger). toString ().

To explore the difference between the'+'operator and concat, you actually need to look at the difference between the append and concat methods.

The append method's source code was previously analyzed.Let's look at the source code for the concat method.

public String concat(String str) {
    int otherLen = str.length();
    if (otherLen == 0) {
        return this;
    }
    int len = value.length;
    char buf[] = Arrays.copyOf(value, len + otherLen);
    str.getChars(buf, len);
    return new String(buf, true);
}

1) If the length of the stitched string is 0, the string before stitching is returned.

if (otherLen == 0) {
    return this;
}

2) Copy the character array value of the original string into the variable buf array.

char buf[] = Arrays.copyOf(value, len + otherLen);

3) Copy the stitched string str into the character array buf and return a new string object.

str.getChars(buf, len);
return new String(buf, true);

From source code analysis, we can roughly draw the following conclusions:

1) If the concatenated string is null, a NullPointerException is thrown when concat, and the'+'operator is treated as a'null' string.

2) Conat is more efficient if the stitched string is an empty string (").After all, you don't need a new StringBuilder object.

3) If you stitch too many strings, concat will be less efficient, because the more string objects you create, the more expensive it will be.

Attention!!!

Ask weakly, are there any other students using JSP?The'+'operator is not allowed to stitch strings in EL expressions, and concat is the only option.

${chenmo.concat('-').concat(wanger)}

05. join method of String class

JDK 1.8 provides a new string stitching posture: the String class adds a static method join.

String chenmo = "silent";
String wanger = "WangTwo";
String cmower = String.join("", chenmo, wanger);
System.out.println(cmower);

The first parameter is a string connector, for example:

String message = String.join("-", "WangTwo", "Tert?", "Fun");

The output is: Is Wang Er-Taite interesting?

Let's look at the source code for the join method:

public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    // Number of elements not likely worth Arrays.stream overhead.
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}

A new class, StringJoiner, was found. The class name looks 6 and reads smoothly.StringJoiner is a class in the java.util package that constructs a sequence of characters reconnected by delimiters.Limited to the length of the text, this article has not been introduced much, interested students can go to understand.

06,StringUtils.join

In real-world projects, this class is often used when dealing with strings, org.apache.commons.lang3.StringUtils, whose join method is a new posture for string splicing.

String chenmo = "silent";
String wanger = "WangTwo";

StringUtils.join(chenmo, wanger);

This method is better at splicing strings in arrays without worrying about NullPointerException.

StringUtils.join(null)            = null
StringUtils.join([])              = ""
StringUtils.join([null])          = ""
StringUtils.join(["a", "b", "c"]) = "abc"
StringUtils.join([null, "", "a"]) = "a"

Looking at the source code, we can see that StringBuilder is still used internally.

public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
    if (array == null) {
        return null;
    }
    if (separator == null) {
        separator = EMPTY;
    }

    final StringBuilder buf = new StringBuilder(noOfItems * 16);

    for (int i = startIndex; i < endIndex; i++) {
        if (i > startIndex) {
            buf.append(separator);
        }
        if (array[i] != null) {
            buf.append(array[i]);
        }
    }
    return buf.toString();
}

When you read this, you will have the same feeling: I rely on (the sound is long), unexpectedly or unexpectedly, there are six positions of string stitching. When you return home at night, you must try them one by one.

07. A reply to the side dish

I'm sure when the vegetable reads this article, he will understand why Alibaba does not recommend string stitching using the "+" operator in the for loop.

Let's look at two pieces of code.

The first paragraph uses the'+'operator in the for loop.

String result = "";
for (int i = 0; i < 100000; i++) {
    result += "666";
}

In the second section, append is used in the for loop.

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100000; i++) {
    sb.append("666");
}

How long will these two pieces of code take?The results tested on my iMac are:

1) The first code executed in 6212 milliseconds

2) The second code executed in 1 millisecond

The gap is too big!Why?

I believe that many students already have their own answers: the first section of the for loop creates a large number of StringBuilder objects, while the second section of code has only one StringBuilder object from start to finish.

08, Last

Thank you for your reading. The original is not easy. If you like it, just give it a compliment. This will be my strongest writing power.If you find the article helpful and interesting, take a look at my public number Silence King II.

Keywords: Java less JSP JDK

Added by jacomus on Thu, 14 Nov 2019 00:43:09 +0200