这会创建12个字符串对象吗?

时间:2012-08-29 00:27:00

标签: java

我试图理解下面这段代码是否为像“stephan”这样的字符串创建了12个对象

public String reverse(String str) {
            if ((null == str) || (str.length()  <= 1)) {
                return str;
            }
            return reverse(str.substring(1)) + str.charAt(0);
        }

这会以递归方式反转字符串。我明白它是如何工作的。但我想是否在这种情况下,字符串的长度和通过串联创建的字符串对象的数量之间是否存在关系?

2 个答案:

答案 0 :(得分:2)

是的,它会创建大量的字符串对象。

每次递归调用“reverse()”都会产生2:

  1. str.substring(1)将创建一个新的String对象

  2. reverse()调用将为其返回值创建一个新字符串,但我们不会计算,因为在分析该递归调用时会计算该值(例如,它将是来自项目符号#3的字符串)下一个reverse()来电。

  3. 由于Java Strings are immutable,通过“+”添加字符将创建第二个字符串对象。

  4. 因此,对于长度为N的字符串,它将创建(N-1)* 2个对象(因为1-char字符串的反向不会创建新的字符串); 因此对于“stephan”的7个字符,它将创建6 * 2 = 12个字符串对象。

答案 1 :(得分:1)

定理:

  • 当字符串长度为N个字符时,@ Phoenix的reverse实现将创建(N-1)*3个新对象。

证明(通过归纳):

  • 当str为1个字符长时,直接返回。 (1*1)*3 = 0
  • 当str为N个字符时:
    • String将创建一个新的.substring(1)
    • 通过归纳假设,在reverse(...)个对象创建后将返回对(N-2)*3的调用。
    • 将创建一个新的StringBuilder来附加字符串,然后是第一个char(您可以通过反编译字节代码来看到这一点)。
    • String将创建一个新的StringBuilder.toString() - 这是返回值。
    • 总共创建了3 + (N-2)*3 = (N-2 + 1)*3 = (N-1)*3个对象。
  • QED。

[编辑] StringBuilders:

  • StringBuilder(扩展AbstractStringBuilder)做了自己的花哨步法:
    • 构建StringBuilder时,会使用大小为16的char[]进行初始化。
    • 如果您追加超出当前尺寸的内容,则会将其抛出并创建一个大小为char[]的新(<old size> + <size of new data> + 1) * 2
  • 因此,只要输入字符串为&gt; 16个字符,基本上是StringBuilder容量的2倍。 (当输入字符串大小较小时,您的char[]比您需要的更多。)
  • 考虑到String s基本上是char[] s(有一些int s用于衡量标准),您实际上使用{{1}中子字符串长度的4倍s - 每一步。 :(