Computer Science Notes Chapter 9 Page 1 of 23 Chapter 9: Strings and Text I/O These notes are meant to accompany Introduction to Java Programming: Brief Version, eighth edition by Y. Daniel Lang. Programming Skills in a Nutshell: At the end of this chapter you should have the following programming skills: 1. To use more methods from the String class. 2. To open a file for either reading or writing using the Scanner and PrintWriter classes, respectively. 3. To read or write data to file using the println() and next() methods of the Scanner and PrintWriter classes, respectively. 4. To close a file once you are done with it. package encryption; import java.io.File; import java.io.PrintWriter; import java.util.Scanner; /** * The EncryptionTool class contains methods for encrypting and decrypting * text files using a simple rotation (Caesar cipher) technique. * @author Kevin Mirus */ public class EncryptionTool { /** * Encrypts a given File by rotating characters by a given key value. * The encrypted file will have the source file's name with an extension of .rot * @param key the key value * @param sourceFile the File that will be encrypted */ public static void rotationEncrypt(int key, File sourceFile) throws Exception { //Create a Scanner object to read in from the sourceFile. Scanner diskInput = new Scanner(sourceFile); //Create a target File for output. File targetFile = new File (sourceFile.getAbsolutePath() + ".rot"); //Create a PrintWriter object to do the writing to targetFile. PrintWriter diskOutput = new PrintWriter(targetFile); //Process every line in the input file. while (diskInput.hasNextLine()) { //Read in the next line of text. String inputLine = diskInput.nextLine(); //Create a String to store the encrypted line of text. String outputLine = ""; //Loop through every character of the inputLine and encrypt it using rotation. for (int i = 0; i < inputLine.length(); i++) { char nextChar = rotateCharacter( inputLine.charAt(i), key); outputLine += nextChar; } Computer Science Notes Chapter 9 Page 2 of 23 //Write the encrypted line of text to the output file. diskOutput.println(outputLine); } //Close both input and output files. diskInput.close(); diskOutput.close(); }//end method rotationEncrypt(key, File) /** * Decrypts a given File by "un-"rotating characters by a given key value. * It is expected that the encrypted file has an extension of .rot; * the decrypted file's name will be the encrypted file's name less the extension .rot * @param key the key value that was used to encrypt the file * @param sourceFile the File that will be decrypted */ public static void rotationDecrypt(int key, File sourceFile) throws Exception { //Create a Scanner object to read in from the sourceFile. Scanner diskInput = new Scanner(sourceFile); //Create a target File for output. File targetFile = new File (sourceFile.getAbsolutePath().substring(0, sourceFile.getAbsolutePath().length()-4)); //Create a PrintWriter object to do the writing to targetFile. PrintWriter diskOutput = new PrintWriter(targetFile); //Process every line in the input file. while (diskInput.hasNextLine()) { //Read in the next line of text. String inputLine = diskInput .nextLine(); //Create a String to store the decrypted line of text. String outputLine = ""; //Loop through every character of the inputLine and encrypt it using rotation. for (int i = 0; i < inputLine.length(); i++) { char nextChar = rotateCharacter( inputLine.charAt(i), -key); outputLine += nextChar; } //Write the encrypted line of text to the output file. diskOutput.println(outputLine); } //Close both input and output files. diskInput.close(); diskOutput.close(); }//end method rotationDecrypt(int, File) /** * "Deciphers" a given File that was encrypted using an unknown rotation key * by reading up to the first five lines of the encrypted file, then applying * all possible rotation keys to that file. The results are returned as a Computer Science Notes Chapter 9 Page 3 of 23 * two-dimensional String array for the user to peruse and decide upon the proper * rotation key. * It is expected that the encrypted file has an extension of .rot. * @param sourceFile the File that will be deciphered */ public static String[][] rotationDecipher(File sourceFile) throws Exception { String[][] possibleSolutions = new String[26][5]; //Create a Scanner object to read in from the sourceFile. Scanner diskInput = new Scanner(sourceFile); //Process up to the first five lines in the input file. int lineIndex = 0; while (diskInput.hasNextLine() && lineIndex < possibleSolutions[0].length) { //Read in the next line of text. String inputLine = diskInput.nextLine(); //Loop through a decryption of that line for every possible key. for (int key = 0; key < possibleSolutions.length; key++) { possibleSolutions[key][lineIndex] = ""; //Loop through every character of the inputLine and encrypt it using rotation. for (int i = 0; i < inputLine.length(); i++) { char nextChar = rotateCharacter( inputLine.charAt(i), key); possibleSolutions[key][lineIndex] += nextChar; } } lineIndex++; } //Close the input file. diskInput.close(); return possibleSolutions; }//end method rotationDecipher(File) /** * "Rotates" a given character to its encrypted form by shifting it * by a given shift amount. Letters are shifted; non-letters are not. * @param ch is the character to encrypt * @param shift is the amount to shift it by * @return the encrypted character */ public static char rotateCharacter(char ch, int shift) { if (Character.isLetter(ch)) { int offset = Character.isUpperCase(ch) ? (int)'A' : (int) 'a'; int c = (int) ch - offset; c = (c + shift) % 26; c = c < 0 ? c + 26: c; c = offset + c; Computer Science Notes Chapter 9 Page 4 of 23 ch = (char) c; } return ch; }//end method rotateCharacter(char, int) /** * Generates a String form of the text in a given File. * Each line of the printed String will have 80 characters or less. * @param sourceFile is the given File for which a String of its contents is desired. * @return a String containing the contents of sourceFile * @throws Exception */ public static String getFileAsString(File sourceFile) throws Exception { String answer = ""; //Create a Scanner object to read in from the sourceFile. Scanner diskInput = new Scanner(sourceFile); //Process every line in the input file. while (diskInput.hasNextLine()) { //Read in the next line of text. String inputLine = diskInput.nextLine(); //If there is a blank line, then insert new lines and skip the next part. if (inputLine.length() == 0) { answer += "\n\n"; continue; } //Split the string into subpieces at the spaces, and insert a new line such that //any line of the string, when printed, is never longer than 80 characters. String[] tokens = inputLine.split(" ", 0); int lineLength = 0; for (int j = 0; j < tokens.length; j++) { if (lineLength + tokens[j].length() > 79) { answer += "\n"; lineLength = 0; } answer += tokens[j] + " "; lineLength += tokens[j].length() + 1; } } //Close the input file. diskInput.close(); return answer; }//end method getFileAsString(File) }//end of class EncryptionTool Computer Science Notes Chapter 9 Page 5 of 23 package encryption; import import import import java.io.File; java.util.Scanner; javax.swing.JOptionPane; javax.swing.JFileChooser; /** The EncryptionToolUserInterface class implements an application that uses the * EncryptionTool class to encrypt and decrypt text files. * @author Kevin Mirus * */ public class EncryptionToolUserInterface { /** Prompts the user for encryption or decryption, the key, and the file. * @param argv is not used. */ public static void main(String[] argv) throws Exception { //Tell the user what the program does JOptionPane.showMessageDialog(null, "This program will encrypt or decrypt text files using a rotation cipher.", "Program Description", JOptionPane.INFORMATION_MESSAGE); Scanner input = new Scanner(System.in); File encryptFile = new File("junk.txt"); File decryptFile = new File("junk.txt"); File decipherFile = new File("junk.txt"); JFileChooser textFileChooser = new JFileChooser(); int menuChoice = 1; final int ENCRYPT = 0; final int DECRYPT = 1; final int DECIPHER = 2; final int VIEW = 3; final int EXIT_PROGRAM = 4; String[] menuChoices = new String[5]; menuChoices[ENCRYPT] = "Encrypt an existing file."; menuChoices[DECRYPT] = "Decrypt an existing file."; menuChoices[DECIPHER] = "Decipher an existing file for which you don't know the key."; menuChoices[VIEW] = "View the contents of a file."; menuChoices[EXIT_PROGRAM] = "Exit program."; String menu = ""; for (int i = 0; i < menuChoices.length; i++) menu += i + ") " + menuChoices[i] + "\n"; String filename = ""; int key = 13; do { String menuChoiceString = JOptionPane.showInputDialog(menu); if (menuChoiceString != null) menuChoice = Integer.parseInt(menuChoiceString); else menuChoice = EXIT_PROGRAM; switch (menuChoice) { Computer Science Notes Chapter 9 Page 6 of 23 case ENCRYPT: //encrypt an existing file JOptionPane.showMessageDialog(null, "Time to choose a file to encrypt.", "About to Encrypt a File", JOptionPane.INFORMATION_MESSAGE); //Get a valid file using the GUI JFileChooser class if (textFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { // Get the selected file encryptFile = textFileChooser.getSelectedFile(); } if (encryptFile.exists()) { filename = encryptFile.getAbsolutePath(); JOptionPane.showMessageDialog(null, "You chose to encrypt file\n" + filename, "Encryption File Name", JOptionPane.INFORMATION_MESSAGE); key = Integer.parseInt( JOptionPane.showInputDialog("Enter the rotation key.") ); //Do the encryption EncryptionTool.rotationEncrypt(key, encryptFile); JOptionPane.showMessageDialog(null, encryptFile.getName() + " was successfully encrypted.", "Encryption Success!", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(null, "No file was chosen for encryption.", "Encryption Aborted", JOptionPane.INFORMATION_MESSAGE); } break; case DECRYPT: //decrypt an existing file JOptionPane.showMessageDialog(null, "Time to choose a file to decrypt.", "About to Decrypt a File", JOptionPane.INFORMATION_MESSAGE); //Get a valid file using the GUI JFileChooser class if (textFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { // Get the selected file decryptFile = textFileChooser.getSelectedFile(); } if (decryptFile.exists()) { filename = decryptFile.getAbsolutePath(); JOptionPane.showMessageDialog(null, "You chose to decrypt file\n" + filename, Computer Science Notes Chapter 9 Page 7 of 23 "Decryption File Name", JOptionPane.INFORMATION_MESSAGE); key = Integer.parseInt( JOptionPane.showInputDialog("Enter the rotation key.") ); //Do the decryption EncryptionTool.rotationDecrypt(key, decryptFile); JOptionPane.showMessageDialog(null, encryptFile.getName() + " was successfully decrypted.", "Dencryption Success!", JOptionPane.INFORMATION_MESSAGE); } else { JOptionPane.showMessageDialog(null, "No file was chosen for decryption.", "Decryption Aborted", JOptionPane.INFORMATION_MESSAGE); } break; case DECIPHER: //decipher an existing file of unknown key JOptionPane.showMessageDialog(null, "Time to choose a file to decipher.", "About to Decipher a File", JOptionPane.INFORMATION_MESSAGE); //Get a valid file using the GUI JFileChooser class if (textFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { // Get the selected file decipherFile = textFileChooser.getSelectedFile(); } if (decipherFile.exists()) { filename = decipherFile.getAbsolutePath(); JOptionPane.showMessageDialog(null, "You chose to decipher file\n" + filename, "Decipher File Name", JOptionPane.INFORMATION_MESSAGE); //Do the encryption String[][] solutions = EncryptionTool.rotationDecipher(decipherFile); String message = ""; for (key = 0; key < solutions.length; key++) { message = ""; for(int lineNumber = 0; lineNumber < solutions[0].length; lineNumber++) message += solutions[key][lineNumber].substring(0, Math.min(80, solutions[key][lineNumber].length())) + "\n"; int quitListingSolutions = JOptionPane.showConfirmDialog(null, message, "Decryption Using key = " + key, JOptionPane.OK_CANCEL_OPTION); if( quitListingSolutions == JOptionPane.CANCEL_OPTION) break; Computer Science Notes Chapter 9 Page 8 of 23 } } else { JOptionPane.showMessageDialog(null, "No file was chosen for decipherment.", "Decipher Aborted", JOptionPane.INFORMATION_MESSAGE); } break; case VIEW: //view the contents of a file JOptionPane.showMessageDialog(null, "Time to choose a file to view.", "About to View a File", JOptionPane.INFORMATION_MESSAGE); //Get a valid file using the GUI JFileChooser class if (textFileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { // Get the selected file encryptFile = textFileChooser.getSelectedFile(); } if (encryptFile.exists()) { filename = encryptFile.getAbsolutePath(); //Display the contents of the file in a message dialog box JOptionPane.showMessageDialog(null, EncryptionTool.getFileAsString(encryptFile), "Contents of " + filename, JOptionPane.PLAIN_MESSAGE); } else { JOptionPane.showMessageDialog(null, "No file was chosen for viewing.", "Nothing to show!", JOptionPane.ERROR_MESSAGE); } break; case EXIT_PROGRAM: //Exit program break; default: JOptionPane.showMessageDialog(null, "That was not a valid menu choice.", "Invalid Menu Choice", JOptionPane.ERROR_MESSAGE); } } while(menuChoice != EXIT_PROGRAM); JOptionPane.showMessageDialog(null, "Encryption program will now terminate.", "Program Ending", JOptionPane.INFORMATION_MESSAGE); }//end method main() Computer Science Notes Chapter 9 Page 9 of 23 }//end class EncryptionToolUserInterface Book’s Statement of Skills: 1. To use the String class to process fixed strings. (9.2) 2. To use the Character class to process a single character. (9.3) 3. To use the StringBuilder and StringBuffer classes to process flexible strings. (9.4) 4. To distinguish between the String, StringBuilder, and StringBuffer classes. (9.2 – 9.4) 5. To learn how to pass strings to the main method from the command line. (9.5) 6. To discover file properties and to delete and rename files using the File class. (9.6) 7. To write data to a file using the PrintWriter class. (9.7.1) 8. To read data from a file using the Scanner class. (9.7.2) 9. (Optional GUI) To open files using a dialog box. (9.8) Section 9.1: Introduction A string is a sequence of characters. In Java, a string is an object. The String, StringBuilder, and StringBuffer classes are used for storing and processing strings. The String class is immutable; the StringBuilder and StringBuffer classes are not. This chapter also illustrates how to process command-line arguments to the main method (which is an application of processing a String array), and how to perform simple text output and input using the Scanner and PrintWriter classes (respectively) Section 9.2: The String Class The java.lang.String class models a sequence of characters as a string. The String class has 13 constructors and 53 methods… See http://download.oracle.com/javase/6/docs/api/java/lang/String.html Some common String operations are: Isolating individual characters Comparing Strings Searching for and manipulating substrings Converting characters to upper case or lower case java.lang.String +CASE_INSENSITIVE_ORDER: Comparator +String() +String(bytes: byte[]) +String(bytes: byte[], charset: Charset ) The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class. Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. A Comparator that orders String objects as by compareToIgnoreCase. Constructs a default String. Constructs a new String by decoding the specified array of bytes using the platform's default charset. Constructs a new String by decoding the specified array of bytes using the specified charset. Computer Science Notes Chapter 9 +String(bytes: byte[], offset: int, length: int) +String(bytes: byte[], offset: int, length: int, charset: Charset) +String(bytes: byte[], offset: int, length: int, charsetName: String) +String(bytes: byte[], charsetName: String) +String(value: char[]) +String(value: char[], offset: int, count: int) +String(codePoints: int[], offset: int, count: int) +String(original: String) +String(buffer: StringBuffer) +String(builder: StringBuilder) +charAt(index: int): char +charAt(int index): char +codePointAt(int index): int codePointBefore(int index): int +codePointCount(int beginIndex, int endIndex): int +compareTo(String anotherString): int +compareToIgnoreCase(String str): int +concat(String str): String +contains(CharSequence s): boolean +contentEquals(CharSequence cs): boolean +contentEquals(StringBuffer sb): boolean +copyValueOf(char[] data): String +copyValueOf(char[] data, int offset, int count): String +endsWith(String suffix): boolean +equals(Object anObject): boolean +equalsIgnoreCase(String anotherString): boolean format(Locale l, String format, Object... args): String +format(String format, Object... args): String Page 10 of 23 Constructs a new String by decoding the specified subarray of bytes using the platform's default charset. Constructs a new String by decoding the specified subarray of bytes using the specified charset. Constructs a new String by decoding the specified subarray of bytes using the specified charset. Constructs a new String by decoding the specified array of bytes using the specified charset. Allocates a new String so that it represents the sequence of characters currently contained in the character array argument. Allocates a new String that contains characters from a subarray of the character array argument. Allocates a new String that contains characters from a subarray of the Unicode code point array argument. Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Allocates a new string that contains the sequence of characters currently contained in the string buffer argument. Allocates a new string that contains the sequence of characters currently contained in the string builder argument. Returns the char value at the specified index. Returns the char value at the specified index. Returns the character (Unicode code point) at the specified index. Returns the character (Unicode code point) before the specified index. Returns the number of Unicode code points in the specified text range of this String. Compares two strings lexicographically. Compares two strings lexicographically, ignoring case differences. Concatenates the specified string to the end of this string. Returns true if and only if this string contains the specified sequence of char values. Compares this string to the specified CharSequence. Compares this string to the specified StringBuffer Returns a String that represents the character sequence in the array specified. Returns a String that represents the character sequence in the array specified. Tests if this string ends with the specified suffix. Compares this string to the specified object. Compares this String to another String, ignoring case considerations. Returns a formatted string using the specified locale, format string, and arguments. Returns a formatted string using the specified format string and arguments. Computer Science Notes +getBytes():byte[] +getBytes(Charset charset): byte[] +getBytes(String charsetName): byte[] +getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): void +hashCode(): int +indexOf(int ch): int +indexOf(int ch, int fromIndex): int +indexOf(String str): int +indexOf(String str, int fromIndex): int +intern():String +isEmpty(): boolean +lastIndexOf(int ch): int +lastIndexOf(int ch, int fromIndex): int +lastIndexOf(String str): int +lastIndexOf(String str, int fromIndex): int +length():int +matches(String regex): boolean +offsetByCodePoints(int index, int codePointOffset): int +regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len): boolean +regionMatches(int offset, String other, int offset, int len): boolean +replace(char oldChar, char newChar): String +replace(CharSequence target, CharSequence replacement): String +replaceAll(String regex, String replacement): String +replaceFirst(String regex, String replacement): String +split(String regex): String[] Chapter 9 Page 11 of 23 Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array. Encodes this String into a sequence of bytes using the given charset, storing the result into a new byte array. Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array. Copies characters from this string into the destination character array. Returns a hash code for this string. Returns the index within this string of the first occurrence of the specified character. Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index. Returns the index within this string of the first occurrence of the specified substring. Returns the index within this string of the first occurrence of the specified substring, starting at the specified index. Returns a canonical representation for the string object. Returns true if, and only if, length() is 0. Returns the index within this string of the last occurrence of the specified character. Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index. Returns the index within this string of the rightmost occurrence of the specified substring. Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index. Returns the length of this string. Tells whether or not this string matches the given regular expression. Returns the index within this String that is offset from the given index by codePointOffset code points. Tests if two string regions are equal. Tests if two string regions are equal. Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar. Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence. Replaces each substring of this string that matches the given regular expression with the given replacement. Replaces the first substring of this string that matches the given regular expression with the given replacement. Splits this string around matches of the given regular expression. Computer Science Notes Chapter 9 +split(String regex, int limit): String[] +startsWith(String prefix): boolean +startsWith(String prefix, int toffset): boolean +subSequence(int beginIndex, int endIndex): CharSequence +substring(int beginIndex): String +substring(int beginIndex, int endIndex): String +toCharArray():char[] +toLowerCase():String +toLowerCase(Locale locale): String +toString():String +toUpperCase():String +toUpperCase(Locale locale): String +trim():String +valueOf(boolean b): String +valueOf(char c): String +valueOf(char[] data): String +valueOf(char[] data, int offset, int count): String +valueOf(double d): String +valueOf(float f): String +valueOf(int i): String +valueOf(long l): String +valueOf(Object obj): String Page 12 of 23 Splits this string around matches of the given regular expression. Tests if this string starts with the specified prefix. Tests if the substring of this string beginning at the specified index starts with the specified prefix. Returns a new character sequence that is a subsequence of this sequence. Returns a new string that is a substring of this string. Returns a new string that is a substring of this string. Converts this string to a new character array. Converts all of the characters in this String to lower case using the rules of the default locale. Converts all of the characters in this String to lower case using the rules of the given Locale. This object (which is already a string!) is itself returned. Converts all of the characters in this String to upper case using the rules of the default locale. Converts all of the characters in this String to upper case using the rules of the given Locale. Returns a copy of the string, with leading and trailing whitespace omitted. Returns the string representation of the boolean argument. Returns the string representation of the char argument. Returns the string representation of the char array argument. Returns the string representation of a specific subarray of the char array argument. Returns the string representation of the double argument. Returns the string representation of the float argument. Returns the string representation of the int argument. Returns the string representation of the long argument. Returns the string representation of the Object argument. Section 9.2.1: Constructing a String You can construct a new String object from a string literal: o Syntax: String newString = new String(stringLiteral); o Example: String newString = new String(My name is Kevin.); Since string literals are treated as String objects, you can also create a String as: o Example: String newString = My name is Kevin.; You can construct a new String object from an array of characters: o Example: char[] charArray = {H, e, l, l, o, ,, , D, o, o, f, u, s, }; String newString = new String(charArray); Section 9.2.2: Immutable Strings and Interned Strings A String object is immutable, meaning its contents can not be changed. For example, the following code does not change the value of any String object, but rather changes which String object the String variable s refers to: Computer Science Notes Chapter 9 Page 13 of 23 String s = Hello; s = Goodbye.; An interned string is a unique instance of a string literal with the same character sequence used by the JVM to reduce memory load when the same string literal is used more than once in a program. The intern() method of the String class returns an interned string. Section 9.2.3: String Comparisons Do not use the = = operator to determine if two strings have the same sequence of characters! Instead, use the equals() method of the String class to determine if two strings have the same sequence of characters. The compareTo() method of the String class is used to “lexigraphically” compare (i.e., by comparing ASCII values) whether one string comes before another one. The equalsIgnoreCase() method of the String class determines if two strings have the same sequence of characters, regardless of capitalization. The compareToIgnoreCase() method of the String class determines whether one string comes before another one, regardless of capitalization. The regionMatches() method of the String class determines if two strings have the same sequence of characters in a given region. The startsWith() method of the String class determines if a strings starts with a given string. The endsWith() method of the String class determines if a strings ends with a given string. //import java.lang.String; //Do not need above import because //all classes from the java.lang package are imported autoatically. /**The StringComparisons class implements an application that * performs various comparisons between strings. * @author Kevin Mirus */ public class StringComparisons { /**Shows how various strings compare under methods from teh String class. * @param argv is not used. */ public static void main(String[] argv) { //Declare first pair of strings to compare. String s1 = "Hello."; String s2 = "hello."; //Declare second pair of strings to compare. String s3 = "abc"; String s4 = "abg"; //Declare third pair of strings to compare. String s5 = "Kevin"; String s6 = "Kevin"; //Declare fourth pair of strings to compare. String s7 = "Goodbye."; String s8 = "Goodbye!"; //Tell the user what the program does. Computer Science Notes Chapter 9 Page 14 of 23 System.out.println("This program compares strings.\n"); System.out.println("String s1 = " + s1); System.out.println("String s2 = " + s2); System.out.println("Under the equals() method:"); if (s1.equals(s2)) System.out.println("s1 and s2 have THE SAME contents."); else System.out.println("s1 and s2 have DIFFERENT contents."); System.out.println("Under the equalsIgnoreCase() method:"); if (s1.equalsIgnoreCase(s2)) System.out.println("s1 and s2 have THE SAME contents (ignoring capitalization)."); else System.out.println("s1 and s2 have DIFFERENT contents (ignoring capitalization)."); System.out.println("\nString s3 = " + s3); System.out.println("String s4 = " + s4); System.out.println("Under the compareTo() method:"); System.out.println("s3.compareTo(s4) returns: " + s3.compareTo(s4)); System.out.println("s4.compareTo(s3) returns: " + s4.compareTo(s3)); System.out.println("s1.compareTo(s2) returns: " + s1.compareTo(s2)); System.out.println("s2.compareTo(s1) returns: " + s2.compareTo(s1)); System.out.println("String s5 = " + s5); System.out.println("String s6 = " + s6); System.out.println("s5.compareTo(s6) returns: " + s5.compareTo(s6)); System.out.println("String s7 = " + s7); System.out.println("String s8 = " + s8); System.out.println("s7.compareTo(s8) returns: " + s7.compareTo(s8)); System.out.println("\nUnder the compareToIgnoreCase() method:"); System.out.println("s3.compareToIgnoreCase(s4) returns: " + s3.compareToIgnoreCase(s4)); System.out.println("s4.compareToIgnoreCase(s3) returns: " + s4.compareToIgnoreCase(s3)); System.out.println("s1.compareToIgnoreCase(s2) returns: " + s1.compareToIgnoreCase(s2)); System.out.println("s2.compareToIgnoreCase(s1) returns: " + s2.compareToIgnoreCase(s1)); System.out.println("s5.compareToIgnoreCase(s6) returns: " + s5.compareToIgnoreCase(s6)); System.out.println("\nUnder the regionMatches() method:"); System.out.println("s1.regionMatches(1, s2, 1, 3) returns: " + s1.regionMatches(1, s2, 1, 3)); System.out.println("(because \"ell\" is the same thing as \"ell\")"); System.out.println("\nUnder the startsWith() method:"); System.out.println("s1.startsWith(\"Hell\") returns: " + s1.startsWith("Hell")); System.out.println("\nUnder the endsWith() method:"); System.out.println("s5.endsWith(\"vin\") returns: " + s5.endsWith("vin")); }//end main(String) }//end class StringComparisons Computer Science Notes Chapter 9 Page 15 of 23 This program compares strings. String s1 String s2 Under the s1 and s2 Under the s1 and s2 = Hello. = hello. equals() method: have DIFFERENT contents. equalsIgnoreCase() method: have THE SAME contents (ignoring capitalization). String s3 = abc String s4 = abg Under the compareTo() method: s3.compareTo(s4) returns: -4 s4.compareTo(s3) returns: 4 s1.compareTo(s2) returns: -32 s2.compareTo(s1) returns: 32 String s5 = Kevin String s6 = Kevin s5.compareTo(s6) returns: 0 String s7 = Goodbye. String s8 = Goodbye! s7.compareTo(s8) returns: 13 Under the compareToIgnoreCase() method: s3.compareToIgnoreCase(s4) returns: -4 s4.compareToIgnoreCase(s3) returns: 4 s1.compareToIgnoreCase(s2) returns: 0 s2.compareToIgnoreCase(s1) returns: 0 s5.compareToIgnoreCase(s6) returns: 0 Under the regionMatches() method: s1.regionMatches(1, s2, 1, 3) returns: true (because "ell" is the same thing as "ell") Under the startsWith() method: s1.startsWith("Hell") returns: true Under the endsWith() method: s5.endsWith("vin") returns: true Section 9.2.4: String Length, Characters, and Combining Strings The length() method of the String class returns the number of characters in the string. The charAt(index) method of the String class returns the character at position index, where 0 index length() – 1. The charAt() method is an indication of the fact that a string is represented internally as a private array of characters. To get a single character for input from the keyboard, you can use keyboard.next().charAt(0) You can use the + operator to concatenate strings… Example: String s1 = Hello, ; String s2 = Doofus. ; String s3 = s1 + s2; Computer Science Notes Chapter 9 Page 16 of 23 You also can use the concat() method of the String class to concatenate strings… Example: String s1 = Hello, ; String s2 = Doofus. ; String s3 = s1.concat(s2); Section 8.2.5: Obtaining Substrings The method substring(int beginIndex, int endIndex) of the String class returns a new string that starts with the character at index beginIndex and ends at the character at index endIndex. The method substring(int beginIndex) of the String class returns a new string that starts with the character at index beginIndex and goes to the end of the string. Section 8.2.7: Converting, Replacing, and Splitting Strings The method toLowerCase() of the String class returns a new string with all alphabetic characters converted to lower case. The method toUpperCase() of the String class returns a new string with all alphabetic characters converted to upper case. The method trim() of the String class returns a new string with all leading and trailing whitespace trimmed away. The method replace(char oldChar, char newChar) of the String class returns a new string with all occurrences of oldChar replaced with newChar. The method replaceFirst(String regex, String newString) of the String class returns a new string with the first occurrences of the regular expression regex replaced with newString. The method replaceAll(String regex, String newString) of the String class returns a new string with every occurrence of the regular expression regex replaced with newString. The method split(String regex, int limit) of the String class returns an array of Strings where each string in the array is obtained by splitting the original string around matches of the given regular expression (extract tokens from a string with the specified delimiter). Example: String[] tokens = Java#HTML#Perl.split(#, 0); for (int i = 0; i < tokens.length; i++) System.out.println(tokens[i] + ); Produces as output: Java HTML Perl Section 9.2.7 Matching, Replacing, and Splitting by Patterns A regular expression is a string that specifies a pattern in a text string to look for. The method matches(String regex) of the String class returns whether or not the String matches the regular expression regex. Example: All the following return true because the substring .* of the regular expression Java.* matches any zero or more characters. Java is fun..matches(Java.*) Java is cool..matches(Java.*) Java is powerful..matches(Java.*) Example: Check to see if two strings are valid social security numbers. Computer Science Notes Chapter 9 Page 17 of 23 String validSSN = 111-11-1111; System.out.println(validSSN.matches([\\d][ \\d][ \\d]- + [ \\d][ \\d]-[ \\d][ \\d][ \\d][ \\d])); String inValidSSN = 22-11-1111; System.out.println(inValidSSN.matches([\\d][ \\d][ \\d]- + [ \\d][ \\d]-[ \\d][ \\d][ \\d][ \\d])); The method replaceAll(String regex, String replacement) of the String class replaces all matches of the regular expression regex with the string replacement. Example: String s = a+b$#c.replaceAll([$+#],NNN); System.out.println(s); //returns aNNNbNNNNNNc Java is cool..matches(Java.*) Java is powerful..matches(Java.*) The method split(String regex) of the String class returns an array of Strings where each string in the array is obtained by splitting the original string at matches of the given regular expression. Example: String[] tokens = Java,C?C#,C++.split([.,:;?]); for (int i = 0; i < tokens.length; i++) System.out.println(tokens[i]); //returns Java C C# C++ ***Same as Table 8.1 in intro6e p281 ***with modifications Computer Science Notes Chapter 9 Page 18 of 23 Table 1: Frequently Used Regular Expressions Regular Expression x . (ab|cd) [abc] [^abc] Matches Example a specified character x any single character ab or cd a, b, or c any character except a, b, or c a through z any character except a through z a through e or m through p intersection of a-e with c-p Java matches Java Java matches J..a ten matches t(en|im) Java matches Ja[uvwx]a Java matches Ja[^ars]a \d \D \w \W \s \S a a a a a a Java2 matches "Java[\\d]" $Java matches "[\\D][\\D]ava" Java matches "[\\w]ava" $Java matches "[\\W][\\w]ava" "Java 2" matches "Java\\s2" Java matches "[\\S]ava" p* zero or more occurrences of pattern p one or more occurrences of pattern p zero or one occurrence of pattern p exactly n occurrences of pattern p at least n occurrences of pattern p between n and m occurrences (inclusive) [a-z] [^a-z] [a-e[m-p]] [a-e&&[c-p]] p+ p? p{n} p{n,} p{n,m} digit, same as [0-9] non-digit word character non-word character whitespace character non-whitespace char Java matches [A-M]av[a-d] Java matches Jav[^b-d] Java matches [A-G[I-M]]av[a-d] Java matches [A-P&&[I-M]]av[a-d] Java matches "a*" bbb matches "a*" Java matches "a+" bbb matches "a+" Java matches "J?Java" ava matches "J?ava" Java matches "a{1}" Java does not match "a{2}" Java matches "a{1,}" Java does not match "a{2,}" Java matches "a{1,9}" Java does not match "a{2,9}" The above table is from http://www.cs.armstrong.edu/liang/intro7e/supplement/SupplementRegularExpression.doc Section 9.2.8 Finding a Character or a Substring in a String Welcome to Java.indexOf(W) returns Welcome to Java.indexOf(o) returns Welcome to Java.indexOf(o, 5) returns Welcome to Java.indexOf(come) returns Welcome to Java.indexOf(Java) returns Welcome to Java.indexOf(Java, 5) returns Welcome to Java.lastIndexOf(W) returns Welcome to Java.lastIndexOf(o) returns Welcome to Java.lastIndexOf(o, 5)returns 0. 4. 8. 3. 11. -1. 0. 8. 4. Section 9.2.9 Conversion Between Strings and Arrays The method toCharArray() of the String class converts a string into a character array Example: Computer Science Notes Chapter 9 Page 19 of 23 char[] chars = Java. toCharArray (); for (int i = 0; i < chars.length; i++) System.out.println(chars[i]); //returns J a v a The method getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) of the String class copies a substring of characters starting at index srcBegin and ending at index srcEnd – 1 into array dst starting at index dstBegin. The constructor String(char[]) of the String class creates a string containing all the characters in the character array. The static method valueOf(char[]) of the String class returns a string containing all the characters in the character array. Section 9.2.10 Converting Characters and Numeric Values to Strings The static methods valueOf(char[]),valueOf (char) , valueOf(double) , valueOf(float) , valueOf(int), and valueOf(long) of the String class return a string representation of the given character, array of characters, or number. The static methods Double.parseDouble(String) and Integer.parseInt(String) return a numerical representation of the given string. Section 9.2.11 Formatting Strings String.format(String format, item1, item2, …) Section 9.2.12 Problem: Checking Palindromes See http://www.cs.armstrong.edu/liang/intro8e/html/CheckPalindrome.html Section 9.2.13 Problem: Converting Hexadecimals to Decimals See http://www.cs.armstrong.edu/liang/intro8e/html/HexToDecimalConversion.html Section 9.3: The Character Class Java provides a wrapper class for every primitive data type. A wrapper class stores the primitive data type and provides several useful methods relating to that data type. The Character class is a wrapper class for the primitive char data type, and provides methods like isLetter() that determine whether or not the character is an alphabetic letter. See http://download.oracle.com/javase/6/docs/api/java/lang/Character.html http://download.oracle.com/javase/6/docs/api/java/lang/Boolean.html http://download.oracle.com/javase/6/docs/api/java/lang/Byte.html http://download.oracle.com/javase/6/docs/api/java/lang/Short.html http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html http://download.oracle.com/javase/6/docs/api/java/lang/Long.html http://download.oracle.com/javase/6/docs/api/java/lang/Float.html http://download.oracle.com/javase/6/docs/api/java/lang/Double.html Computer Science Notes Chapter 9 Page 20 of 23 Section 9.4 The StringBuilder/StringBuffer Classes Instances are like a String object, but more flexible (you can mutate the data fields). You can add, insert, or append new content into a StringBuffer/StringBuilder object. The StringBuffer class is older, and should be used when it will be accessed by multiple tasks concurrently. See http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html The StringBuilder class was introduced in JDK 1.5, and is more efficient when it will be accessed by a single task. See http://download.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html Section 9.4.1 Modifying Strings in the StringBuilder The append() method can be used to append information to the end of a StringBuilder object. The delete() and deleteCharAt() methods can be used to delete a range of characters or a single character, respectively, from a StringBuilder object. The insert() method can be used to insert characters into the middle of a StringBuilder object. The replace() method can be used to replace characters into the middle of a StringBuilder object. The setCharAt() method can be used to replace a single character in the middle of a StringBuilder object. The reverse() method can be used to reverse the order of all characters in a StringBuilder object. Section 9.4.2 The toString, capacity, length, setLength, and charAt Methods The toString() method returns a String object from the StringBuilder object. The capacity() method returns the number of characters this StringBuilder object can store without increasing its size. The charAt() method returns a single character from a StringBuilder object. The length() method returns the number of characters stored in a StringBuilder object. The setLength() sets a new length for a StringBuilder object (characters are either deleted or null characters are appended). The subString() method returns a substring within a StringBuilder object. The trimToSize() method reduces the capacity of a StringBuilder object to the length of the character array it stores. Section 9.4.3 Problem: Ignoring Nonalphanumeric Charcters When Checking Palindromes See http://www.cs.armstrong.edu/liang/intro8e/html/PalindromeIgnoreNonAlphanumeric.html Computer Science Notes Chapter 9 Page 21 of 23 Section 9.5 Command Line Arguments The main method always has an array of String objects for an input parameter… public static void main(String[] args) {…} The array of String objects is created and passed to main when the compiled Java program is run from the command line with stuff typed after the name of the program… java myProgram First Name hello 23 You have to write the code that processes the array of Strings. Section 9.5.1 Passing Strings to the main Method To send strings to your program from the command line, simple type them after the name of the program with a space between each string … java myProgram First Name hello 23 You have to write the code that processes the array of Strings. Section 9.5.2 Problem: Calculator See http://www.cs.armstrong.edu/liang/intro8e/html/Calculator.html Section 9.6 The File Class The java.io.File class is used to obtain file properties and to delete and rename files. The File class does not contain methods to read the contents of or write to a file. See http://download.oracle.com/javase/6/docs/api/java/io/File.html See http://www.cs.armstrong.edu/liang/intro8e/html/TestFileClass.html Section 9.7 File Input and Output The File class does not contain methods to read the contents of or write to a file. In order to perform I/O (input/output), you need to use objects that have appropriate methods for reading and writing data. The two classes this chapter uses are the Scanner class for reading and the PrintWriter class for writing. See http://download.oracle.com/javase/6/docs/api/java/util/Scanner.html See http://download.oracle.com/javase/6/docs/api/java/io/PrintWriter.html There are 3 things you need to do in general in any programming language when dealing with disk files: 1. Open the file for reading or writing. In this chapter, opening a file will be accomplished by creating an instance of a Scanner object or a PrintWriter object. 2. Read data from or write data to the file. In this chapter, we will read from a file using one of the next* methods of the Scanner class, and we will write to a file using one of the print* methods of the PrintWriter class. 3. Close the file. In this chapter, we will close a file by using the close() method of the Scanner and PrintWriter classes. Extra Java things: 1. You have to create a File object and use it when you instantiate the Scanner or PrintWriter classes so they know what file to open for reading or writing. 2. Any method that does I/O needs to have throws Exception tacked on after the parameter list. Computer Science Notes Chapter 9 Page 22 of 23 Examples: Text Input //Create a File object. java.io.File inputFile = new java.io.File(inputData.txt); Text Output //Create a File object. java.io.File outputFile = new java.io.File(outputData.txt); //Open the file for reading. Scanner diskInput = new Scanner (inputFile); //Open the file for writing. PrintWriter diskOutput = new PrintWriter (outputFile); //Read a line of text from the File. String firstLine = diskInput.next(); //Write a line of text to the File. diskOutput.println(Here is a line of text written on the disk.); //Close the File. diskInput.close(); //Close the File. diskOutput.close(); Section 9.7.1 Writing Data Using PrintWriter See http://www.cs.armstrong.edu/liang/intro8e/html/WriteData.html The print() methods of the PrintWriter class write various types of information without including a line feed. The println() methods of the PrintWriter class write various types of information with a line feed. The printf() method of the PrintWriter class performs formatted writes. The close() method of the PrintWriter class closes the file that was opened for writing. Section 9.7.2 Reading Data Using Scanner See http://www.cs.armstrong.edu/liang/intro8e/html/ReadData.html The hasNext() method of the Scanner class returns true if the Scanner has more data to be read. The next() method of the Scanner class returns the next token as a string delimited by whitespace. The nextLine() method of the Scanner class returns a line of text ending with the line separator. The nextByte() method of the Scanner class returns the next token as a byte. The nextInt() method of the Scanner class returns the next token as an int. The nextShort() method of the Scanner class returns the next token as a short. The nextLong() method of the Scanner class returns the next token as a long. The nextDouble() method of the Scanner class returns the next token as a double. The nextFloat() method of the Scanner class returns the next token as a float. Computer Science Notes Chapter 9 Page 23 of 23 Section 9.7.3 How Does Scanner Work? By skipping delimiters (i.e., whitespace), and the reading in a token up to the next delimiter. Section 9.7.4 Problem: Replacing Text See http://www.cs.armstrong.edu/liang/intro8e/html/ReplaceText.html Section 9.8 (GUI) File Dialogs See http://download.oracle.com/javase/6/docs/api/javax/swing/JFileChooser.html See http://www.cs.armstrong.edu/liang/intro8e/html/ReadFileUsingJFileChooser.html