【问题标题】:How stringbuilder append workstringbuilder 追加如何工作
【发布时间】:2016-02-25 07:31:32
【问题描述】:

下面的代码将创建多少个对象,请解释一下如何?

StringBuilder s=new StringBuilder();
s.append("hi"+"java"+"test");

【问题讨论】:

  • 首先你写的不对,应该是StringBuilder s=new StringBuilder(); s.append("hi");s.append("java");s.append("test");
  • 这个msdn doc会告诉你所有你需要知道的,然后你可以看一下这个source code,它会给你多少。但字符串更多地与地址和指针有关,而不是对象。

标签: stringbuffer


【解决方案1】:

所以来自页面底部的msdn docs:

以下示例说明了 StringBuilder 对象如何分配 新内存并随着字符串动态增加其容量 分配给对象的扩展。代码创建一个 StringBuilder 对象通过调用其默认(无参数)构造函数。 默认 该对象的容量为 16 个字符,其最大容量为 超过 20 亿个字符。附加字符串“这是一个 句子。”导致新的内存分配,因为字符串 长度(19 个字符)超过了默认容量 StringBuilder 对象。 对象的容量翻倍至 32 字符,添加新字符串,现在对象的长度 等于 19 个字符。然后代码附加字符串“这是一个 附加句。”到 StringBuilder 对象的值 11 次。每当 append 操作导致 StringBuilder 对象超出其容量,其现有容量为 加倍,追加操作成功。

我用粗体突出了重要的部分。

所以基本上,步骤是:

  1. StringBuilder 创建一个长度来保存一些字符串
  2. 当超过长度时,它会加倍,直到它可以容纳字符串
  3. 查看source 中的第 373 行以输出字符串,它将通过内存地址将其组合在一起...从非常高的级别读取。

所以要记住它不会创建对象,它只是动态重新分配内存空间以处理调用append 时确定的新字符串长度。

进一步回答您的问题

场景A),我们设置一个长度:

var s = new StringBuilder(10);
s.Append("hijavatest");

这应该创建一个容量为 10 的字符串生成器,并将该字符串存储在其中。

场景 B),我们没有指定长度:

var s = new StringBuilder();
s.Append("hi");
s.Append("java");
s.Append("test");

这将创建字符串生成器的默认容量:16。不应更改大小以附加所有新字符串。

场景C),我们设置一个小的长度:

var s = new StringBuilder(3);
s.Append("hi");
s.Append("java"); // doubles capacity to 6
s.Append("test"); // doubles capacity to 12

这将使容量翻倍,直到它可以存储所有字符串,在本例中为 12。

在 dotnetfiddle 中运行以下代码:

using System;
using System.Text;  

public class Program
{
    public static void Main()
    {
      ScenarioA();
        ScenarioB();
        ScenarioC();
   }

   private static void ShowSBInfo(StringBuilder sb)
   {
      foreach (var prop in sb.GetType().GetProperties()) {
         if (prop.GetIndexParameters().Length == 0)
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
      }
      Console.WriteLine();
   }
    
    private static void ScenarioA()
    {
        Console.WriteLine("Scenario A");
        var sb = new StringBuilder(10);
        ShowSBInfo(sb);
        sb.Append("hijavatest");    
        ShowSBInfo(sb);
    }
    
    private static void ScenarioB()
    {
        Console.WriteLine("Scenario B");
        var sb = new StringBuilder();
        ShowSBInfo(sb);
        sb.Append("hi");
        ShowSBInfo(sb);
        sb.Append("java");
        ShowSBInfo(sb);
        sb.Append("test");  
        ShowSBInfo(sb);
    }
    
    private static void ScenarioC()
    {
        Console.WriteLine("Scenario C");
        var sb = new StringBuilder(3);
        ShowSBInfo(sb);
        sb.Append("hi");
        ShowSBInfo(sb);
        sb.Append("java"); // doubles capacity to 6
        ShowSBInfo(sb);
        sb.Append("test"); // doubles capacity to 12    
        ShowSBInfo(sb);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-02
    • 2019-03-06
    • 1970-01-01
    相关资源
    最近更新 更多