Home » Java » Remove last character of a StringBuilder?

Remove last character of a StringBuilder?

Posted by: admin November 2, 2017 Leave a comment

Questions:

When you have to loop through a collection and make a string of each data separated by a delimiter, you always end up with an extra delimiter at the end, e.g.

for(String serverId : serverIds) {
 sb.append(serverId);
 sb.append(",");
}

Gives something like : serverId_1, serverId_2, serverId_3,

I would like to delete the last character in the StringBuilder (without converting it because I still need it after this loop).

Answers:

Others have pointed out the deleteCharAt method, but here’s another alternative approach:

String prefix = "";
for (String serverId : serverIds) {
  sb.append(prefix);
  prefix = ",";
  sb.append(serverId);
}

Alternatively, use the Joiner class from Guava 🙂

As of Java 8, StringJoiner is part of the standard JRE.

Questions:
Answers:

Another simple solution is:

sb.setLength(sb.length() - 1);

A more complicated solution:

The above solution assumes that sb.length() > 0 … i.e. there is a “last character” to remove. If you can’t make that assumption, and/or you can’t deal with the exception that would ensue if the assumption is incorrect, then check the StringBuilder’s length first; e.g.

// Readable version
if (sb.length() > 0) {
   sb.setLength(sb.length() - 1);
}

or

// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));

Questions:
Answers:
sb.deleteCharAt(sb.length()-1) 

Questions:
Answers:

As of Java 8, there’s a new StringJoiner class built in.

StringJoiner sj = new StringJoiner(", ");
for (String serverId : serverIds) {
    sj.add(serverId)
}

Questions:
Answers:

In this case,

sb.setLength(sb.length() - 1);

is preferable as it just assign the last value to '\0' whereas deleting last character does System.arraycopy

Questions:
Answers:

Just get the position of the last character occurrence.

for(String serverId : serverIds) {
 sb.append(serverId);
 sb.append(",");
}
sb.deleteCharAt(sb.lastIndexOf(","));

Since lastIndexOf will perform a reverse search, and you know that it will find at the first try, performance won’t be an issue here.

Questions:
Answers:

Another alternative

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}
sb.deleteCharAt(0);

Questions:
Answers:

Alternatively,

StringBuilder result = new StringBuilder();
    for(String string : collection) {
        result.append(string);
        result.append(",");
    }
    return result.substring(0, result.length() - 1) ;

Questions:
Answers:

With Java-8 you can use static method of String class,

String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements).


public class Test {

    public static void main(String[] args) {

        List<String> names = new ArrayList<>();
        names.add("James");
        names.add("Harry");
        names.add("Roy");
        System.out.println(String.join(",", names));
    }
}

OUTPUT

James,Harry,Roy

Questions:
Answers:
StringBuilder sb = new StringBuilder();
sb.append("abcdef");
sb.deleteCharAt(sb.length() - 1);
assertEquals("abcde",sb.toString());
// true

Questions:
Answers:

Yet another alternative:

public String join(Collection<String> collection, String seperator) {
    if (collection.isEmpty()) return "";

    Iterator<String> iter = collection.iterator();
    StringBuilder sb = new StringBuilder(iter.next());
    while (iter.hasNext()) {
        sb.append(seperator);
        sb.append(iter.next());
    }

    return sb.toString();
}

Questions:
Answers:

To avoid reinit(affect performance) of prefix use TextUtils.isEmpty:

            String prefix = "";
            for (String item : list) {
                sb.append(prefix);
                if (TextUtils.isEmpty(prefix))
                    prefix = ",";
                sb.append(item);
            }

Questions:
Answers:

I am doing something like this:

    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i < value.length; i++) {
        stringBuilder.append(values[i]);
        if (value.length-1) {
            stringBuilder.append(", ");
        }
    }

Questions:
Answers:

You may try to use ‘Joiner’ class instead of removing the last character from your generated text;

                List<String> textList = new ArrayList<>();
                textList.add("text1");
                textList.add("text2");
                textList.add("text3");

                Joiner joiner = Joiner.on(",").useForNull("null");
                String output = joiner.join(textList);

               //output : "text1,text2,text3"

Questions:
Answers:

Here is another solution:

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}

String resultingString = "";
if ( sb.length() > 1 ) {
    resultingString = sb.substring(1);
}