Tech Geek
Tech Geek

Reputation: 465

String vs StringBuilder

I have a condition like :

public String createId(List<String> list)
{
String id="";
if(list.contains("name"))
id+="TEST VALUE NAME";
if(list.contains("age"))
id+="Test Value AGE";
.
.
. likewise many if condition
return id;
}

As per my understanding we should use StringBuilder in loop condition and String in simple concatenation. So here wanted to ask I should use String or StringBuilder? Kindly suggest

Upvotes: 0

Views: 309

Answers (4)

Pieter van Onselen
Pieter van Onselen

Reputation: 1

As already said StringBuilder is immutable and String is not.

To add to this, when compiler compiles string concatenations it converts it to StringBuilder. String concatenation in toString in Java

Something else to keep in mind is that id+="TEST VALUE NAME"; will add complicity if you do code analysis with Sonar or other tools.

Using StringBuilder will not add complexity with analysis tools.

Upvotes: -1

Nowhere Man
Nowhere Man

Reputation: 19545

It seems that for the given task it would be better to get rid of the multiple duplicated if statements by defining a list of the keys to match the input list and use Stream API to generate the string id, e.g. Collectors.joining with delimiter or without the delimiter.

Assuming that there is a single rule to create a part of the id: append "Test Value " + key.toUpperCase(), the implementation may look as follows:

final List<String> keys = Arrays.asList(
    "name", "age" /* and other needed keys*/
);

public String createId(List<String> list) {
    return keys
            .stream()
            .filter(list::contains)
            .map(String::toUpperCase)
            .map(str -> "Test Value " + str)
            .collect(Collectors.joining("_")); // or Collectors.joining()
}

System.out.println(createId(Arrays.asList("age", "name", "surname")));
// output: Test Value NAME_Test Value AGE

If custom parts should be provided for name, age, etc., a Map of matches should be prepared and used, also it may make sense to convert the input list into Set<String to facilitate look-ups:

final Map<String, String> keys = new LinkedHashMap<>(); {
    // fill the map in special order
    keys.put("name", "Name Part");
    keys.put("age", "Test Age");
    /* and other needed keys*/
}

public String createId(List<String> list) {
    Set<String> words = new HashSet<>(list);
    return keys.keySet()
            .stream()
            .filter(words::contains) // faster lookup O(1) at the cost of another collection
            .map(keys::get)
            .collect(Collectors.joining("_")); // or Collectors.joining()
}

System.out.println(createId(Arrays.asList("age", "surname", "name")));
// output: Name Part_Test Age

Upvotes: 1

Paul
Paul

Reputation: 20061

In general your understanding is correct about when to use String concatenation vs StringBuilder. The Java Language Specification says

To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.

For the larger majority of cases you should use whichever method results in better readability and maintainability.

Upvotes: 0

Shimron Duan
Shimron Duan

Reputation: 441

StringBuilder is the best for this scenario because it's mutable. the String is immutable so when you modify the string it creates a new object.

Upvotes: 3

Related Questions