Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java StringBuilder.setLength() - is time complexity O(1)?

I'm planning to perform lots of deletes of the last character in StringBuilders. The solution to use sb.setLength(sb.length() - 1); looks good to me. However, since these deletions will be in a loop, I need to know complexity of it.

The way I understand it is that this operation simply decrements some private attribute of my StringBuilder object and does not perform any copying/cloning/duplicating of the characters themselves, thus it is O(1) in time and should work fast.

Am I right?

like image 588
alekscooper Avatar asked Jan 31 '16 05:01

alekscooper


People also ask

What does StringBuilder setLength do?

The setLength(int newLength) method of StringBuilder is used to set the length of the character sequence equal to newLength. For every index k greater then 0 and less than newLength. If the newLength passed as argument is less than the old length, the old length is changed to the newLength.

What is the time complexity of StringBuilder append?

It is O(1) when appending single characters. A StringBuilder is like an ArrayList. When you append a single item the cost is O(1). Appending a string is like calling addAll()--the cost is proportional to the length of the string / the number of items being added.

What is the time complexity of StringBuilder reverse?

So we have created an object “obj” of the StringBuilder class. Next, we are appending the input string “str” using the append() method. The reverse() method is then called using obj and the result is returned. The time complexity of the code will be O(N).

Is StringBuilder constant-time?

For String, StringBuffer, and StringBuilder, charAt() is a constant-time operation. For StringBuffer and StringBuilder, deleteCharAt() is a linear-time (i.e. O(n)) operation, and NOT constant time operation.


2 Answers

It's O(1) if the new length is less than the old one, which it is in your case.

The JDK's source code is available online, so you can check it for yourself. Using Java 8 as an example, setLength is implemented in AbstractStringBuilder. It does a few things:

  • errors if the new length < 0
  • ensures that the StringBuilder has enough capacity for the new length (which it will, if you're shortening the length)
  • fills in 0s for the additional length, if you're extending the length (which you're not)
  • sets the this.count field to the length you specify

Putting it all together:

  • If you're shortening the length, this is O(1) — a few quick checks and then a field assignment.
  • If you're increasing the length, but such that the old capacity is still sufficient, then it's O(N) where N is the additional length (for instance, if you had a 100-length builder, then shortened it to 10, and are are now increasing it to 90, then N would be 90-10=80)
  • If you're increasing the length such that the capacity needs to be increased, it's O(N) where N is the new capacity
like image 197
yshavit Avatar answered Sep 19 '22 19:09

yshavit


From the documentation:

Sets the length of the character sequence. The sequence is changed to a new character sequence whose length is specified by the argument. For every nonnegative index k less than newLength, the character at index k in the new character sequence is the same as the character at index k in the old sequence if k is less than the length of the old character sequence; otherwise, it is the null character '\u0000'. In other words, if the newLength argument is less than the current length, the length is changed to the specified length. If the newLength argument is greater than or equal to the current length, sufficient null characters ('\u0000') are appended so that length becomes the newLength argument.

The newLength argument must be greater than or equal to 0.

I would say yes. But I wouldn't see it from the point of view of time complexity. The reason we use StringBuilder instead of String in a loop is because Strings are immutable. Hence a new string object will always be created when we try to change it. When you change the length of a StringBuilder object, no new object is created.

like image 45
user3437460 Avatar answered Sep 22 '22 19:09

user3437460