Take note that although objects of classes like Integer
and Double
can hold primitive numbers, the value stored in one cannot be changed once the object has been created. We call classes like these, where the value is fixed at initialization time and cannot later be changed, immutable.
So what if you have a number and want to replace it by the result of some computation? You have to create a new object of the Number
type and replace your pointer to the old Number
by a pointer to the new one:
Integer i = new Integer(0);
⋮
// what if we want to increment i?
i = new Integer(i.intValue() + 1);
Because of the automatic boxing and unboxing, you can often omit the intValue()
and new Integer()
calls, but they are still happening in the background.
The printf
and format
functions are actually drawn from C++’s parent language, C. printf
is available in C++ as well, though most C++ programmers do not use it, preferring to work with the stream-based <iomanip>
functions.
The single biggest change for C++ programmers is that Java Strings are immutable. You cannot alter an already-initialized String object. If you want to, for example, add a character to the end of a string or delete a bunch of characters from a string, you need to actually create a new string object that is initialized with the altered content that you want.
StringBuilder and the related StringBuffer class are very important when working with code that builds strings incrementally over a lengthy calculation. For example, I once had a programmer working on an application to convert documents from one word processor format to another who wrote code like this:
String output = "";
for (int i = 0; i < inputDocumentLength; ++i) {
String s = convertCharacterOfInput (i);
output = output + s;
}
It was terribly slow for reasonably sized documents. Why? Look at the statement
output = output + s;
Let’s assume that most of the conversions yield at least one character. Then, on the i’th iteration of the loop, output will already have at least i
characters. So the concatenation operator (+
) has to copy at least i characters from output
plus at least 1 character from s
. So the number of characters to be copies is at least i+1
.
So on the first iteration of the loop, we copy at least 1, character, on the next, we copy at least two, and so on. On the final iteration, we are copying at least inputDocumentLength characters. Add that up over all the iterations of the loop, and you get at least 0.5 * inputDocumentLength<sup>2</sup>
characters being copied. So for a 10,000 character document, we’re talking about copying 50 million characters. That’s pretty bad. By contrast, if we do this:
StringBuffer output = new StringBuffer;
for (int i = 0; i < inputDocumentLength; ++i) {
String s = convertCharacterOfInput (i);
output.append(s);
}
then the total number of characters copies in in the range 10,000–20,000, which is much, much better.