0

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

Tech Geek
  • 437
  • 1
  • 4
  • 19
  • StringBuilder would be prefered – sanjeevRm Jul 30 '21 at 06:35
  • You may format your code by indenting it. – Ravindra Ranwala Jul 30 '21 at 06:56
  • 2
    Assuming there’s a large number of these `if` statements, a `StringBuilder` would be preferable, but then, you should also be concerned about these repeated linear searches. – Holger Jul 30 '21 at 10:11
  • Even if a `StringBuilder` is preferred over a `String +=` here, the `.contains`, `List` and general structure of the code here are most likely having a bigger impact than `StringBuilder` vs `String`. For example, If all your conditions look like this (each value in the list maps to exactly one value the resulting string), you could just loop trough the List once, add a `switch-case` and concat using a `StringBuilder` in that loop. Or use a `Set`. Each call to `contains` on a `List` has to loop through all elements until it finds the queried value. Then again, dont do premature optimization. – Felix Jul 30 '21 at 10:50

4 Answers4

3

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.

Shimron Duan
  • 391
  • 1
  • 3
  • 9
  • Not necessarily. According to the [Java Language Specification](https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.18.1), "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." – Paul Jul 30 '21 at 12:50
1

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
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
0

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.

Paul
  • 19,704
  • 14
  • 78
  • 96
-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.

  • Thanks for contributing your first answer! It needs a bit of editing: "StringBuilder is mutable and String is not." And you surely meant "complexity" instead of "complicity." – David Gish Mar 08 '23 at 22:26