String concatenation in java

String is the most commonly used data type in Java.

This article is also a supplement to the knowledge about strings in Java. It mainly introduces the knowledge about string splicing. This article is based on jdk1.8.0_181.

string concatenation

String splicing is something we often do in Java code, which is to splice multiple strings together.

We all know that String is an immutable class in Java , so once it is instantiated it cannot be modified.

Once an instance of an immutable class is created, the values ​​of its member variables cannot be modified. This design has many advantages, such as hashcode can be cached, more convenient to use, and more secure.

But since strings are immutable, what about string concatenation?

String immutability and string concatenation

In fact, all so-called string splicing is to regenerate a new string. The following string concatenation code:

String s = "abcd";
s = s.concat("ef");

In fact, the s we got in the end is already a new string. As shown below

![][8]

What is saved in s is a reference to a recreated String object.

So, in Java, how to do string concatenation? There are many ways to concatenate strings, here are a few of the more commonly used ones.

Using +concatenated strings

In Java, the easiest way +to concatenate strings is to use symbols directly. like:

String wechat = "Hollis";
String introduce = "每日更新Java相关技术文章";
String hollis = wechat + "," + introduce;


In addition to using concat+ to concatenate strings, you can also use the concat method in the String class to concatenate strings. like:

String wechat = "Hollis";
String introduce = "每日更新Java相关技术文章";
String hollis = wechat.concat(",").concat(introduce);

StringBuffer

Regarding strings, in addition to defining a class that can be used to define string constants , Java Stringalso provides classes that can be used to define string variables , StringBufferand its objects can be expanded and modified.

StringBufferStrings can be concatenated conveniently . like:

StringBuffer wechat = new StringBuffer("Hollis");
String introduce = "每日更新Java相关技术文章";
StringBuffer hollis = wechat.append(",").append(introduce);


In addition to StringBuilderStringBuffer , there is another class StringBuilderthat can also be used, and its usage is StringBuffersimilar. like:

StringBuilder wechat = new StringBuilder("Hollis");
String introduce = "每日更新Java相关技术文章";
StringBuilder hollis = wechat.append(",").append(introduce);

In addition to the built-in string concatenation methods in JDK, StringUtils.join
can also use the string concatenation method names provided in some open source class libraries, such as the apache.commons中provided StringUtilsclasses, in which joinmethods can concatenate strings.

String wechat = "Hollis";
String introduce = "每日更新Java相关技术文章";
System.out.println(StringUtils.join(wechat, ",", introduce));

Here is a brief introduction, the main function of the join method provided in StringUtils is: splicing arrays or collections together with a splicing character to form a new string, such as:

String []list  ={"Hollis","每日更新Java相关技术文章"};
String result= StringUtils.join(list,",");
System.out.println(result);
//结果:Hollis,每日更新Java相关技术文章

Moreover, the String class in Java8 also provides a static join method, the usage is similar to StringUtils.join.

The above are the five commonly used methods of splicing strings in Java, so which one is better to use? +Why is it not recommended to use string concatenation in the loop body in the Alibaba Java Development Manual ?

(Statutes on string concatenation in the Alibaba Java Development Manual)

The implementation principle of using +concatenated strings

Regarding this knowledge point, as introduced in the previous chapter, it is mainly realized through the append method of StringBuilder.

How concat is implemented

Let's take a look at the source code of the concat method again and see how this method is implemented.

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);
}

This code first creates a character array whose length is the sum of the lengths of the existing string and the string to be concatenated, then copies the values ​​of the two strings into a new character array, and uses this character array to create a new String object and return.

Through the source code, we can also see that after the concat method, a new String is actually new, which also echoes the invariance of the string we mentioned earlier.

StringBuffer和StringBuilder

Next, let's look at the realization principle of StringBufferand StringBuilder.

Similar to Stringclasses, StringBuilderclasses also encapsulate a character array, defined as follows:

char[] value;

