2012-06-19 66 views
22

我们如何修正StringBuilder的值,而不会因为使用StringBuilder.toString().trim()而导致的开销,从而为每个修剪调用创建新的String和/或新的StringBuilder实例?如何修剪StringBuilder的字符串?

+1

我可以问你为什么不希望使用'StringBuilder.toString()。修剪()'? –

+1

其实我在一个循环中,我必须比较这个StringBuilder字符串与许多其他值,所以如果我每次调用StringBuilder.toString()。trim(),它会创建一个新的实例,我不想创建一个每次都有新的String对象。 –

+0

您可以根据需要多次使用'toString()。trim()'。请编辑您的问题并添加您以前的评论以澄清。 – mschonaker

回答

18

为什么StringBuilder的没有TRIM()方法

  1. 因为这就是它设计的方式。试着问设计师。
  2. 因为没有太多的要求。
  3. 由于字符串trim()语义和签名不适合可变字符串,尽管这是有争议的。

无论哪种方式,答案与解决您的问题无关。

以及如何修剪StringBuilder值?

最简单的方法是使用StringBuilder.toString().trim() ...

我不想使用StringBuilder.toString()。修剪()。

在这种情况下,所以你需要做什么trim()在封面下做:匹配并删除前导和尾随的空白。由于StringBuilder API没有正则表达式支持,所以你需要这么做;即通过从前面向前和向后反复查看字符来查看需要删除哪些字符,等等。

你确定你不喜欢这么简单吗?如果没有,这个问答& A有一些示例实现,分析,标杆管理,等等:


其实我在一个循环,我要比较这StringBuilder的字符串与许多其他值,所以如果我每次调用StringBuilder.toString()。trim(),它将创建一个新的实例,我不想每次都创建一个新的String对象。

另一方面是从StringBuilder的开头删除字符需要复制所有剩余的字符。

也许你最好把整个StringBuilder转换成一个字符串开始,然后当你使用trim()substring()之类的时候,你不会复制字符。 (这些方法的工作原理是创建一个新的字符串,其中股份原始字符串的支持数组... ...所以你最终只能复制字符串的控制信息。 UPDATE - 在Java 7中,他们改变的trim行为和substring让他们使用String构造那份支持数组的一个子)

+1

正在审阅你的类似答案:http://stackoverflow.com/questions/7510422/when-should-we-change -a-string-to-a-stringbuilder。我会说你已经很好地回答了这个问题。 –

+0

@KazekageGaara - 谢谢你:-) –

+5

“为什么不发生?因为它不会发生”。非常有建设性。你碰巧知道设计师没有实现toString()的原因吗? – Buffalo

0

您可以将StringBuilder实例转换为string,稍后可以将其修剪。

sb.toString().trim();//sb is stringBuilder Instance. 
1

为什么StringBuilder的没有TRIM()方法?

嗯.. StringBuilder就像String,只是有一点区别,它可以创建其他后修改了它是一样的字符串。

StringBuilder

如上链接所述,上一个StringBuilder的主要操作是追加和插入方法。我想他们提议支持可变字符串,与StringBuffer一样。如果你能通过一些其他方法的小调用,然后想要的方法来完成事情,那么最新的事情。为什么你想在多个类中实现相同的实现。

我们如何修剪StringBuilder值?

至于说其他人stringBuilder.toString().trim();

我不想使用StringBuilder.toString().trim()

嗯...选择的问题,这是什么具体原因?

+1

实际上,我在一个循环中,我必须将此StringBuilder字符串与许多其他值进行比较,所以如果我调用StringBuilder .toString()。trim(),它会创建一个新的实例,我不想每次创建一个新的String对象。 –

+0

然后使用你自己的'char []'和分隔符。检查'java.lang.String'代码。 – mschonaker

1

使用StringBuilder.toString().trim()但将其保存在一个变量中。

例如:

String myTrimmedString = myStringBuilder.toString().trim();

它不具有trim()方法,因为它是非常容易的,有点优选使用不可变对象。想象一下,一个线程正在修剪StringBuilder而另一个线程正在追加它。想象一下在你的代码中可能导致的错误和怪异。

+2

想象一下,一个线程正在修剪StringBuilder而另一个线程正在追加它。 这种情况也可以发生在追加操作中,而一个线程正在追加某些东西,另一个追加了其他东西......那么在那种情况下呢?它不应该支持追加 –

+0

@PramodKumar我会想象虚拟机只允许一次写入char []。然而,对读取操作施加相同的限制将是荒谬的。在同时读写时,我猜想它会阻止读取,这是一个非问题。这一切都取决于VM的实施。 trim()很可能会正常工作。显示实现不可变对象有多容易是一种假设情况。他们使用更少的内存。 – iracigt

+1

虽然你的解决方案是正确的,但你的理由是没有道理的。 StringBuilder不是线程安全的,因此,正如Pramod Kumar所说的那样,**任何**并发操作都是危险的。任何在多个线程中使用StringBuilder而没有同步的人都需要拍摄。 StringBuffer是StringBuilder的线程安全版本,因为它使用内部同步。 *(StringBuilder是在Java中引入的,如果您确信一次只有一个线程可以访问它,并且希望在没有在StringBuffer中同步的开销的情况下执行此操作)。 – megaflop

3

我不知道你在努力达到什么,但是如果你担心性能问题,也许你可以在追加到StringBuilder的时候执行trim。

stringbuilder.append(string.trim())