在 JAVA 中使用递归获得不同的结果 StringBuilder 与 String

Getting different result StringBuilder vs String using recusrion in JAVA

当我在 运行 下面的代码中使用 StringBuilder 作为参数时,我得到了不同的输出:

public static List<String> generateParenthesis(int n) {
        if(n==0)
            return new ArrayList<String>();
        List<String> list = new ArrayList<>();
        generate(list, new StringBuilder(), 0, 0, n);
        return list;
    }
    public static void generate(List<String> list, StringBuilder s, int j, int k, int n)
    {
        if(s.length()>2*n || j>n || k>n || k>j)
            return;
        if(s.length()==2*n && j==n && k==n)
        {
            list.add(s.toString());
            return;
        }
        if(j<n)
        {
            generate(list, s.append("("), j+1, k, n);
        }
        if(k<j)
        {
            generate(list, s.append(")"), j, k+1, n);
        }
    }   

输出:[((()))]

当我使用 运行 相同代码并将参数作为字符串时,我得到不同的输出:

        if(n==0)
            return new ArrayList<String>();
        List<String> list = new ArrayList<>();
        generate(list, "", 0, 0, n);
        return list;
    }
    public static void generate(List<String> list, String s, int j, int k, int n)
    {
        if(s.length()>2*n || j>n || k>n || k>j)
            return;
        if(s.length()==2*n && j==n && k==n)
        {
            list.add(s.toString());
            return;
        }
        if(j<n)
        {
            generate(list, s+"(", j+1, k, n);
        }
        if(k<j)
        {
            generate(list, s+")", j, k+1, n);
        }
    } 

输出:[((())), (()()), (())(), ()(()), ()()()]

谁能帮我理解为什么会这样? 谢谢!!

区别仅在于 String 是不可变的:每当您连接或以其他方式操作 String 对象时,您实际上是在创建一个具有新值的新 String 对象。

然而,

StringBuilder 是可变的:您 可以 更改任何给定 StringBuilder 实例的值(这基本上是它存在的主要原因)。

所以在这一行中:

generate(list, s.append("("), j+1, k, n);

  1. 修改StringBuilder实例
  2. 致电generate
  3. 调用后还有修改的StringBuilder

但是在

generate(list, s+"(", j+1, k, n);

改为你

  1. 使用新值
  2. 创建String
  3. 调用 generate,传递新值
  4. sgenerate 调用后仍然引用之前的值。