>>Let's talk about differences between StringBuilders and Strings. In Java there are actually three
String-like classes. When I say String-like, what I mean is that sequences of characters
are stored. Now when a computer scientist says sequence what they mean is order is important.
So for example, ABC is different than CBA. And that is certainly true in the case of
sequences of characters.
The first class is called the String class and you've seen this one quite a bit. Now
it has a special syntax to it and that can be both good or bad. So, I've talked a little
bit about the fact that when you have a String name equals double quote ABC double quote,
that that's actually calling a constructor in building a new object. This is something
that's sort of curious in Java. The way I look at it is this: If you think about human
language, you'll find that the most commonly used things become irregular. So for example
if you've ever spoken a foreign language you'll find that it's very common for the verbs 'to
be', 'to make', 'to do' to be highly irregular, even weird at times. Well, guess what? That
happens in synthetic language too. It's really quite amazing.
Now the String object has a very unusual property. It's called immutable. What that means is
once you create a String object you absolutely positively cannot change it no matter what.
And that is kind of strange and has some important consequences that we'll discuss today. Now
the StringBuilder is very similar to the String, but the difference is it's mutable-- that
is the characters can be changed in it. There is a third String-like class, it's called
StringBuffer. Now this one has a unique property called synchronization. Synchronization is
a very advanced topic in programming and one we're not going to approach this semester,
so we're not going to use the StringBuffer class at all.
When you got o access String properties, you can do it like this. First you build the String
object so we could say String name equals new String double quote Sadie. Name dot length,
return the number of characters in the String. Now length is unit indexed. When I say unit
indexed I mean we start counting at one. So Sadie has five letters in it and that's what
will be returned. You also can find out what the individual letters are by asking for them
by number. So name dot char at zero returns a capital S. Now you'll notice that the letters
themselves are zero indexed. So the first letter is zero, the second one is one, the
third one is two. That's going to seem a little weird at first, and it is certainly the source
of a lot of mistakes for beginners-- but you will get used to it soon.
Here's the pattern for calling methods that are in the String class. We have the reference
to the object and then a period, then the method names, and then any arguments. Now
remember there may be arguments there may not. It just depends on which method you're
calling. So for example the length method doesn't have any arguments, but the charAt
method does have one. One integer argument I might add. All of the methods that are available
in the String class are documented in the API.
To lower case is an example of a method that's in the String class. What this class does
is it changes any upper case letters that happen to be in the String to lower case.
Now wait, you should be thinking, "Just a minute ago you told me that Strings were immutable."
And Strings are immutable, but what it really does is it creates a new String object with
all lower case characters. So it takes the one's that were upper case and it changes
them to lower case. And then it returns the reference, which remember we can store or
not store as we prefer.
Now let's take a look at what this means in a memory diagram. So if we say String name
is new String Sadie. This is what we have. This is String object and memory. Notice the
reference name points to the object that's stored on the heap. Then we say name equals
name dot to lower case. Now name dot to lower case creates a new object. Notice it's Sadie
with a little S. It's not changing the original object because the original object is unchangeable.
Then, because we stored the reference that was returned by name.dot to lower case and
name itself, the reference gets replaced. So notice right over here on the left hand
side we're pointing to the new object that's in lower case and the reference to the original
object has been lost. So at this point, this object, the one with Sadie with a capital
S, that one is going to disappear when it gets garbage collected.
Now the other thing to notice here is what we're dealing with is a hidden constructor.
That is, the to lower case method is constructing a new String object inside the method itself
and it's returning it. So these hidden constructors can cause a lot of grief in Java. We need
to look for them very carefully. Now let's talk about a StringBuilder. StringBuilder
is also a sequence of a characters, but this time it's mutable. That means we can make
changes to the object without reconstructing it. The access is very similar to a String,
and in fact some of the most useful methods are identical. So if we could say StringBuilder
name equals new StringBuilder and then Abby in double quotes. Now StringBuilders are not
that common a class, and so they don't have any shortcut operators like the String class
does. So all we have is the regular constructor. If we call name dot length now on our StringBuilder
object, it's going to return four because Abby has four characters. If we call name
dot charAt zero, this returns a capital A because the zero of character of the String
that the reference name refers to is a capital A. Remember, charAt uses zero indexing.
Now, for mutating if we start with a StringBuilder name equals new StringBuilder Sadie, this
is what we have. Remember the StringBuilder is different than the String. So if we call
name dot reverse what happens is this: The characters inside the original object get
changed. So instead of having Sadie we have eidaS, or something like that, Sadie reversed.
Notice we did not have to assign it for this to happen, so this is a very different mechanism
then what we've seen in the String class. And all of this has to do whether the objects
are mutable or immutable.
Now what this means is inside every program we have some really tough software engineering
decisions. Strings are more efficiently represented than StringBuilders. Now the reason is the
StringBuilder needs to have some excess capacity. So if you make changes it can respond to them.
Excess capacity is wasted if changes aren't needed. Now, if no changes are needed or if
very minimal changes are needed, you're probably better off using the String. If changes are
definitely going to be needed than you need to use the StringBuilder. So this becomes
an important decision you make with every program you write. String, StringBuilder,
and it all depends on whether you think the objects are going to change or not. So keep
programming.