410 likes | 557 Views
The StringBuffer Class . StringBuffer stringBuf = new StringBuffer(); stringBuf.append("abc"); // stringBuf now contains "abc" stringBuf.append(123); // stringBuf now contains "abc123" stringBuf = new StringBuffer("TH8"); stringBuf.insert(2, "X");
E N D
The StringBuffer Class StringBuffer stringBuf = new StringBuffer(); stringBuf.append("abc"); // stringBuf now contains "abc" stringBuf.append(123); // stringBuf now contains "abc123" stringBuf = new StringBuffer("TH8"); stringBuf.insert(2, "X"); // stringBuf now contains "THX8" stringBuf.insert(3, 113); // stringBuf now contains "THX1138" char ch = stringBuf.charAt(2); // ch is ‘X’ stringBuf.setCharAt(2, 'a'); // stringBuf now contains "THa1138“
13.7 The StringBuffer Class • String objects are immutable: once a String object has been created, the characters in it can never be changed. • A StringBuffer object (or string buffer) is similar to a String object, except that its characters can be changed.
Buffers • In the computing field, a buffer is a place where data is stored temporarily, usually on its way from one place to another. • A string buffer is a temporary place to store a string as it’s being changed. • Changing a String object requires three steps: • Converting it to a string buffer. • Changing the characters in the string buffer. • Converting the buffer back to a String object.
Properties of String Buffers • A string buffer behaves like a vector of characters. • Each string buffer has a capacity—the maximum number of characters it can store. • If an operation on the buffer causes the capacity to be exceeded, the capacity is increased automatically. • The StringBuffer class belongs to the java.lang package.
Creating a String Buffer • Examples of using StringBuffer constructors: StringBuffer stringBuf1 = new StringBuffer(); StringBuffer stringBuf2 = new StringBuffer(100); StringBuffer stringBuf3 = new StringBuffer("antidisestablishmentarianism"); • strBuf1 will have a capacity of 16 characters. • The capacity of strBuf2 will be 100, and the capacity of strBuf3 will be 28 + 16 = 44. • strBuf1 and strBuf2 are currently empty. • strBuf3 contains antidisestablishmentarianism.
Operations on String Buffers • Primary operations on a string buffer: • Appending: Adding characters to the end of the string that’s currently stored in the string buffer. • Inserting: Moving some of the characters already in the string and then putting additional characters in the middle of the string. • Both operations will automatically increase the capacity of the buffer if necessary.
Appending to a String Buffer • Appending is done by calling the append method. • There are 10 different versions of append, but they’re all similar. • Almost any kind of data can be appended, including a string, a value of a primitive type, or an object: StringBuffer stringBuf = new StringBuffer(); stringBuf.append("abc"); // stringBuf now contains "abc" stringBuf.append(123); // stringBuf now contains "abc123" • If the data to be appended isn’t a string, append will automatically convert it to string form.
Appending to a String Buffer • The append method returns the string buffer on which the operation was performed. • This property makes it possible to chain together a series of append calls: stringBuf.append("abc").append(123);
Appending to a String Buffer • The + operator is actually a shorthand notation for the append method. • The statement str = str1 + str2 + str3; is equivalent to StringBuffer stringBuf = new StringBuffer(); stringBuf.append(str1).append(str2).append(str3); str = stringBuf.toString();
The toString Method • The toString method can be used to convert a string buffer back to ordinary string form. • To print the contents of a string buffer, it’s not necessary to call toString explicitly; the System.out.print and System.out.println methods will automatically call toString.
Inserting into a String Buffer • The insert methods that StringBuffer provides are similar to the append methods. • Most versions of insert require two arguments: • An “offset” in the string buffer • The data item to be inserted • After the insertion, the first character of this item will occupy the specified offset: StringBuffer stringBuf = new StringBuffer("TH8"); stringBuf.insert(2, "X"); // stringBuf now contains "THX8" stringBuf.insert(3, 113); // stringBuf now contains "THX1138"
Inserting into a String Buffer • Any kind of data can be inserted into a string buffer, including values of primitive types as well as objects. • insert returns the string buffer on which the operation was performed, which allows chaining: stringBuf.insert(2, "X").insert(3, 113); • insert throws StringIndexOutOfBoundsException if the offset is less than 0 or greater than the length of the string stored in the string buffer.
Inserting into a String Buffer • Inserting at the end of a string is legal: StringBuffer stringBuf = new StringBuffer("abc"); stringBuf.insert(3, "d"); // stringBuf now contains "abcd"
Other String Buffer Operations • The other major operations on a string buffer are accessing a character and changing a character. • The charAt method returns the character at a specified position in a string buffer: char ch = stringBuf.charAt(2); • The setCharAt method stores a character into a string buffer at a specified position: stringBuf.setCharAt(2, 'a');
Length and Capacity of a String Buffer • Other StringBuffer methods are related to the length and capacity of a string buffer. • The capacity method returns the current capacity of a string buffer: int capacity = stringBuf.capacity(); • The ensureCapacity method increases the capacity of a string buffer, if necessary, to a specified value: stringBuf.ensureCapacity(100); • If the buffer’s current capacity is greater than or equal to the desired capacity, the method does nothing.
Length and Capacity of a String Buffer • The length method returns the current length of the string stored in a string buffer: int length = stringBuf.length(); • The setLength method changes the length of a string buffer: stringBuf.setLength(10); • If the length of the string that’s currently stored in the buffer is larger than the specified value, characters are removed from the end of the string. • If the string’s length is smaller than the specified value, null characters are added to the end.
Program: Sorting theCharacters in a String • The SortCharacters program will prompt the user to enter a string of characters and then print the sorted version of those characters: Enter a string: folderol Sorted version of string: deflloor • The input will be stored in a string that can’t be changed directly, so a string buffer will be needed. • The program will fetch characters one by one from the original string and insert them into the string buffer, using the algorithm from the SortLines program.
SortCharacters.java // Sorts the characters in a string import jpb.*; public class SortCharacters { public static void main(String[] args) { // Prompt user to enter a string SimpleIO.prompt("Enter a string: "); String userInput = SimpleIO.readLine(); // Create a string buffer to hold the sorted string StringBuffer stringBuf = new StringBuffer();
// Insert characters from the user's input into the // string buffer, keeping the characters in the buffer // sorted at all times for (int i = 0; i < userInput.length(); i++) { char ch = userInput.charAt(i); int j; for (j = 0; j < stringBuf.length(); j++) if (ch < stringBuf.charAt(j)) break; stringBuf.insert(j, ch); } // Display contents of string buffer System.out.println("Sorted version of string: " + stringBuf); } }
13.8 Case Study: Finding Anagrams • Sorting can be used to solve a surprising number of problems, including the problem of finding anagrams in a list of words. • An anagram of a word is a permutation of the letters in that word; for example, stop is an anagram of tops.
Program Behavior • The FindAnagrams program will prompt the user to enter a series of words and then determine which words in the list are anagrams of each other. • The program will repeatedly prompt the user to enter words; input stops when the user presses the Enter key without entering a word. • The program will then display the words, with anagrams grouped together on the same line.
Program Behavior • An example: Enter a word: pans Enter a word: pots Enter a word: opt Enter a word: snap Enter a word: stop Enter a word: tops Enter a word: Anagrams: --------- 1. pans snap 2. pots stop tops 3. opt
Program Behavior • The FindAnagrams program will ignore punctuation in a word (it’s is an anagram of sit) • The program will also ignore the case of letters in a word (Pots,STOP, and tops are anagrams).
Signatures • The secret to writing the FindAnagrams program is use sorting. • To test whether two words are anagrams, the program can compute the “signature” of each word by sorting its letters, and check whether the signatures are equal. • For example, the signature of pans is anps, and the signature of snap is also anps.
Signatures • A table of words and their signatures: Word Signature pans anps pots opst opt opt snap anps stop opst tops opst • Uppercase letters are converted to lowercase before the signature is computed. • Punctuation marks are ignored.
Signatures • To determine which words are anagrams, the lines in the table can be sorted by their signatures: Word Signature pans anps snap anps pots opst stop opst tops opst opt opt
Signatures • The last step is to make a pass over the table from top to bottom. • Words that have the same signature are anagrams, so they will be printed on the same line: pans snap pots stop tops opt
Design of the FindAnagrams Program • The FindAnagrams program will store the words and their signatures in parallel vectors named words and signatures. • An alternative would be to define a new class whose instances contain both a word and its signature, and then store those objects in a single vector.
Design of the FindAnagrams Program • The program can be divided into two steps: 1. Read words from the user, storing the words into the words vector and the signatures of the words into the signatures vector. 2. Print the words in the words vector, putting words that are anagrams of each other on the same line. • These steps will be performed by class methods named readWords and printAnagrams.
Design of the readWords Method • Pseudocode for readWords: while (true) { Prompt the user to enter a word; return if the word is empty; Compute the signature of the word; Determine where the signature belongs in the signatures vector; Insert the signature into the signatures vector; Insert the word at the corresponding location in the words vector; }
Design of the printAnagrams Method • Pseudocode for printAnagrams: Return if the signatures vector is empty; Print a heading, followed by the first word in the words vector; Print the remaining words in the words vector, placing words on the same line if they have the same signature;
Design of the computeSignature Method • Pseudocode for computeSignature, a helper method that computes the signature of a word: Create a new string buffer; for (int i = 0; i < word.length(); i++) { Extract the character at position i in word; If the character is not a letter, ignore it; otherwise, convert it to lowercase; Insert the character into the string buffer, keeping the characters in the buffer sorted at all times; } Convert the string buffer into a string and return it;
FindAnagrams.java // Program name: FindAnagrams // Author: K. N. King // Written: 1998-08-19 // // Prompts the user to enter a series of words. When the // user presses the Enter key without entering a word, the // program will then display the original words, with // anagrams displayed on the same line. // // When determining whether two words are anagrams, the // program will ignore punctuation and the case of the // letters in the words. // // To find anagrams, the program computes a "signature" for // each word, consisting of the letters in the word after // they have been sorted. The words and their signatures are // stored in parallel vectors, sorted by signature. After // all words have been read, anagrams are located by // looking for identical signatures. Because the signatures // are sorted, identical signatures must be adjacent in the // signatures vector.
import java.util.*; import jpb.*; public class FindAnagrams { private static Vector words = new Vector(); private static Vector signatures = new Vector(); public static void main(String[] args) { readWords(); printAnagrams(); }
/////////////////////////////////////////////////////////// // NAME: readWords // BEHAVIOR: Repeatedly prompts the user to enter words, // stopping when the user enters an empty // word. Computes the signature of each word, // storing the signature in the signatures // vector in such a way that the vector is // always sorted in ascending order. Stores // each word in the words vector at the same // position as the signature in the // signatures vector. // PARAMETERS: None // RETURNS: Nothing /////////////////////////////////////////////////////////// private static void readWords() { while (true) { // Prompt the user to enter a word; return if the word // is empty SimpleIO.prompt("Enter a word: "); String word = SimpleIO.readLine().trim(); if (word.length() == 0) return;
// Compute the signature of the word String signature = computeSignature(word); // Determine where the signature belongs in the // signatures vector int i; for (i = 0; i < signatures.size(); i++) { String signatureInVector = (String) signatures.elementAt(i); if (signature.compareTo(signatureInVector) < 0) break; } // Insert the signature into the signatures vector. // Insert the word at the corresponding location in the // words vector. signatures.insertElementAt(signature, i); words.insertElementAt(word, i); } }
/////////////////////////////////////////////////////////// // NAME: printAnagrams // BEHAVIOR: Prints the contents of the words vector, // putting words that are anagrams of each // other on the same line. Uses the signatures // vector to determine which words are // anagrams. Assumes that the i-th element of // the signatures vector is the signature of // the i-th word in the words vector. Also // assumes that the elements of the signatures // vector are in sorted order. // PARAMETERS: None // RETURNS: Nothing /////////////////////////////////////////////////////////// private static void printAnagrams() { int anagramNumber = 1; int signatureCount = signatures.size();
// Return if the signatures vector is empty if (signatureCount == 0) return; // Print a heading, followed by the first word in the // words vector System.out.println("\nAnagrams:\n---------"); System.out.print("1. " + words.firstElement()); // Print the remaining words in the words vector, placing // words on the same line if they have the same signature for (int i = 1; i < signatureCount; i++) { if (signatures.elementAt(i).equals (signatures.elementAt(i-1))) System.out.print(" "); else System.out.print("\n" + ++anagramNumber + ". "); System.out.print(words.elementAt(i)); } System.out.println(); }
/////////////////////////////////////////////////////////// // NAME: computeSignature // BEHAVIOR: Computes the signature of a word by sorting // the letters in the word. Characters other // than letters are ignored, and uppercase // letters are converted to lowercase. // PARAMETERS: word - the word whose signature is to be // computed // RETURNS: String object containing the same letters // as the original word, but in sorted order /////////////////////////////////////////////////////////// private static String computeSignature(String word) { // Create a new string buffer StringBuffer stringBuf = new StringBuffer(word.length());
for (int i = 0; i < word.length(); i++) { // Extract the character at position i in word. // If the character is not a letter, ignore it; // otherwise, convert it to lowercase. char ch = word.charAt(i); if (!Character.isLetter(ch)) continue; ch = Character.toLowerCase(ch); // Insert the character into the string buffer, keeping // the characters in the buffer sorted at all times int j; for (j = 0; j < stringBuf.length(); j++) if (ch < stringBuf.charAt(j)) break; stringBuf.insert(j, ch); } // Convert the string buffer into a string and return it return stringBuf.toString(); } }