在java中重复String的简单方法

时间:2009-08-05 19:14:38

标签: java string

我正在寻找一个简单的公共方法或运算符,它允许我重复一些String n 次。我知道我可以使用for循环来编写它,但是我希望在必要时避免使用循环,并且在某处应该存在一个简单的直接方法。

String str = "abc";
String repeated = str.repeat(3);

repeated.equals("abcabcabc");

与:

相关

repeat string javascript Create NSString by repeating another string a given number of times

被修改

我尝试避免在不完全必要时使用for循环,因为:

  1. 即使它们隐藏在另一个函数中,它们也会增加代码行数。

  2. 有人在阅读我的代码时必须弄清楚我在循环中做了什么。即使它被评论并且具有有意义的变量名称,它们仍然必须确保它没有做任何“聪明”的事情。

  3. 程序员喜欢把聪明的东西放在for循环中,即使我把它写成“只做它想要做的事情”,这并不排除有人出现并添加一些额外的聪明“修复”。 / p>

  4. 他们经常容易出错。对于涉及索引的循环,往往会产生一个错误。

  5. For循环经常重用相同的变量,增加了很难找到范围错误的机会。

  6. For循环增加了一个bug猎人必须看的地方数量。

32 个答案:

答案 0 :(得分:824)

这是最短的版本(需要Java 1.5+):

repeated = new String(new char[n]).replace("\0", s);

其中n是您要重复字符串的次数,s是要重复的字符串。

不需要导入或库。

答案 1 :(得分:292)

Commons Lang StringUtils.repeat()

用法:

String str = "abc";
String repeated = StringUtils.repeat(str, 3);

repeated.equals("abcabcabc");

答案 2 :(得分:250)

如果您使用的是 Java< = 7 ,这很简单:

// create a string made up of n copies of string s
String.format("%0" + n + "d", 0).replace("0", s);

Java 8 及以上版本中,有一种简单的方法:

// create a string made up of n copies of string s
String.join("", Collections.nCopies(n, s));