The difference Stringis that it is not final, so he can be modified. In addition, unlike Stringthe character array, not all positions in the character array have been used. It has an instance variable, which indicates the number of characters used in the array, and is defined as follows:

int count;

Its append source code is as follows:

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

This class inherits AbstractStringBuilderthe class, look at its appendmethod:

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;
}

append will directly copy the characters to the internal character array, if the length of the character array is not enough, it will be extended.

StringBufferAnd StringBuildersimilar, the biggest difference is that StringBufferit is thread-safe, take a look at StringBufferthe appendmethod.

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

The method synchronizedis declared using , indicating that it is a thread-safe method. It StringBuilderis not thread-safe.

How StringUtils.join is implemented

By looking StringUtils.joinat the source code, we can find that, in fact, he is also StringBuilderimplemented through.

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;
    }

    // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))
    //           (Assuming that all Strings are roughly equally long)
    final int noOfItems = endIndex - startIndex;
    if (noOfItems <= 0) {
        return 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();
}

Efficiency comparison

Since there are so many methods of string concatenation, which one is the most efficient? Let's make a simple comparison.

long t1 = System.currentTimeMillis();
//这里是初始字符串定义
for (int i = 0; i < 50000; i++) {
    //这里是字符串拼接代码
}
long t2 = System.currentTimeMillis();
System.out.println("cost:" + (t2 - t1));

We use codes in the form above to test the running time of the next five string concatenation codes. The result is as follows:

+ cost:5119
StringBuilder cost:3
StringBuffer cost:4
concat cost:3623
StringUtils.join cost:25726

As can be seen from the results, the comparison from short to long is:

StringBuilder<StringBuffer<concat<+<StringUtils.join

StringBufferOn StringBuilderthe basis of , the synchronization process is done, so it will be relatively more time-consuming.

StringUtils.join also uses StringBuilder, and there are still many other operations in it, so it takes a long time, and this is easy to understand. In fact, StringUtils.join is better at dealing with the splicing of string arrays or lists.

Then the question comes, we have analyzed before, in fact, the +implementation principle of using concatenated strings is also used StringBuilder, so why are the results so different, as high as 1000 times?

Let's decompile the following code again:

long t1 = System.currentTimeMillis();
String str = "hollis";
for (int i = 0; i &lt; 50000; i++) {
    String s = String.valueOf(i);
    str += s;
}
long t2 = System.currentTimeMillis();
System.out.println("+ cost:" + (t2 - t1));

The decompiled code is as follows:

long t1 = System.currentTimeMillis();
String str = "hollis";
for(int i = 0; i &lt; 50000; i++)
{
    String s = String.valueOf(i);
    str = (new StringBuilder()).append(str).append(s).toString();
}

long t2 = System.currentTimeMillis();
System.out.println((new StringBuilder()).append("+ cost:").append(t2 - t1).toString());

We can see that the decompiled code, in forthe loop, newreads one each time StringBuilder, and then Stringconverts it to StringBuilder, and then proceeds append.

Of course, frequent new objects will take a lot of time. Not only will it take time, but frequent object creation will also cause a waste of memory resources.

Therefore, the Alibaba Java Development Manual recommends that in the loop body, the string connection method should be extended using the method StringBuilder. appendInstead of using +.

Summarize

This article introduces what string splicing is. Although strings are immutable, strings can still be spliced ​​by creating new strings.

There are five commonly used string splicing methods, which are use +, use concat, use, use StringBuilder, StringBufferand use StringUtils.join.

Since new objects are created during string splicing, memory and efficiency issues must be considered if string splicing is to be performed in a loop body.

Therefore, after comparison, we found that the direct use StringBuildermethod is the most efficient. Because StringBuilderit is designed to define variable strings and string change operations.

However, it is also emphasized that:

1. If you do not perform string splicing in the loop body, you can use it directly +.

2. If string splicing is performed in a concurrent scenario, use StringBufferinstead StringBuilder.

Guess you like

Origin blog.csdn.net/zy_dreamer/article/details/132307440