What are the pros and cons of using private methods that return a String instead of going around a StringBuilder

Consider a class with the "buildMessage" method (something like):

public class MessageBuilder { public String buildMessage() { //Build up the message and return // //Get the header //Get the body //Get the footer //return } } 

When we create our message, it is preferable to create strings using a StringBuilder (or a similar buffering object) rather than just instantiating a bunch of strings. But does this mean that you are losing this advantage by returning a String instead of taking your StringBuilder as an argument?

In other words, it is well read and easy to understand:

 private String getHeader() { StringBuilder builder = new StringBuilder(); builder.append("Hello ") .append(this.firstname) .append(",\n"); return builder.toString(); } 

It seems more natural to me than being forced into a StringBuilder, but we could also write:

 private void appendHeader(StringBuilder builder) { builder.append("Hello ") .append(this.firstname) .append(",\n"); } 

The first option allows you to use get methods, even if the intention is not to add the return value to the buffer. It also simplifies the understanding of the social method:

 public class MessageBuilder { public String buildMessage() { StringBuilder builder = new StringBuilder(); builder.append(getHeader()) .append(getBody()) .append(getFooter()); return builder.toString(); } } 

When using the second option:

 public class MessageBuilder { public String buildMessage() { StringBuilder builder = new StringBuilder(); appendHeader(builder); appendBody(builder); appendFooter(builder); return builder.toString(); } } 

My question is whether the first option depends on the same memory problems as "concinating" + "strings" + "together". I would be interested to hear opinions about what reads better (because if there is a clear winner in that one is cleaner and easier to read, it would greatly affect its benefit), but I am also interested in the effectiveness of it. I suspect that little does not matter there, but ask yourself if anyone knows about the costs associated with each approach - if this is you, please share it!

+6
source share
5 answers

Reusing StringBuilder is more efficient for the processor. However, I doubt it really matters.

You must do what you think is most natural and understandable. (Which seems to be StringBuilder from what you are saying)

Performance is only less common - a good reason to do something that many people think.

+1
source

Basically, with the first option, you suffer from two different flaws.

one). You create the stringBuilder object 3 more times (so only 4 times), while in the second version it is created only once and reused. Creating an object should be worth it, so you usually use stringBuilder when you are doing a few string string manipulation tasks.

2). Since each header, body, and footer return a string, in each case you create a normal string and copy it unnecessarily, this is detrimental to the purpose of using stringBuilder. Basically, equating a normal string, it simply recreates it from scratch, so you suffer the same overhead that occurs during creation when you create (because concating just recreates from scratch).

You are probably better off creating a class, and in the class constructor you can create a string builder object, so you don't need to do this in your top-level code. inside the class, you can use three methods, each of which uses a private object of the string builder when it creates and ultimately returns a string. this way you can just make your calls without passing a string strobe argument and without creating an object in your top-level code (messy material is automatically processed in the class according to your code, this will make it easier to read) ... :)

Hope this helps. if you want me to explain further let me know.

you should only worry about these things if there are a large number of calls to these procedures on your server, and especially if this happens in a For loop, and even more so if both of these points are true or apply.)

cheers mate.

0
source

Desired Thinking

That would be great - if StringBuilder was not the last class. Put the append ... methods in an inner class that extends StringBuilder:

 public class MessageBuilder { public String buildMessage() { return "" + MyStringBuilder() .appendHeader() .appendBody() .appendFooter(); } private class MyBuilder extends StringBuilder { MyBuilder appendHeader() { append("Hello ") .append(this.firstname) .append(",\n"); } } 

The approach that actually works β€” with much more work β€” is to write a (not finite!) Delegate class for StringBuilder and implement private special extensions like this one as subclasses. See discussion here .

0
source

Just because I do not see in it a special mention in other answers:

 private String getHeader() { StringBuilder builder = new StringBuilder(); builder.append("Hello ") .append(this.firstname) .append(",\n"); return builder.toString(); } 

can be replaced by

 private StringBuilder builder = new StringBuilder(); private String getHeader() { builder.setLength(0); builder.append("Hello ") .append(this.firstname) .append(",\n"); return builder.toString(); } 

The buffer will be allocated once. When the buffer is expanded, the extension is retained until the declaration object is assembled. Thus, no time is wasted when redistributing and resizing the buffer.

The only failure is that you may need to make your method synchronous (i.e. thread safe).

Using an existing string buffer is faster than a string because allocation is not required. Manual string concatenation is quite expensive, as multiple highlighting is required.

PS: Of course, the private allocation of the string builder can be divided between private methods, that is, the end user does not need to select it independently. In some cases, passing a buffer makes the code more readable and more functional. There is no definite answer or rule, it really depends on what you are doing and what you need.

0
source

The latter approach will be a true builder pattern if "StringBuilder" is hidden in the instance variable. The reason for using this design pattern (the first examples are NOT designpattern Builder) is to make derived classes that overwrite the appendHeader / appendFooter and appendBody methods (for example, you would like to create a little snippet HTML code. If you only want to gracefully build a line, then an easy example (the second last) looks best, and most likely, for younger programmers it is most easy to understand.

-one
source

All Articles