StringBuilder与StringWriter和PrintWriter的string组装

我最近遇到了一个我以前没见过的成语:由StringWriter和PrintWriter组装起来的string。 我的意思是,我知道如何使用它们,但是我一直使用StringBuilder。 有一个比另一个更喜欢的具体原因吗? StringBuilder方法对我来说似乎更加自然,但它是风格吗?

我在这里看到了几个问题(包括最接近的一个: StringWriter或者StringBuilder ),但是没有一个答案实际上解决了是否有理由相对于简单的string程序集来优先考虑的问题。

这是我见过的很多习惯用法:StringBuilder的string汇编:

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的string组装:

 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(); } 

编辑似乎没有什么具体的理由可以相互比较,所以我已经接受了最符合我理解的答案,并且答复了所有其他的答案。 另外,我贴出了我自己的答案,给出了我跑的基准的结果,以回答其中的一个答案。 谢谢大家。

再次编辑事实certificate,有一个具体的原因喜欢一个(特别是StringBuilder)而不是另一个。 我第一次错过的是添加换行符。 当你添加一个换行符(如上面,作为一个单独的append)时,它会稍微快一点 – 不是很大,但加上意图的清晰度,它肯定更好。 请参阅下面的答案以改善计时。

在风格上, StringBuilder方法更清洁。 它是更less的代码行,并使用专门为构buildstring而devise的类。

另一个考虑是哪个更有效率。 回答这个问题的最好方法是对两个select进行基准testing。 但是有一些清晰的指针,StringBuilder 应该更快。 首先,StringWriter使用StringBuilder中的 StringBuffer来保存写入“stream”的字符。

StringWriter是当你想要写入string的时候使用的,但是你正在使用一个需要Writer或者Stream的API。 这不是一个select,这是一个妥协:只有当你必须使用StringWriter。

好吧,由于答案似乎强调了比较喜欢的风格理由,所以我决定创build一个时间testing。

编辑 :在上面的robinst的注释之后,我现在有三个方法:一个是PrintWriter(StringWriter)types的追加,另外两个是使用StringBuilder:一个是追加内部的换行符(如原始文件: builder.append(thing + newline); ),另一个做一个单独的append(如上: builder.append(thing).append(newline); )。

我遵循我通常的基准testingscheme:首先调用几个方法(在这种情况下为1000次),让优化器有足够的时间进行预热,然后以交替的顺序每次调用大量的次数(在这种情况下为100,000次)在工作站的运行环境中更公平地分布,并且多次运行testing并且平均结果。

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

这里的代码是: http : //pastebin.com/vtZFzuds

注意:我还没有更新pastebin代码来反映新的testing。

TL,DR? 每种方法的100,000次调用的平均结果非常接近:

  • 每个调用0.11908毫秒使用StringBuilder(+ paren换行符)
  • 每个调用使用StringBuilder 0.10201毫秒(换行符作为单独的追加)
  • 每个调用使用PrintWriter(StringWriter)0.10803毫秒

这是非常接近的时间几乎与我无关,所以我会继续按照我总是做的方式:StringBuilder(具有单独的追加),出于文体的原因。 当然,在这个已经build立和成熟的代码库中工作的时候,我会主要遵守现有的约定,以尽量减less意外。

作家 – PrintWriter写入一个stream。 它做怪异的事情,如抑制IOExceptions。 System.out就是其中之一。 – StringWriter是写入到StringBuffer的Writer(类似于OutputStreams的ByteArrayOutputStream)

StringBuilder – 当然StringBuilder是你想要的,如果你只是想在内存中构造string。

结论

作家的devise是为了将字符数据从stream(通常是文件或通过连接)推出,所以能够使用作家简单地组装string似乎有点副作用。

StringBuilder(和它的同步兄弟StringBuffer)被devise来组装string(读取stringbashing)。 如果你看看StringBuilder的API,你可以看到,不仅可以做香草追加,而且还可以replace,反向,插入等。StringBuilder是你的stringbuild设的朋友。

我看到了PrintWriter方法的两个优点:(1)不必在每一行的末尾添加“+ newline”,如果你需要大量的写入,实际上会导致代码变短。 (2)您不必调用System.getProperty(); 你让PrintWriter担心换行符应该是什么。

在这个链接: http : //nohack.eingenetzt.com/java/java-stringwriter-vs-stringbuilder作者表示,StringWriter比StringBuilder还要快一点,并且还说:“所以当大量的数据进入玩StringWriter清楚地performance出它比StringBuilder在性能上的优越性。“