Java 11 专门为此添加了一个新的repeat​(int count)方法(link

int n = 3;
"abc".repeat(n);

答案 3 :(得分:130)

Java 8 String.join提供了一种与Collections.nCopies结合使用的简洁方法:

// say hello 100 times
System.out.println(String.join("", Collections.nCopies(100, "hello")));

答案 4 :(得分:126)

从Java 11开始,there's a method String::repeat完全符合您的要求:

String str = "abc";
String repeated = str.repeat(3);
repeated.equals("abcabcabc");

Its Javadoc说:

/**
 * Returns a string whose value is the concatenation of this
 * string repeated {@code count} times.
 * <p>
 * If this string is empty or count is zero then the empty
 * string is returned.
 *
 * @param count number of times to repeat
 *
 * @return A string composed of this string repeated
 * {@code count} times or the empty string if this
 * string is empty or count is zero
 *
 * @throws IllegalArgumentException if the {@code count} is
 * negative.
 *
 * @since 11
 */ 

答案 5 :(得分:98)

这是一种只使用标准字符串函数而不使用显式循环的方法:

// create a string made up of  n  copies of  s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);

答案 6 :(得分:84)

如果你像我一样想要使用Google Guava而不是Apache Commons。您可以在Guava Strings类中使用repeat方法。

Strings.repeat("-", 60);

答案 7 :(得分:49)

使用,您还可以使用Stream.generate

import static java.util.stream.Collectors.joining;
...
String repeated = Stream.generate(() -> "abc").limit(3).collect(joining()); //"abcabcabc"

如果需要,您可以将其包装在一个简单的实用程序方法中:

public static String repeat(String str, int times) {
   return Stream.generate(() -> str).limit(times).collect(joining());
}

答案 8 :(得分:32)

所以你想避免循环?

在这里你拥有它:

public static String repeat(String s, int times) {
    if (times <= 0) return "";
    else return s + repeat(s, times-1);
}

(当然我知道这是丑陋而低效的,但它没有循环:-p)

你想要它更简单,更漂亮吗?使用jython:

s * 3

编辑:让我们稍微优化一下:-D

public static String repeat(String s, int times) {
   if (times <= 0) return "";
   else if (times % 2 == 0) return repeat(s+s, times/2);
   else return s + repeat(s+s, times/2);
}

Edit2 :我已经为4个主要替代品做了一个快速而肮脏的基准测试,但是我没有时间运行它几次以获取方法并绘制几个输入的时间...所以这是代码,如果有人想尝试它:

public class Repeat {
    public static void main(String[] args)  {
        int n = Integer.parseInt(args[0]);
        String s = args[1];
        int l = s.length();
        long start, end;

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatLog2(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("RecLog2Concat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatR(s,i).length()!=i*l) throw new RuntimeException();
        }               
        end = System.currentTimeMillis();
        System.out.println("RecLinConcat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatIc(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("IterConcat: " + (end-start) + "ms");

        start = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            if(repeatSb(s,i).length()!=i*l) throw new RuntimeException();
        }
        end = System.currentTimeMillis();
        System.out.println("IterStrB: " + (end-start) + "ms");
    }

    public static String repeatLog2(String s, int times) {
        if (times <= 0) {
            return "";
        }
        else if (times % 2 == 0) {
            return repeatLog2(s+s, times/2);
        }
        else {
           return s + repeatLog2(s+s, times/2);
        }
    }

    public static String repeatR(String s, int times) {
        if (times <= 0) {
            return "";
        }
        else {
            return s + repeatR(s, times-1);
        }
    }

    public static String repeatIc(String s, int times) {
        String tmp = "";
        for (int i = 0; i < times; i++) {
            tmp += s;
        }
        return tmp;
    }

    public static String repeatSb(String s, int n) {
        final StringBuilder sb = new StringBuilder();
        for(int i = 0; i < n; i++) {
            sb.append(s);
        }
        return sb.toString();
    }
}

它需要2个参数,第一个是迭代次数(每个函数以1..n重复次数arg运行),第二个是要重复的字符串。

到目前为止,快速检查使用不同输入运行的时间会使排名变得像这样(越来越差):

  1. Iterative StringBuilder追加(1x)。
  2. 递归连接log2调用(~3x)。
  3. 递归连接线性调用(~30x)。
  4. 迭代连接线性(~45x)。
  5. 我不会猜到递归函数比for循环更快:-o

    玩得开心(ctional xD)。

答案 9 :(得分:20)

这包含的字符少于您的问题

public static String repeat(String s, int n) {
    if(s == null) {
        return null;
    }
    final StringBuilder sb = new StringBuilder(s.length() * n);
    for(int i = 0; i < n; i++) {
        sb.append(s);
    }
    return sb.toString();
}

答案 10 :(得分:9)

基于fortran's answer,这是一个使用StringBuilder的递归版本:

public static void repeat(StringBuilder stringBuilder, String s, int times) {
    if (times > 0) {
        repeat(stringBuilder.append(s), s, times - 1);
    }
}

public static String repeat(String s, int times) {
    StringBuilder stringBuilder = new StringBuilder(s.length() * times);
    repeat(stringBuilder, s, times);
    return stringBuilder.toString();
}

答案 11 :(得分:7)

使用Dollar很简单,只需输入:

@Test
public void repeatString() {
    String string = "abc";
    assertThat($(string).repeat(3).toString(), is("abcabcabc"));
}

PS:重复也适用于数组,列表,集等

答案 12 :(得分:7)

我想要一个函数来创建用于JDBC目的的逗号分隔的问号列表,并找到了这篇文章。所以,我决定采用两种变体,看哪哪种表现更好。经过100万次迭代后,花园种类的StringBuilder花了2秒钟(fun1),而神秘的假想更加优化的版本(fun2)耗时30秒。再次隐晦有什么意义呢?

private static String fun1(int size) {
    StringBuilder sb = new StringBuilder(size * 2);
    for (int i = 0; i < size; i++) {
        sb.append(",?");
    }
    return sb.substring(1);
}

private static String fun2(int size) {
    return new String(new char[size]).replaceAll("\0", ",?").substring(1);
}

答案 13 :(得分:7)

OOP解决方案

几乎每个答案都提出了一个静态函数作为解决方案,但是考虑面向对象(为了可重用性和清晰度)我通过CharSequence-Interface通过委派提出了一个解决方案(这也开启了可变CharSequence-的可用性 - 类)。

以下类可以使用或不使用Separator-String / CharSequence,每次调用&#34; toString()&#34;构建最终重复的String。 Input / Separator不仅限于String-Class,而且可以是每个实现CharSequence的Class(例如StringBuilder,StringBuffer等)!

源代码:

/**
 * Helper-Class for Repeating Strings and other CharSequence-Implementations
 * @author Maciej Schuttkowski
 */
public class RepeatingCharSequence implements CharSequence {
    final int count;
    CharSequence internalCharSeq = "";
    CharSequence separator = "";
    /**
     * CONSTRUCTOR - RepeatingCharSequence
     * @param input CharSequence to repeat
     * @param count Repeat-Count
     */
    public RepeatingCharSequence(CharSequence input, int count) {
        if(count < 0)
            throw new IllegalArgumentException("Can not repeat String \""+input+"\" less than 0 times! count="+count);
        if(count > 0)
            internalCharSeq = input;
        this.count = count;
    }
    /**
     * CONSTRUCTOR - Strings.RepeatingCharSequence
     * @param input CharSequence to repeat
     * @param count Repeat-Count
     * @param separator Separator-Sequence to use
     */
    public RepeatingCharSequence(CharSequence input, int count, CharSequence separator) {
        this(input, count);
        this.separator = separator;
    }

    @Override
    public CharSequence subSequence(int start, int end) {
        checkBounds(start);
        checkBounds(end);
        int subLen = end - start;
        if (subLen < 0) {
            throw new IndexOutOfBoundsException("Illegal subSequence-Length: "+subLen);
        }
        return (start == 0 && end == length()) ? this
                    : toString().substring(start, subLen);
    }
    @Override
    public int length() {
        //We return the total length of our CharSequences with the separator 1 time less than amount of repeats:
        return count < 1 ? 0
                : ( (internalCharSeq.length()*count) + (separator.length()*(count-1)));
    }
    @Override
    public char charAt(int index) {
        final int internalIndex = internalIndex(index);
        //Delegate to Separator-CharSequence or Input-CharSequence depending on internal index:
        if(internalIndex > internalCharSeq.length()-1) {
            return separator.charAt(internalIndex-internalCharSeq.length());
        }
        return internalCharSeq.charAt(internalIndex);
    }
    @Override
    public String toString() {
        return count < 1 ? ""
                : new StringBuilder(this).toString();
    }

    private void checkBounds(int index) {
        if(index < 0 || index >= length())
            throw new IndexOutOfBoundsException("Index out of Bounds: "+index);
    }
    private int internalIndex(int index) {
        // We need to add 1 Separator-Length to total length before dividing,
        // as we subtracted one Separator-Length in "length()"
        return index % ((length()+separator.length())/count);
    }
}

用法-示例:

public static void main(String[] args) {
    //String input = "12345";
    //StringBuffer input = new StringBuffer("12345");
    StringBuilder input = new StringBuilder("123");
    //String separator = "<=>";
    StringBuilder separator = new StringBuilder("<=");//.append('>');
    int repeatCount = 2;

    CharSequence repSeq = new RepeatingCharSequence(input, repeatCount, separator);
    String repStr = repSeq.toString();

    System.out.println("Repeat="+repeatCount+"\tSeparator="+separator+"\tInput="+input+"\tLength="+input.length());
    System.out.println("CharSeq:\tLength="+repSeq.length()+"\tVal="+repSeq);
    System.out.println("String :\tLength="+repStr.length()+"\tVal="+repStr);

    //Here comes the Magic with a StringBuilder as Input, as you can append to the String-Builder
    //and at the same Time your Repeating-Sequence's toString()-Method returns the updated String :)
    input.append("ff");
    System.out.println(repSeq);
    //Same can be done with the Separator:
    separator.append("===").append('>');
    System.out.println(repSeq);
}

实施例-输出:

Repeat=2    Separator=<=    Input=123   Length=3
CharSeq:    Length=8    Val=123<=123
String :    Length=8    Val=123<=123
123ff<=123ff
123ff<====>123ff

答案 14 :(得分:6)

仅使用JRE类(System.arraycopy)和尝试最小化临时对象的数量,您可以编写如下内容:

public static String repeat(String toRepeat, int times) {
    if (toRepeat == null) {
        toRepeat = "";
    }

    if (times < 0) {
        times = 0;
    }

    final int length = toRepeat.length();
    final int total = length * times;
    final char[] src = toRepeat.toCharArray();
    char[] dst = new char[total];

    for (int i = 0; i < total; i += length) {
        System.arraycopy(src, 0, dst, i, length);
    }

    return String.copyValueOf(dst);
}

修改

没有循环你可以试试:

public static String repeat2(String toRepeat, int times) {
    if (toRepeat == null) {
        toRepeat = "";
    }

    if (times < 0) {
        times = 0;
    }

    String[] copies = new String[times];
    Arrays.fill(copies, toRepeat);
    return Arrays.toString(copies).
              replace("[", "").
              replace("]", "").
              replaceAll(", ", "");
}

编辑2

使用Collections甚至更短:

public static String repeat3(String toRepeat, int times) {
    return Collections.nCopies(times, toRepeat).
           toString().
           replace("[", "").
           replace("]", "").
           replaceAll(", ", "");
}

然而我仍然喜欢第一个版本。

答案 15 :(得分:5)

如果你担心速度,那么你应该使用尽可能少的内存复制。因此,需要使用字符数组。

public static String repeatString(String what, int howmany) {
    char[] pattern = what.toCharArray();
    char[] res = new char[howmany * pattern.length];
    int length = pattern.length;
    for (int i = 0; i < howmany; i++)
        System.arraycopy(pattern, 0, res, i * length, length);
    return new String(res);
}

为了测试速度,使用StirngBuilder的类似优化方法如下:

public static String repeatStringSB(String what, int howmany) {
    StringBuilder out = new StringBuilder(what.length() * howmany);
    for (int i = 0; i < howmany; i++)
        out.append(what);
    return out.toString();
}

以及测试它的代码:

public static void main(String... args) {
    String res;
    long time;

    for (int j = 0; j < 1000; j++) {
        res = repeatString("123", 100000);
        res = repeatStringSB("123", 100000);
    }

    time = System.nanoTime();
    res = repeatString("123", 1000000);
    time = System.nanoTime() - time;
    System.out.println("elapsed repeatString: " + time);

    time = System.nanoTime();
    res = repeatStringSB("123", 1000000);
    time = System.nanoTime() - time;
    System.out.println("elapsed repeatStringSB: " + time);

}

这里的运行来自我的系统:

elapsed repeatString: 6006571
elapsed repeatStringSB: 9064937

请注意,循环测试是启动JIT并获得最佳结果。

答案 16 :(得分:4)

不是最短的,但(我认为)最快的方法是使用StringBuilder:

 /**
   * Repeat a String as many times you need.
   *
   * @param i - Number of Repeating the String.
   * @param s - The String wich you want repeated.
   * @return The string n - times.
   */
  public static String repeate(int i, String s) {
    StringBuilder sb = new StringBuilder();
    for (int j = 0; j < i; j++)
      sb.append(s);
    return sb.toString();
  }

答案 17 :(得分:4)

为了便于阅读和便携:

public String repeat(String str, int count){
    if(count <= 0) {return "";}
    return new String(new char[count]).replace("\0", str);
}

答案 18 :(得分:3)

如果你担心性能,只需在循环中使用StringBuilder并在循环退出时执行.toString()。哎呀,编写自己的Util类并重用它。最多5行代码

答案 19 :(得分:2)

使用递归,您可以执行以下操作(使用三元运算符,最多一行):

public static final String repeat(String string, long number) {
    return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}

我知道,它很丑陋,可能效率不高,但它只有一条线!

答案 20 :(得分:2)

如果您只知道输出字符串的 length (并且可能不能被输入字符串的长度整除),请使用以下方法:

static String repeat(String s, int length) {
    return s.length() >= length ? s.substring(0, length) : repeat(s + s, length);
}

用法演示:

for (int i = 0; i < 50; i++)
    System.out.println(repeat("_/‾\\", i));

请勿使用空的slength> 0,因为在这种情况下无法获得理想的结果。

答案 21 :(得分:2)

试试这个:

public static char[] myABCs = {'a', 'b', 'c'};
public static int numInput;
static Scanner in = new Scanner(System.in);

public static void main(String[] args) {
    System.out.print("Enter Number of Times to repeat: ");
    numInput = in.nextInt();
    repeatArray(numInput);
}

public static int repeatArray(int y) {
    for (int a = 0; a < y; a++) {
        for (int b = 0; b < myABCs.length; b++) {
            System.out.print(myABCs[b]);                
        }
        System.out.print(" ");
    }
    return y;
}

答案 22 :(得分:2)

简单循环

public static String repeat(String string, int times) {
    StringBuilder out = new StringBuilder();
    while (times-- > 0) {
        out.append(string);
    }
    return out.toString();
}

答案 23 :(得分:2)

我真的很喜欢这个问题。有很多知识和风格。所以我不能离开它而不显示我的摇滚乐;)

{
    String string = repeat("1234567890", 4);
    System.out.println(string);
    System.out.println("=======");
    repeatWithoutCopySample(string, 100000);
    System.out.println(string);// This take time, try it without printing
    System.out.println(string.length());
}

/**
 * The core of the task.
 */
@SuppressWarnings("AssignmentToMethodParameter")
public static char[] repeat(char[] sample, int times) {
    char[] r = new char[sample.length * times];
    while (--times > -1) {
        System.arraycopy(sample, 0, r, times * sample.length, sample.length);
    }
    return r;
}

/**
 * Java classic style.
 */
public static String repeat(String sample, int times) {
    return new String(repeat(sample.toCharArray(), times));
}

/**
 * Java extreme memory style.
 */
@SuppressWarnings("UseSpecificCatch")
public static void repeatWithoutCopySample(String sample, int times) {
    try {
        Field valueStringField = String.class.getDeclaredField("value");
        valueStringField.setAccessible(true);
        valueStringField.set(sample, repeat((char[]) valueStringField.get(sample), times));
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}
你喜欢吗?

答案 24 :(得分:1)

public static String repeat(String str, int times) {
    int length = str.length();
    int size = length * times;
    char[] c = new char[size];
    for (int i = 0; i < size; i++) {
        c[i] = str.charAt(i % length);
    }
    return new String(c);
}

答案 25 :(得分:1)

简单的单行解决方案:
需要Java 8

Collections.nCopies( 3, "abc" ).stream().collect( Collectors.joining() );

答案 26 :(得分:1)

尽管你不想使用循环,我认为你应该使用循环。

String repeatString(String s, int repetitions)
{
    if(repetitions < 0) throw SomeException();

    else if(s == null) return null;

    StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);

    for(int i = 0; i < repetitions; i++)
        stringBuilder.append(s);

    return stringBuilder.toString();
}

不使用for循环的原因不是很好。回应你的批评:

  1. 您使用的解决方案几乎肯定会比这更长。使用预先构建的功能只能将它放在更多的封面下。
  2. 读取代码的人必须弄清楚你在非循环中做了什么。鉴于for循环是执行此操作的惯用方法,因此可以更容易地确定是否使用for循环执行此操作。
  3. 是的,有人可能会添加一些聪明的东西,但是通过避免使用for循环 做一些聪明的事情。这就像是故意用脚射击自己,以免意外撞到脚下。
  4. 一次性错误也很容易被一次测试所困扰。鉴于您应该测试您的代码,应该很容易修复和捕获一个错误的错误。值得注意的是:上面的代码不包含一个错误的错误。对于循环同样容易正确。
  5. 所以不要重复使用变量。那不是for-loop的错。
  6. 同样,您使用的解决方案也是如此。正如我之前提到的那样;一个bug猎人可能会期望你用for循环来做这个,所以如果你使用for循环他们会更容易找到它。

答案 27 :(得分:0)

我创建了一个递归方法,可以执行您想要的相同操作。随意使用此...

public String repeat(String str, int count) {
    return count > 0 ?  repeat(str, count -1) + str: "";
}

我在Can I multiply strings in java to repeat sequences?

上有相同的答案

答案 28 :(得分:0)

这是最新的Stringutils.java StringUtils.java

    public static String repeat(String str, int repeat) {
    // Performance tuned for 2.0 (JDK1.4)

    if (str == null) {
        return null;
    }
    if (repeat <= 0) {
        return EMPTY;
    }
    int inputLength = str.length();
    if (repeat == 1 || inputLength == 0) {
        return str;
    }
    if (inputLength == 1 && repeat <= PAD_LIMIT) {
        return repeat(str.charAt(0), repeat);
    }

    int outputLength = inputLength * repeat;
    switch (inputLength) {
        case 1 :
            return repeat(str.charAt(0), repeat);
        case 2 :
            char ch0 = str.charAt(0);
            char ch1 = str.charAt(1);
            char[] output2 = new char[outputLength];
            for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
                output2[i] = ch0;
                output2[i + 1] = ch1;
            }
            return new String(output2);
        default :
            StringBuilder buf = new StringBuilder(outputLength);
            for (int i = 0; i < repeat; i++) {
                buf.append(str);
            }
            return buf.toString();
    }
    }

