14

What is a Java StringWriter, and when should I use it?

I have read the documentation and looked here, but I do not understand when I should use it.

Jack Lawrence
  • 10,664
  • 1
  • 47
  • 61
MarkusWillson
  • 411
  • 1
  • 3
  • 11
  • 3
    Maybe this would be useful for other people to know. – MarkusWillson Dec 01 '14 at 03:34
  • 3
    All people can simply search for `StringWriter` javadoc. – Sotirios Delimanolis Dec 01 '14 at 03:34
  • 3
    What part of 'A character stream that collects its output in a string buffer, which can then be used to construct a string' don't you understand? – user207421 Dec 01 '14 at 03:35
  • 1
    Thank you for all of the answers! They are all exceptionally useful! Especially, I would like to thank the people who answered for giving examples of usage that one cannot simply find in the documentation, such as @RossBille 's explanation of its usage in concatenation optimization, and Jaskey's explanation of its usage in printing stacktraces. – MarkusWillson Dec 01 '14 at 04:02
  • @MarkusWillson , please accept one of the answers if it answers your question and helps you. And next time, you should ask question with a more meaningful title with a narrow scope after you search some similar question on SO, so that nobody downvotes. – JaskeyLam Dec 01 '14 at 07:03

2 Answers2

31

It is a specialized Writer that writes characters to a StringBuffer, and then we use method like toString() to get the string result.

When StringWriter is used is that you want to write to a string, but the API is expecting a Writer or a Stream. It is a compromised, you use StringWriter only when you have to, since StringBuffer/StringBuilder to write characters is much more natural and easier,which should be your first choice.

Here is two of a typical good case to use StringWriter

1.Converts the stack trace into String, so that we can log it easily.

StringWriter sw = new StringWriter();//create a StringWriter
PrintWriter pw = new PrintWriter(sw);//create a PrintWriter using this string writer instance
t.printStackTrace(pw);//print the stack trace to the print writer(it wraps the string writer sw)
String s=sw.toString(); // we can now have the stack trace as a string

2.Another case will be when we need to copy from an InputStream to chars on a Writer so that we can get String later, using Apache commons IOUtils#copy :

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);//copy the stream into the StringWriter
String result = writer.toString();
JaskeyLam
  • 15,405
  • 21
  • 114
  • 149
  • A lot of your explanation was already covered in my answer – RossBille Dec 01 '14 at 07:14
  • 1
    @RossBille , you give a good explaination but with a bad example in which we should not choose `StringWriter` actually. Besides, I don't think we should call it similar to `StringBuffer`/`StringBuilder`, it is more like a adapter which deals with stream/writer cases , this should only be should when we have no other choices. – JaskeyLam Dec 01 '14 at 07:23
7

It is used to construct a string char-by-char or string-by-string.

It is similar to StringBuilder but uses a StringBuffer under the hood. This is preferable when you are working with an API that requires a stream or writer. If you don't have this requirement it should be more efficient to use a StringBuilder (due to the synchronisation overhead of StringBuffer).

Of course this only makes sense if you realise that string concatenation (eg.

String s = "abc"+"def"; //... (especially when spread throughout a loop)` 

is a slow operation (see here).

small e.g.

StringWriter writer = new StringWriter();
writer.write('t');
writer.write("his awesome");
String result = writer.toString();
System.out.println(result); //outputs this is awesome

A better example:

String[] strings = /* some array of strings*/
StringWriter writer = new StringWriter();
for(String s : strings){
    writer.write(s);
}    
String result = writer.toString();
System.out.println(result);
RossBille
  • 1,448
  • 1
  • 17
  • 26