Principle 7.8.1. DEBUGGING TIP: Off-by-One Errors.
Loops should be carefully checked to make sure they don’t commit an off-by-one error. During program testing, develop data that tests the loop variable’s initial and final values.
String
length()
method determines the number of characters in a String
and that strings are zero indexed. This means that the first character is at index 0, and the last character is at index length()-1
. For example, to print each character in a string on a separate line, we would step through the string from its first to its last character and print each character::// Precondition: str is not null
// Postcondition: the letters in str will have been printed
public void printLetters(String str)
{
for (int k = 0; k < str.length(); k++)// For each char
System.out.println(str.charAt(k)); // Print it
}
k < str.length()
, since the index of the last character of any String
is length()-1
. Note also the use of str.charAt(k)
to retrieve the kth character in str
on each iteration of the loop.str
has been properly initialized — that is, it is not null
. The postcondition merely states the expected behavior of the method.k <= str.length()
, this would cause an off-by-one error, because the last character in str
is at location length()-1
. This would lead to a Java IndexOutOfBoundsException
, which would be reported as soon as the program executed this statement.countChar()
method will count the number of occurrences of any particular character in a String
(Listing 7.8.2). This method takes two parameters: a String
parameter that stores the string being searched and a char
parameter that stores the character being counted.counter
, to 0. As in the previous example, the for
loop here will iterate through each character of the String
—from 0 to length()-1
. On each iteration a check is made to see if the character in the kth position (str.charAt(k)
) is the character being counted. If so, counter
is incremented. The method ends by returning counter
, which, when the method completes, will store an integer representing the number of ch’s in str
.reverse()
method. This is a method that reverses the letters in a string. For example, the reverse of "java"
is "avaj"
.reverse()
method should use a simple counting loop to reverse the letters in its String
parameter. In this case, however, we can process the string from right to left, beginning at its last character and ending with its first character. That way we can just append each character, left to right, in the result string:/*
* Pre: s is any non null string
* Post: s is returned in reverse order
*/
public String reverse(String s)
{
StringBuffer result = new StringBuffer();
for (int k = s.length()-1; k >= 0; k--) {
result.append(s.charAt(k));
} //for
return result.toString();
} // reverse()
keywordSearch()
— we should us a StringBuffer
to store the method’s result. Thus we declare the result
StringBuffer
at the beginning of the method and convert it back into a String
at the end of the method.StringBuffer
to store the result.capitalize()
method, which returns a String
whose initial letter is capitalized but whose other letters are lowercase — for example, “Hello”. We use the static
toUpperCase()
and toLowerCase()
methods from the Character
class to convert individual letters. The algorithm converts the first letter to upper case and then loops through the remaining letters converting each to lowercase:/*
* Pre: s is any non null string
* Post: s is returned with only its first letter capitalized
*/
public String capitalize(String s)
{
if (s.length() == 0) // Special case: empty string
return s;
StringBuffer result = new StringBuffer();
result.append(Character.toUpperCase(s.charAt(0)));
// Convert the first letter
for (int k = 1; k < s.length(); k++) { // And the rest
result.append(Character.toLowerCase(s.charAt(k)));
} //for
return result.toString();
} // capitalize()
reverse()
as a static method and write code to test it in the main while loop.removeBlanks()
, that accepts a string parameter and returns a string with all blank characters removed.String
Methods
String
class methods we have discussed — valueOf()
, equals()
, indexOf()
, lastIndexOf()
, charAt()
, substring()
— Table 7.8.4 shows some of the other useful methods in the String
class.String
methods applied to the literal string “Perfection”.Method Signature | Example |
boolean endsWith(String suffix) |
"Perfection".endsWith("tion") \(\Rightarrow\) true |
boolean startsWith(String prefix) |
"Perfection".startsWith("Per") \(\Rightarrow\) true |
boolean startsWith(String prefix, int offset) |
"Perfection".startsWith("fect",3) \(\Rightarrow\) true |
String toUpperCase() |
"Perfection".toUpperCase() \(\Rightarrow\) "PERFECTION"
|
String toLowerCase() |
"Perfection".toLowerCase() \(\Rightarrow\) "perfection"
|
String trim() |
"Perfection".trim() \(\Rightarrow\) "Perfection"
|
String
, methods such as toUpperCase()
, toLowerCase()
, and trim()
do not change their string. Instead they produce a new string. If you want to use one of these methods to convert a string, you must reassign its result back to the original string:String s = new String("hello world");
s = s.toUpperCase(); // s now equals "HELLO WORLD"