Numbers and Strings: Commentary

Steven Zeil

Last modified: Aug 19, 2016
Contents:

The numbers and String classes are some of the most common utility classes in Java programming.

1 Numbers

1.1 The Numbers Classes

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.

1.2 Formatting Numeric Print Output

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.

1.3 Beyond Basic Arithmetic

1.4 Summary of Numbers

2 Characters

3 Strings

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.

3.1 Converting Between Numbers and Strings

3.2 Manipulating Characters in a String

3.3 Comparing Strings and Portions of Strings

3.4 The StringBuilder Class

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.

3.5 Summary of Characters and Strings