On string splicing in java

Posted by Bunyip on Tue, 08 Feb 2022 13:17:49 +0100

Pre knowledge

  1. String is an immutable class in java. Once instantiated, it cannot be modified

    Once an instance of an immutable class is created, the value of its member variable cannot be modified. This design can cache hashcode, make it easier to use and more secure.

  2. java does not support operator overloading

    Operator overloading: in computer programming, operator overloading is a kind of polymorphism. Operator overloading is to redefine the existing operators and give them another function to adapt to different data types.
    Syntax sugar: syntax sugar, also translated as sugar coated grammar, is a term invented by British computer scientist Peter randing. It refers to a certain grammar added to the computer language. This grammar has no impact on the function of the language, but it is more convenient for programmers to use. Syntax sugar makes the program more concise and more readable.

Common String splicing methods include using symbol '+', concat method in String class, StringBuffer, StringBuilder and stringutils join

Use the symbol '+' to splice

Using + to splice strings is actually just a syntax sugar provided by Java. Its implementation principle is StringBuilder append

// Concatenate strings with the symbol '+'
String hollis = wechat + "," + introduce;

// Decompilation result of the above code
String hollis = (new StringBuilder()).append(wechat).append(",").append(introduce).toString();

From the decompiled code, use + to splice strings. Each time, a StringBuilder is created, and then the String is converted to StringBuilder, and then append.

If you use the + concatenation string in the for loop, you will frequently new an object, which will not only consume time, but also cause a waste of memory resources.

Therefore, according to Alibaba's Java development manual, it is suggested to use the append method of StringBuilder instead of +.

Splice using concat method in String class

usage

String hollis = "wechat".concat(",").concat("introduce");

The source code of concat method in String class

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

As you can see, the concat method first creates a character array whose length is the sum of the length of the existing String and the String to be spliced, 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 it.

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

Splicing using StringBuffer and StringBuilder

Both StringBuffer and StringBuilder inherit the AbstractStringBuilder class. A character array char[] value is defined in the AbstractStringBuilder class. Unlike the String class, it has no final modifier, so it can be modified
The biggest difference between StringBuffer and StringBuilder is that StringBuffer is thread safe. StringBuffer uses synchronized to declare and overrides some methods in AbstractStringBuilder class,

@Override
    public synchronized int length() {
        return count;
    }

StringUtils.join

StringUtils.join source code

public static String join(Collection var0, String var1) {
    StringBuffer var2 = new StringBuffer();

    for(Iterator var3 = var0.iterator(); var3.hasNext(); var2.append((String)var3.next())) {
        if (var2.length() != 0) {
            var2.append(var1);
        }
    }

    return var2.toString();
}

As you can see, stringutils Join is implemented through StringBuffer. Its main function is to splice arrays or sets together with a splicing character to form a new string.

StringJoiner

StringJoiner is Java A class in the util package that constructs a sequence of characters separated by a delimiter (optional) and can start with the supplied prefix and end with the supplied suffix.

usage

public class StringJoinerTest {

    public static void main(String[] args) {
        StringJoiner sj = new StringJoiner("Hollis");    // Hollis is the separator

        sj.add("hollischuang");
        sj.add("Java dried food");
        System.out.println(sj.toString());

        StringJoiner sj1 = new StringJoiner(":","[","]");    // StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)

        sj1.add("Hollis").add("hollischuang").add("Java dried food");
        System.out.println(sj1.toString());
    }
}

// The above code returns the result
// Hollichuanghollisjava dry goods
// [Hollis: Hollis Chuang: Java dry goods]

It should be noted that when we initialize a StringJoiner with a StringJoiner(CharSequence delimiter), the delimiter is actually a separator, not the initial value of the variable string.

According to stringjoiner The source code of the add method can be seen that its implementation principle also depends on the StringBuilder class

public StringJoiner add(CharSequence newElement) {
    prepareBuilder().append(newElement);
    return this;
}

private StringBuilder prepareBuilder() {
    if (value != null) {
        value.append(delimiter);
    } else {
        value = new StringBuilder().append(prefix);
    }
    return value;
}

list.stream().collect(Collectors.joining(",")) is also a list splicing string implemented with the help of StringJoiner class. However, the use of StringJoiner class can easily add prefixes and suffixes, which is suitable for scenes where string splicing has prefixes and suffixes.

If string splicing is needed in daily development, how to choose?

  • If it's just a simple string splicing instead of string splicing in the loop body, just use + directly
  • If string splicing is performed in a for loop, consider using StringBuilder and StringBuffer
  • If string splicing is performed in a concurrent scenario, StringBuffer should be used instead of StringBuilder
  • If string splicing is performed through a List, consider using stringutils Join and StringJoiner

Reference articles

Several methods and performance comparison of Java string splicing

Topics: Java