我最近遇到了一个我以前没见过的成语:StringWriter和PrintWriter的字符串汇编.我的意思是,我知道如何使用它们,但我一直使用StringBuilder.是否有一个具体的理由选择一个而不是另一个?StringBuilder方法对我来说似乎更自然,但它只是风格吗?
我在这里看了几个问题(包括最近的一个问题:StringWriter或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();
    }
编辑似乎没有具体的理由偏爱其中一个,所以我接受了最符合我理解的答案,并且+ 1除了所有其他答案.另外,我发布了自己的答案,给出了我运行的基准测试结果,以回答其中一个答案.谢谢大家.
再次编辑事实证明,有是一个具体的理由,更喜欢一个(特别是StringBuilder的)比其他.我第一次错过的是添加换行符.当你添加一个换行符(如上所述,作为一个单独的追加)时,它会稍微快一点 - 不是很大,但加上意图的清晰度,它肯定会更好.请参阅下面的答案,了解改进的时间安排.
Ala*_*ore 39
StringWriter是您在要写入字符串时使用的,但是您正在使用期望Writer或Stream的API.它不是替代品,它是一种妥协:只有在必要时才使用StringWriter.
CPe*_*ins 19
好吧,既然答案似乎强调了偏爱一方的风格原因,我决定进行时间测试.
编辑:按照上面robinst的评论,我现在有三种方法:一是它确实为PrintWriter(StringWriter的)风格的附加,而其中两个使用StringBuilder(原为:一个换行符的追加追加内builder.append(thing + newline);),以及其他人做一个单独的追加(如上所述:) builder.append(thing).append(newline);.
我遵循我通常的基准测试方案:首先调用几个方法(在这种情况下为1000),以便优化器有时间预热,然后按交替顺序多次调用每次(在这种情况下为100,000),以便进行任何更改在工作站的运行时环境中,分布更加公平,并多次运行测试本身并对结果进行平均.
哦,当然,创建的行数和行的长度是随机的,但对于每对调用都保持相同,因为我想避免缓冲区大小或行大小对结果产生任何可能的影响.
代码如下:http://pastebin.com/vtZFzuds
注意:我还没有更新pastebin代码以反映新测试.
TL,DR? 每种方法100,000次调用的平均结果非常接近:
那是如此接近以至于时间几乎与我无关,所以我将继续按照我一直以来的方式做事:StringBuilder(带有单独的附加),出于文体原因.当然,在这个既定且成熟的代码库中工作时,我将主要遵循现有的约定,以尽量减少意外.
Ste*_*n C 18
在风格上,这种StringBuilder方法更清洁.代码行数较少,并且使用专门为构建字符串而设计的类.
另一个考虑因素是更有效率.回答这个问题的最佳方法是对两种替代方案进行基准测试.但是有一些明确的指示,StringBuilder 应该更快.首先,StringWriter使用StringBuilder StringBuffer来保存写入"stream"的字符.
kro*_*ock 14
作家 - PrintWriter写入流.它做了一些奇怪的事情,比如压制IOExceptions.System.out就是其中之一. - StringWriter是一个写入StringBuffer的Writer(类似于OutputStreams的ByteArrayOutputStream)
StringBuilder - 当然,如果你只是想在内存中构造字符串,那么StringBuilder就是你想要的.
结论
设计的作者是为了将字符数据推出流(通常是文件或通过连接),因此能够使用Writers简单地组装字符串似乎有点副作用.
StringBuilder的(和它的同步兄弟的StringBuffer)被设计来组装字符串(字符串读扑).如果您查看StringBuilder API,您可以看到,您不仅可以执行vanilla附加,还可以替换,反向,插入等.CtringBuilder是您的String构建好友.
小智 7
我看到了PrintWriter方法的两个优点:(1)您不必在每一行的末尾添加"+换行符",如果您有大量的写入操作,实际上会导致更短的代码.(2)您不必调用System.getProperty(); 你让PrintWriter担心换行符应该是什么.