过去,我一直使用printf格式化打印到控制台,但我目前的作业(创建发票报告)要求我们使用StringBuilder,但我不知道怎么做而不是简单的使用" "因为每个需要的差距。例如......我应该打印出来
Invoice Customer Salesperson Subtotal Fees Taxes Discount Total
INV001 Company Eccleston, Chris $ 2357.60 $ 40.00 $ 190.19 $ -282.91 $ 2304.88
但是我不知道如何使用StringBuilder来排列所有内容。有什么建议吗?
答案 0 :(得分:3)
StringBuilder旨在减少与创建字符串相关的开销。
正如您可能知道或不知道的那样,字符串是不可变的。这意味着像
这样的东西String a = "foo";
String b = "bar";
String c = a + b;
String d = c + c;
为每一行创建一个新字符串。如果我们所关心的是最终字符串d
,则字符串c
的行会浪费空间,因为当我们不需要它时会创建一个新的String
对象。 / p>
字符串构建器只会延迟实际构建String
对象,直到您调用.toString()
为止。此时,它会将内部char[]
转换为实际字符串。
让我们再举一个例子。
String foo() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
sb.append(i);
return sb.toString();
}
在这里,我们只创建一个字符串。 StringBuilder
将跟踪您在内部char[] value
中添加到字符串中的字符。请注意,value.length
通常会大于您添加到StringBuilder
的总字符数,但value
如果字符串是value
可能会超出您的追加范围建筑太大了。当发生这种情况时,它会调整大小,这意味着用更大的char[]
替换sb.toString()
,并将旧值复制到新数组,以及所附加的任何字符。< / p>
最后,当您致电StringBuilder
时,String
将调用带有char[]
参数的String
构造函数。
这意味着只创建了一个char[]
对象,我们只需要String foo() {
String toReturn = "";
for (int i = 0; i < 100; i++)
toReturn += "" + i;
toReturn;
}
足够的内存并调整其大小。
与以下内容比较:
toReturn
在这里,我们创建了101个字符串对象(可能更多,我不确定)。我们只需要一个!这意味着在每次调用时,我们都会处理所表示的原始字符串StringBuilder
,并创建另一个字符串。
特别是对于大字符串,这非常昂贵,因为在每次调用时,您需要首先获取与新字符串所需的内存一样多的内存,并且处理与旧字符串一样多的内存。当事情变得简短时,这不是什么大不了的事,但是当你处理整个文件时,这很容易成为一个问题。
简而言之:如果您在最终确定输出之前正在进行附加/删除信息:请使用FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(
ticket.Version,
userID,
DateTime.Now,//ticket.IssueDate
DateTime.Now.AddMinutes(FormsAuthentication.Timeout.Minutes),
ticket.IsPersistent,
ticket.UserData,
ticket.CookiePath);
。如果你的字符串非常短,我认为只是为了方便而正常连接是可以的,但这取决于你定义什么&#34; short&#34;是