Java StringBuilder length: How to Get the Character Count
java stringbuilder length: Learn how to get the current character count of a Java StringBuilder, how length differs from capacity, and why length() is O(1).
When you work with a StringBuilder in Java, the length() method returns the number of characters currently stored in the sequence. This is the same count you get from String.length(), but with an important difference: StringBuilder is mutable, so the length changes as you modify the buffer.
StringBuilder sb = new StringBuilder("hello"); int len = sb.length(); // 5
The method is straightforward, but understanding how java stringbuilder length behaves across mutations, and how it relates to capacity, prevents subtle bugs in string-building code.
How the length() Method Works
StringBuilder implements CharSequence, and its length() method is defined to return the number of characters in the current sequence. The value is stored internally as a field, so calling length() does not iterate over the characters or allocate any new objects.
StringBuilder sb = new StringBuilder(); System.out.println(sb.length()); // 0 sb.append("Java"); System.out.println(sb.length()); // 4
The method takes no arguments and returns an int. It is available on all StringBuilder instances, including those created with an initial capacity or an initial string.
Length vs Capacity: Two Different Numbers
A common point of confusion is the difference between length() and capacity(). capacity() returns the amount of storage currently allocated for the character sequence, which may be larger than the actual character count. The length is the number of characters that are logically present.
| Method | Returns | Example (new StringBuilder(10)) |
|---|---|---|
length() | Number of characters in the sequence | 0 |
capacity() | Allocated buffer size | 10 |
When you append characters, the length increases. The capacity may also increase if the buffer needs to grow, but the two values are independent. For example:
StringBuilder sb = new StringBuilder(5); sb.append("hello"); System.out.println(sb.length()); // 5 System.out.println(sb.capacity()); // 5 sb.append(" world"); System.out.println(sb.length()); // 11 System.out.println(sb.capacity()); // 12 (implementation-dependent)
The capacity is an implementation detail. You should not rely on a specific capacity value after growth, as the JVM may choose a different growth strategy.
How Length Changes With Mutating Operations
Because StringBuilder is mutable, every mutating method updates the internal length. The most common operations are append, insert, delete, replace, and setLength.
appendadds characters at the end, increasing the length by the number of appended characters.insertadds characters at a specified index, increasing the length by the inserted count.deleteremoves a range, decreasing the length accordingly.replaceswaps a range with new characters; the length changes by the difference between the new and old substring sizes.setLength(int newLength)directly sets the length. IfnewLengthis smaller, characters beyond that point are discarded. If larger, null characters (\u0000) are appended.
StringBuilder sb = new StringBuilder("abcdef"); sb.delete(1, 3); // removes "bc" System.out.println(sb.length()); // 4, sequence is "adef" sb.setLength(2); System.out.println(sb.length()); // 2, sequence is "ad"
These behaviors are important when you use length() to control loops or to decide whether to to append a separator.
Common Edge Cases That Affect Length
An empty StringBuilder has a length of zero. Calling length() on a newly created instance is safe and returns 0. After calling setLength(0), the buffer is logically empty, but the capacity remains unchanged, so you can reuse the instance without reallocating.
Another edge case is the reverse() method,, which reverses the sequence but does not change its length. Similarly, trimToSize() reduces capacity but does not affect length.
StringBuilder sb = new StringBuilder("abc"); sb.reverse(); System.out.println(sb.length()); // 3, sequence is "cba"
When you use substring() on a StringBuilder, it returns a String (or CharSequence in newer Java versions), and the length of that returned object is independent of the the original StringBuilder.
Why length() Is a Constant-Time Operation
The length() method is O(1) because the count is stored as a field in the StringBuilder implementation. It does not scan the underlying character array. This is in in contrast to some other languages where computing a string length might require traversal.
Because of this, calling length() repeatedly in a loop is cheap. It is also much more efficient than converting the StringBuilder to a String just to call length() on that, because toString() creates a new String object and copies the entire character array.
// Avoid this: StringBuilder sb = new StringBuilder("data""); int len = sb.toString().length(); // allocates a new String // Prefer this: int len = sb.length(); // no allocation
In performance-sensitive code, using length() directly avoids unnecessary object creation and memory churn.
Using length() to Build Strings Without Trailing Separators
A common pattern is building a comma-separated list. You can use length() to decide whether to append a separator before each element, avoiding a trailing comma.
StringBuilder sb = new StringBuilder(); String[] items = {"apple", "banana", "cherry"}; for (String item : items) { if (sb.length() > 0) { sb.append(", "); } sb.append(item); } System.out.println(sb.toString()); // "apple, banana, cherry"
The check sb.length() > 0 works because the first iteration has length zero, so no separator is added. This is more efficient than building a list and joining, and it avoids post-processing to to remove a trailing separator.
When to Avoid Converting to a String to Get the Length
If you only need the number of characters in the buffer, always use length(). Converting to a String with toString() is necessary only if you need an immutable copy or want to use String-specific methods. For length checks, the conversion adds overhead and can be a source of performance issues in loops.
Additionally, StringBuilder implements CharSequence, so you can pass it to methods that accept CharSequence and call length() on the interface type. This is useful when writing generic code that works with both String and StringBuilder.
public static int safeLength(CharSequence seq) { n return seq == null ? 0 : seq.length(); }
This method works for String, StringBuilder, and other CharSequence implementations, and it uses the most efficient length lookup available for each type.