|
|
The String class provides a variety of useful methods for manipulating String objects. Remember that the text of a String object cannot be changed, which means that many of its methods are read-oriented or return a new String object of the required changes.
In order to compare the text values of one String object to another, you cannot just use the equality operator (==) because this will test if two variables reference the same object. The method equals, a member of the String class, can be used to compare two string values, where you may specify a String object as a parameter to test against, returning true if the text values of the two strings are equal and false if they are not.
String a = "hello"; String b = "hello"; if(a.equals(b) == true) System.out.println("The string values are equal");
Note | You may actually specify any object as an argument to the method equals, not just String objects, as all objects contain the method toString, which returns a String object representation of that object. We will look at this in Chapter 4 when we start creating our own classes/objects and can take a proper look at the method toString(). |
Note | As you can see in the previous example, we have added "== true" after the method call, but this is really not essential; we could equally have the following if statement. if(a.equals(b)) If we were checking if "a" was not equal to "b", we may have… if(a.equals(b) == false) In our shortened form, we can use the ! operator to create the following if statement, which would also check if the statement was false. if(!a.equals(b)) |
This if statement would return the value true, as both of the text values of strings a and b are equal. However, the method equals is case sensitive. If you want to ignore case sensitivity when testing if two strings are equal in value, you can use the method equalsIgnoreCase.
String a = "hELLo"; String b = "Hello"; if(a.equalsIgnoreCase(b) == true) System.out.println("Ignoring case, they are equal");
The equals methods are used to test if two string values are equal or not equal, with the return type being boolean, true or false. You may want to compare two string values lexicographically, testing if one string is greater than or less than the other. This can be seen as similar to an alphabetical test, but instead of comparing letters in the alphabet, the letters to compare are the Unicode values of the characters in each string, which is fine for alphabetical letters since their Unicode/ASCII values are sequentially ordered anyway.
The method compareTo returns an int value after comparing two string values lexicographically. The method returns 0 if the characters in the String object are equal to those in the argument parameter, a negative number if the characters in the String object are less than the string argument parameter, and a positive number if the characters in the String object are greater than the string argument parameter.
Similar to the method equals, the method compareTo is case sensitive. There is another method called compareToIgnoreCase that is not case sensitive. The following example, StringSorter.java, arranges a list of names into alphabetical order using the method compareTo to compare the string values, implementing a well-known sorting algorithm called bubble sort.
public class StringSorter { public static void main(String args[]) { String list[] = {"Glenn", "Andrew", "Jim", "Wes", "Brendan"}; String saveString; for(int i=0; i<list.length-1; i++) { for(int j=0; j<list.length-1-i; j++) { if(list[j].compareTo(list[j+1]) > 0) { saveString = list[j]; list[j] = list[j+1]; list[j+1] = saveString; } } } System.out.println("In Alphabetical Order..."); for(int i=0; i<list.length; i++) System.out.println(list[i]); } }
When you compile and run this code, you should get output displaying the list of names in alphabetical order, similar to the following screen shot.
Figure 3-8:
The bubble-sort algorithm is one of the simplest and therefore one of the slowest sorting algorithms. For future reference, the quick-sort algorithm is a much faster sorting algorithm, yet more difficult to implement.
The simplest data to retrieve from a string value is a single character at a specified location or index in the string. The following code will run through the string str, printing each character individually, one per line.
String str = "Super String"; for(int i=0; i<str.length(); i++) System.out.print(str.charAt(i));
This code introduces us to two new methods. The first is the method length, which simply returns the number of characters in the string. The second method is charAt, which takes an index parameter of type int and returns the char value of the character in the string at the index position specified.
You can also retrieve a sub-string of a string using the method substring. The method has two forms, one taking the beginning index as a parameter of type int and the other taking two parameters: the beginning and end indices, both of type int. Both methods do not change the current string to which they belong, as string values cannot be changed, but they return a newly created String object.
String str = "This is interesting"; String sub = str.substring(8); // sub value is "interesting"; sub = str.substring(8,11); // sub value is "int";
You may want to search an array for characters and sub-strings. The method indexOf can be used to check if a sub-string exists inside of a string value at a given index position. For example, you would say that the sub-string "lo Wor" exists in the string "Hello World" at index position 3 in the source string. This is because the character l is at index 3 in the source string just as the first character H is at index 0 in the source string. The code to check for this sub-string is as follows:
String str = "Hello World"; String sub = "lo Wor"; int returnValue = str.indexOf(sub); if(returnValue != -1) System.out.println("sub-string found at index " + returnValue); else System.out.println("sub-string not found");
The method indexOf returns an int value that is the index position in the string where the sub-string closest to the start of the string is found. If no sub-string is found, the method returns the value -1. It is possible that you may want to find the index position of further sub-strings inside a string. For example, the string "she sells sea shells on the sea shore" contains two instances of the sub-string "she." Another method called indexOf takes two parameters; the first is again the sub-string to test, and the second is the index position to begin searching from. Therefore, we can test for many instances of a sub-string in a string, as follows:
String str = "she sells sea shells on the sea shore"; String sub = "she"; int index = 0; do { index = str.indexOf(sub, index); if(index !=-1) { System.out.println("sub-string found at index " + index); index++; } } while(index !=-1);
In the do while loop, the value of the variable index is assigned the return value from the method indexOf. This method is passed the sub-string value she to search for and also the current value of index, which is the index position to start searching from. Each time we find a sub-string, the value of index is incremented by 1. This is because we don't want to find the same sub-string over and over again; we want to search from the position in the string after the last position where a sub-string was found.
The following example, LetterCounter.java, checks every letter in a string, calculates how many of each letter exists in the string, and prints the amounts to the console screen.
public class LetterCounter { public static void main(String args[]) { String str = "making games requires knowledge of boring things too"; int index; int totalChars; System.out.println(str + "\n"); for(int i=(int)'a'; i<(int)'z'+1; i++) { index = 0; totalChars = 0; do { index = str.indexOf((char)i, index); if(index !=-1) { totalChars++; index++; } } while(index != -1); if(totalChars != 0) System.out.println(totalChars + " letter " + (char)i + "'s found"); } } }
When running this code, you should get output similar to the following screen shot.
Figure 3-9:
Here we use another alternative to the method indexOf, where the first parameter is a char value instead of a String sub-string value. There is also a method called lastIndexOf that will find the last instance of a sub-string or character inside a given string. It has all of the parameter variations of the method indexOf. The difference between the methods indexOf and lastIndexOf is that lastIndexOf searches from the end of the string to the beginning, whereas indexOf searches from beginning to end. Instead of specifying a second parameter as the start index to begin searching from, specify the end index to begin searching from. For example, finding the index of the last o in the string "Hello World," you would use the following code.
String str = "Hello World"; int lastIndex = str.lastIndexOf('o');
To find the index position of the second to last o in the string "Hello World," which is also the first, you would add the following code:
int nextLastIndex = str.lastIndexOf('o', lastIndex - 1);
This search will find the next o character from the index position where the last o character was found, less one, searching from the letter W to the beginning of the string.
There are several useful methods that can be used to create new string objects that are modified versions of the original string in some way. The methods toLowerCase and toUpperCase will return newly created String objects containing text with characters all in lowercase and uppercase, respectively.
String str = "Hello World"; String lowerCase = str.toLowerCase(); String upperCase = str.toUpperCase();
The method toLowerCase does not change the characters in the String object that str references to all lowercase characters, but returns a new String object containing this value. If you wanted str to reference a String object that was a version of itself but with all its characters changed to lowercase, you could implement the code as follows.
String str = "Hello World"; str = str.toLowerCase();
The methods indexOf and lastIndexOf are case sensitive when searching for characters and sub-strings of a string. This is where the methods toLowerCase and toUpperCase come in handy. If you want to ignore the case of characters, it is often useful to create versions of the source string and test strings that are all of equal case, either all lowercase or all uppercase. You can then perform the search without worrying about case sensitivity, as you have (maybe just temporarily) fixed all characters to the same case anyway.
Another useful method is trim. This method will simply remove any spaces from the start and end of a string.
String str = " Hello World "; str = str.trim(); // str now equals "Hello World";
Again, this method does not change the String object it belongs to but returns a new String object with the changes.
The method valueOf is used to convert a data value into its String representation. This method is overloaded to accept all of the data types, namely values of primitive data types. All of the primitive data types can be passed as parameters to the method valueOf in its various overloaded forms.
int number = 1234567; String str = String.valueOf(number);
This code creates a new String object with the value 1234567 converting the numeric value into a string value where the numbers in the string are now represented as characters. Furthermore, the method valueOf, which takes a parameter of type int, is static and can therefore be accessed without a String object being created, using the name of the class to access it: String.valueOf. Here are a few examples of the overloaded method valueOf accepting different data types.
char character = '&'; String str = String.valueOf(character); double Pi = 3.141592653589793; str = String.valueOf(Pi); boolean isCorrect = true; str = String.valueOf(isCorrect); // str equals "true" String empty = null; str = String.valueOf(empty); // str equals "null"
There is also a valueOf method that takes an array of characters as a parameter and returns the String object representation of the characters.
char[] characters = {'S', 'e', 't', ' ', 't', 'o', ' ', 's', 't', 'r', 'i', 'n', 'g'}; String str = String.valueOf(characters);
Converting from strings to primitive data types (for example, converting a string representation of a number to an actual number stored in, say, a variable of type int) is discussed in Chapter 5.
The method replace is another useful method that replaces all of a specified character with a new character, returning a new String object with the desired changes.
String str = "thi% do&% mak& %&n%& r&ally"; str = str.replace('%', 's'); str = str.replace('&', 'e'); // str equals "this does make sense really"
This code simply replaces all instances of the character % with the character s and all instances of the character & with the character e, with each call to the method replace returning a newly created String object.
|
|