它甚至不需要这么大,可以制作成这个,并且可以复制和粘贴 进入项目中的实用程序类。

    public static String repeat(String str, int num) {
    int len = num * str.length();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < times; i++) {
        sb.append(str);
    }
    return sb.toString();
    }

所以e5,我认为最好的方法是简单地使用上面提到的代码,或者这里的任何答案。但是,如果这是一个小项目,那么公共资源就太大了

答案 29 :(得分:0)

public static String rep(int a,String k)

       {
           if(a<=0)
                return "";
           else 
           {a--;
               return k+rep(a,k);
       }

您可以使用此递归方法实现所需的目标。

答案 30 :(得分:0)

已合并以供快速参考:

public class StringRepeat {

// Java 11 has built-in method - str.repeat(3);
// Apache - StringUtils.repeat(3);
// Google - Strings.repeat("",n);
// System.arraycopy

static String repeat_StringBuilderAppend(String str, int n) {

    if (str == null || str.isEmpty())
        return str;

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; i++) {
        sb.append(str);
    }
    return sb.toString();
}

static String repeat_ArraysFill(String str, int n) {
    String[] strs = new String[n];
    Arrays.fill(strs, str);
    return Arrays.toString(strs).replaceAll("\\[|\\]|,| ", "");
}

static String repeat_Recursion(String str, int n) {
    if (n <= 0)
        return "";
    else
        return str + repeat_Recursion(str, n - 1);
}

static String repeat_format1(String str, int n) {
    return String.format(String.format("%%%ds", n), " ").replace(" ", str);
}

static String repeat_format2(String str, int n) {
    return new String(new char[n]).replace("\0", str);
}

static String repeat_format3(String str, int n) {
    return String.format("%0" + n + "d", 0).replace("0", str);
}

static String repeat_join(String str, int n) {
    return String.join("", Collections.nCopies(n, str));
}

static String repeat_stream(String str, int n) {
    return Stream.generate(() -> str).limit(n).collect(Collectors.joining());
}

public static void main(String[] args) {
    System.out.println(repeat_StringBuilderAppend("Mani", 3));
    System.out.println(repeat_ArraysFill("Mani", 3));
    System.out.println(repeat_Recursion("Mani", 3));
    System.out.println(repeat_format1("Mani", 3));
    System.out.println(repeat_format2("Mani", 3));
    System.out.println(repeat_format3("Mani", 3));
    System.out.println(repeat_join("Mani", 3));
    System.out.println(repeat_stream("Mani", 3));

}

}

答案 31 :(得分:-3)

repeated = str + str + str;

有时简单是最好的。阅读代码的每个人都可以看到发生了什么。

编译器会在幕后为你做StringBuilder这些奇特的东西。