代码之家  ›  专栏  ›  技术社区  ›  CPerkins

StringBuilder对StringWriter和PrintWriter的字符串组装

  •  51
  • CPerkins  · 技术社区  · 15 年前

    我最近遇到了一个以前从未见过的习惯用法:string assembly by StringWriter PrintWriter . 我是说,我知道怎么用,但我一直都用 StringBuilder . 有没有一个具体的理由让你更喜欢一个而不是另一个?这个 字符串拼接

    我在这里看了几个问题(包括最接近的一个问题: StringWriter or StringBuilder ),但没有一个答案真正解决了这样一个问题:对于简单的字符串组装,是否有理由选择一个而不是另一个。

    这是我见过并使用过很多次的习惯用法:StringBuilder的字符串组装:

    public static String newline = System.getProperty("line.separator");
    public String viaStringBuilder () {
       StringBuilder builder = new StringBuilder();
       builder.append("first thing").append(newline);  // NOTE: avoid doing builder.append("first thing" + newline);
       builder.append("second thing").append(newline);
       // ... several things
       builder.append("last thing").append(newline);
       return builder.toString();
    }
    

    这就是新的习惯用法:StringWriter和PrintWriter的字符串组装:

    public String viaWriters() {
       StringWriter stringWriter = new StringWriter();
       PrintWriter printWriter = new PrintWriter(stringWriter);
       printWriter.println("first thing");
       printWriter.println("second thing");
       // ... several things
       printWriter.println("last thing");
       printWriter.flush();
       printWriter.close();
       return stringWriter.toString();
    }
    

    看来没有 混凝土

    原来有 选择其中一个(特别是StringBuilder)而不是另一个的具体原因。我第一次错过的是新台词的加入。当你添加一个新行(如上所述,作为一个单独的附加),它会稍微快一点-不是很大,但加上清晰的意图,它肯定是更好的。关于改进的时间安排,请参见下面的答案。

    6 回复  |  直到 4 年前
        1
  •  20
  •   Stephen C    4 年前

    StringBuilder 方法更干净。它的代码行更少,并且使用的类是专门为构建字符串而设计的。

    期待

    A StringWriter 使用 StringBuffer (而不是 字符串拼接 )在引擎盖下保存写在“流”上的字符。因此使用 字符串编写器 因为弦的装配会引起 的同步开销,无论应用程序是否需要。但如果你的申请 如果需要同步,那么应该考虑使用 字符串缓冲区 直接。


    CPerkins已经做了一些基准测试(参见 his answer )他的结果符合我的直觉。他们说 字符串拼接 字符串编写器 典型的 . 然而,很高兴知道“风格”和“性能”标准给出了相同的答案!

        2
  •  42
  •   Alan Moore Chris Ballance    15 年前

    StringWriter是当您想写入字符串,但使用的API需要编写器或流时使用的。这不是一种选择,而是一种折衷:只有在必须的时候才使用StringWriter。

        3
  •  20
  •   CPerkins    12 年前

    好吧,因为答案似乎强调了风格上的原因,所以我决定做一个时间测试。

    编辑 :根据robinst上面的评论,我现在有三个方法:一个是PrintWriter(StringWriter)样式的追加,还有两个是使用StringBuilder的:一个是在追加中追加换行符(如原来的: builder.append(thing + newline); builder.append(thing).append(newline); ).

    哦,当然,创建的行数和行长是随机的,但是对于每对调用保持相同,因为我想避免缓冲区大小或行大小对结果的任何可能影响。

    代码如下: http://pastebin.com/vtZFzuds

    TL医生? 每个方法100000次调用的平均结果非常接近:

    • 使用StringBuilder每次调用0.11908毫秒(+参数内的换行符)
    • 使用StringBuilder每次调用0.10201毫秒(换行符作为单独的附加)

    这是如此接近,以至于时间几乎与我无关,所以出于风格原因,我将继续按我一贯的方式来做:StringBuilder(带有单独的append)。当然,在使用这个已建立且成熟的代码库时,我将主要遵循现有的约定,以尽量减少意外。

        4
  •  16
  •   krock    15 年前

    编剧 -StringWriter是写入StringBuffer的写入程序(类似于OutputStreams的ByteArrayOutputStream)

    -当然,如果你只是想在内存中构造字符串,那么StringBuilder就是你想要的。

    结论

    writer的设计意图是将字符数据推出一个流(通常是到一个文件或通过一个连接),因此能够使用writer简单地组装字符串似乎有点副作用。

    StringBuilder(及其同步的同级StringBuffer)是 设计 StringBuilder API 你可以看到,你不仅可以做香草追加,但也取代,反向,插入等StringBuilder是你的字符串建设的朋友。

        5
  •  7
  •   pjbarnes    14 年前

    我看到了PrintWriter方法的两个优点: (1) 你不必在每一行的末尾加上“+换行符”,如果你要写很多东西的话,这实际上会导致代码变短。 (2) 您不必调用System.getProperty();你让版画作者担心换行符应该是什么。

        6
  •  2
  •   omid haghighatgoo    10 年前

    在此链接中: http://nohack.eingenetzt.com/java/java-stringwriter-vs-stringbuilder 作者展示了StringWriter甚至比StringBuilder快一点,还说:“因此,当大量数据发挥作用时,StringWriter在性能上明显优于StringBuilder。”

        7
  •  0
  •   A248 Uwe Plonus    4 年前

    StringBuffer this question on StringBuilder vs. StringBuffer

    考虑到这一点,StringBuilder可以稍微快一点。因此,如果要编写对性能敏感的代码,除非需要同步,否则最好使用StringBuilder。

    在我的例子中,我必须在使用StringBuilder或StringWriter作为 Appendable ,我不需要同步StringWriter/StringBuffer。

    总结一下:

    • StringBuilder-未在内存中同步追加
    • StringBuffer-在内存中同步附加
    • StringWriter—包装StringBuffer,还扩展了Writer