Scanning Scanning image for text. Scanning frequencies for radio stations. Finding words in a sentence Finding identifiers, operators, in a program char String Variable-size type –Indexing –Enumeration
Primitive Types int, double, boolean, long, short, float, byte char
Primitive Types Constants (Literals & Named Constants) Operations with Invocation Syntax
char Constants char {letters, digits, operators...} ‘a’ ‘A‘ ‘1’ ‘< ‘ ‘’ 16 bits ‘ ‘’’ ‘\’’ Escape sequence ‘\n’ newline ‘ ‘\’ ‘\\’
Useful Escape Sequences
Ordering Characters ‘’‘a’…. position in ordered character list ordinal number (integer code) ….
Ordering Characters ‘’‘a’…. ‘b’‘c’‘z’…. ‘’‘A’…. ‘B’‘C’‘Z’…. ‘’‘0’…. ‘1’‘2’‘3’…. ‘a’ > ‘b’ false ‘B’ > ‘A’ true ‘4’ > ‘0’ true ‘0’ > ‘’ true ‘a’ > ‘A’ ??? ‘a’ > ‘0’ ???
Converting between Characters and their Ordinal Numbers (int) ‘a’ ordinal number of ’a’ (char) 55 character whose ordinal number is 55 (int) ‘’ 0 0 (char) 0 ‘’ (int) ‘d’ ??? (char) 1 ??? (char) -1 (int) ‘c’ - (int) ‘a’ 2 2 ‘c’ - ‘a’ 2 2 Implicit cast to wider type (char) (‘c’ - 2) ‘a’ (char) (‘A’ + 2) ‘C’ (char) (‘C’ - ‘A’ + ‘a’) ‘c’
A Useful Character Operation Character.isLetter(c) true if c is a letter Character.isLetter(‘a’) true Character.isLetter(‘A’) true Character.isLetter(‘1’) false Character.isLetter(‘ ’) false
String constants String{sequences of characters} “hello” “123” “hello 123” “a” variable size ‘a’ “” “hello\n\n123” “\”“\\” Object Type
Accessing String Components String s = “hello world”; s.getFirstChar() s.getSecondChar()... s.charAt(0) ‘h’ s.charAt(1) ‘e’ s.charAt(-1) s.charAt(11) StringIndexBounds exceptiom index s.length() 11 “ ”.length() 1 1 0 0
Accessing SubString “hello world”.substring(4,7) public String substring (int beginIndex, int endIndex) s.charAt(beginIndex).. s.charAt(endIndex-1) s.substring(beginIndex, endIndex) “o w” “hello world”.substring(4,4) “” “hello world”.substring(7,4) StringIndexBounds exceptiom
Changing Strings? Strings are read-only (immutable) “hello” + “world” “hello world” three different instances
Useful String Operations s.toLowerCase() copy of s with letters converted to lower case s.toUpperCase() copy of s with letters converted to upper case “Hello World”.toLowerCase() “hello world” “Hello World”.toUpperCase() “HELLO WORLD”
String Processing int i = 0; while (i < s.length()) { System.out.println (s.charAt(i)); i++; } prints each character on separate line
Dissecting a Loop int i = 0; while (i < s.length()) { System.out.println (s.charAt(i)); i++; } loop condition loop body
Finer-grained Dissection int i = 0; while (i < s.length()) { System.out.println (s.charAt(i)); i++; } loop condition real body Resetting loop variable initalizing loop variables for (int i=0; i<s.length(); i++) System.out.println(s.charAt(i));
Meaning of For Loop S1; while ( E) { S3; S2; } for (S1; E; S2) S3 for (; E; S2) S3 while ( E) { S3; S2; } for (; E; ) S3 while ( E) { S3; } for (; ; ) S3 while ( true) S3;
Scanning Problem
Scanning JohnF.Kenndye token Input stream Token Stream token Line 1Line 2 Multi-line input stream Line stream
Solution Monolithic Solution Class Decomposition
Algorithm String inputLine
Algorithm JohnF.Kenndye marker 0 Output: J String inputLine
Algorithm JohnF.Kenndye marker 1 Output: J String inputLine
Algorithm JohnF.Kenndye marker 2 Output: J String inputLine
Algorithm JohnF.Kenndye marker 5 Output: JF String inputLine
Algorithm JohnF.Kenndye marker 6 Output: JF String inputLine
Algorithm JohnF.Kenndye marker 8 Output: JFK String inputLine
Algorithm JohnF.Kenndye marker 9 Output: JFK String inputLine
Algorithm JohnF.Kenndye marker 14 Output: JFK String inputLine
Monolithic Solution public class UpperCasePrinter { public static void main (String args[]) { String input = getInput(); int index = 0; System.out.println("Upper Case Letters :"); while (index < input.length()) { char nextChar = input.charAt(index); if (Character.isUpperCase(nextChar)) System.out.print(nextChar); // token processing index++; } public static String getInput() { System.out.println("Please enter a string"); return Keyboard.readLine(); }
Storing instead of printing tokens JohnF.Kenndye marker 14 String s = “JFK”; String inputLine
No reuse in Monolithic Solutions String s = ""; // token processing int index = 0; while (index < input.length()) { char nextChar = input.charAt(index); if (Character.isUpperCase(nextChar)) s += nextChar; // token processing index++; } int index = 0; System.out.println("Upper Case Letters :");//token processing while (index < input.length()) { char nextChar = input.charAt(index); if (Character.isUpperCase(nextChar)) System.out.print(nextChar); // token processing index ++; }
Class Decomposition? Main Class
Division of Labor in Radio Scanning
?
Scanner Object calls Scanner User Main Class (Input & Output) Class Decomposition Scanner Class instantiate
DataInputStream Instance readLine() Scanner User Main Class (Input & Output) Class Decomposition DataInputStream instantiate
Scanner User-Scanner Object Interaction DataInputStream dataIn = new DataInputStream (System.in); int product = 1; while (true) { int num = Integer.parseInt (dataIn.readLine()); if (num < 0) break; product = product*num; } System.out.println (product);
DataInputStream Operations Line 1Line 2 Multi-line input stream Line stream dataIn.readLine()Line 1 dataIn.readLine()Line 2 dataIn.readLine()IOException
Scanner Interface? scanner.nextElement()token 1 scanner.nextElement()token 2 scanner.nextElement()ScannerException token 1token 2 Input stream Token Stream
Scanner Interface? scanner.nextElement()token 1 scanner.nextElement()token 2 scanner.hasMoreElements()false Input stream Token Stream token 1token 2 scanner.nextElement()???
Uppercase Scanner Interface? scanner.nextElement()‘J’ scanner.nextElement()‘F’ scanner.hasMoreElements()false JohnF.Kenndye token 1token 2token 3 scanner.nextElement()‘K’ scanner.nextElement()???
Enumeration Interfaces public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements(); } public interface StringEnumeration { public String nextElement(); public boolean hasMoreElements(); } public interface Enumeration { public nextElement(); public boolean hasMoreElements(); }
Using an Enumeration Interface public static void printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); } JohnF.Kenndye token 1token 2token 3
Using an Enumeration Interface public class UpperCasePrinter { public static void main (String args[]) { String input = getInput(); printUpperCase(input); } public static String getInput() { System.out.println("Please enter a string"); return Keyboard.readLine(); } public static void printUpperCase(String s) { System.out.println("Upper Case Letters:"); printChars (new AnUpperCaseEnumeration(s)); } public static void printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); }
Implementing Scanner public class AnUpperCaseEnumeration implements CharEnumeration { … public AnUpperCaseEnumeration(String theString) {... } public boolean hasMoreElements() {... } public char nextElement() {...; } … }
Data Structure: Scanned String public class AnUpperCaseEnumeration implements CharEnumeration { String string; … public AnUpperCaseEnumeration(String theString) { string = theString;... } public boolean hasMoreElements() {... } public char nextElement() {...; } … }
Data Structure: marker JohnF.Kenndye nextElementPos string scanned partUnscanned part
hasMoreElements() JohnF.Kenndye string nextElementPos public boolean hasMoreElements() {... } true
hasMoreElements() JohnF.Kenndye string nextElementPos public boolean hasMoreElements() {... } true
hasMoreElements() JohnF.Kenndye string nextElementPos public boolean hasMoreElements() {... } false
hasMoreElements() JohnF.Kenndye string nextElementPos //return true if nextElementPos is beyond end of string; false otherwise public boolean hasMoreElements() {... }
hasMoreElements() (edited) JohnF.Kenndye string nextElementPos //return false if nextElementPos is beyond end of string; true otherwise public boolean hasMoreElements() { return string.length() > nextElementPos; }
hasMoreElements() JohnF.Kenndye string nextElementPos //return false if nextElementPos is beyond end of string; true otherwise public boolean hasMoreElements() { return nextElementPos < string.length(); }
nextElement() JohnF.Kenndye string nextElementPos public char nextElement() { }
nextElement() JohnF.Kenndye string nextElementPos //Assume nextElemPos is at start of next token or end of string when //method is called. //Method makes sure this is also true before returning. //returns next element if one exists public char nextElements() { }
nextElement() JohnF.Kenndye string nextElementPos //Assume nextElemPos is at start of next token or end of string when //method is called. //Method makes sure this is also true before returning. //returns next element if one exists public char nextElements() { } char retVal = string.charAt(nextElemPos) return retVal; while (!Character.isUpperCase(string.charAt(nextElementPos))) nextElemPos++; Unexecuted Loop
nextElement() JohnF.Kenndye string nextElementPos //Assume nextElemPos is at start of next token or end of string when //method is called. //Method makes sure this is also true before returning. //returns next element if one exists public char nextElements() { } movePastCurrentToken(); char retVal = extractToken(); return retVal; skipNonTokenCharacters();
nextElement() JohnF.Kenndye string nextElementPos //Assume nextElemPos is at start of next token or end of string when //method is called. //returns next token if one exists public char extractToken() { } return string.charAt(nextElementPos);
movePastCurrentToken() //Assume nextElemPos is at start of next token or end of string when //method is called. //Moves past current token. public void movePastCurrentToken() { } nextElemPos++; JohnF.Kenndye string nextElementPos
skipNonTokenCharacters() JohnF.Kenndye string nextElementPos // keep advancing nextElementPos until we hit the next upper case public void skipNonTokenCharacters() { } while (!Character.isUpperCase(string.charAt(nextElementPos))) nextElemPos++; StringIndexOutOfBounds
skipNonTokenCharacters() JohnF.Kenndye string nextElementPos // keep advancing nextElementPos until we hit the next upper case or go // beyond the end of the string. public void skipNonTokenCharacters() { } while (nextElementPos < string.length() && !Character.isUpperCase(string.charAt(nextElement Pos))) nextElemPos++; StringIndexOutOfBounds?short-circuit
Initialization johnF.Kenndye string nextElementPos String string; int nextElementPos = 0; public AnUpperCaseEnumeration(String theString) { } string = theString; skipNonTokenCharacters();
Complete Scanner public class AnUpperCaseEnumeration implements CharEnumeration { String string; int nextElementPos = 0; public AnUpperCaseEnumeration(String theString) { string = theString; skipNonTokenCharacters(); } public boolean hasMoreElements() { return nextElementPos < string.length();} public char nextElement() { char retVal = extractToken(); movePastCurrentToken(); skipNonTokenCharacters(); return retVal; } void movePastCurrentToken() {nextElementPos++;} void skipNonTokenCharacters() { while (nextElementPos < string.length() && !Character.isUpperCase(string.charAt(nextElementPos))) nextElementPos++; } char extractToken() { return string.charAt(nextElementPos);} }
Scanner Pattern public class implements Enumeration { String string; int nextElementStart = 0; int nextElementEnd = ???; public AnUpperCaseEnumeration(String theString) { string = theString; skipNonTokenCharacters(); } public boolean hasMoreElements() { return nextElementStart < string.length();} public nextElement() { retVal = extractToken(tokenLength); movePastCurrentToken(tokenLength); skipNonTokenCharacters(); return retVal; } void movePastCurrentToken() {…}; void skipNonTokenCharacters() {…}; char extractToken() { …} }
Scanner User Again public class UpperCasePrinter { public static void main (String args[]) { String input = getInput(); printUpperCase(input); } public static String getInput() { System.out.println("Please enter a string"); return Keyboard.readLine(); } public static void printUpperCase(String s) { System.out.println("Upper Case Letters:"); printChars (new AnUpperCaseEnumeration(s)); } public static void printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); }
Monolithic Solution public class UpperCasePrinter { public static void main (String args[]) { String input = getInput(); int index = 0; System.out.println("Upper Case Letters :"); while (index < input.length()) { char nextChar = input.charAt(index); if (Character.isUpperCase(nextChar)) System.out.print(nextChar); // token processing index++; } public static String getInput() { System.out.println("Please enter a string"); return Keyboard.readLine(); }
AnUpperCaseEnumeration instance Class Decomposition AnUpperCaseEnumeration instantiate AnUppercasePrinter
AnUpperCaseEnumeration instance Class Decomposition AnUpperCaseEnumeration instantiate AnUppercaseConcatenator
Reuse of Enumeration String s = ""; while (charEnumeration.hasMoreElements()) { s += charEnumeration.nextElement(); } while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement());
Monolithic Solution String s = ""; // token processing int index = 0; while (index < input.length()) { char nextChar = input.charAt(index); if (Character.isUpperCase(nextChar)) s += nextChar; // token processing index++; } int index = 0; System.out.println("Upper Case Letters :");//token processing while (index < input.length()) { char nextChar = input.charAt(index); if (Character.isUpperCase(nextChar)) System.out.print(nextChar); // token processing index ++; }
Monolithic Solution to readLine() initialize while there is more input set next line; user code to process next line …. move next line markers
Enumeration Vs Scanning public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements(); } JohnF.Kenndye token 1token 2token 3
Enumeration without Scanning public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements(); } AllUppercaseLettersInOrder implements ‘A’‘B’...‘Z’
Enumerating all Uppercase Letters public boolean hasMoreElements() { ???? } public char nextElement() { ??? } //instance variables ???
Enumerating all Uppercase Letters (edited) public boolean hasMoreElements() { ???? } //instance variables ??? public char nextElement() { ??? }
Enumerating all Uppercase Letters public class AllUpperCaseLettersInOrder implements CharEnumeration { char nextLetter = 'A'; public boolean hasMoreElements() { return nextLetter <= 'Z'; } public char nextElement() { char retVal = nextLetter; nextLetter = (char) (nextLetter + 1); return retVal; }
Comparing Two Implementations public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements(); } JohnF.Kenndye token 1token 2token 3 AnUpperCaseEnumeration implements ‘J’‘F’‘K’
Radically Different Behaviors public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements(); } AllUppercaseLettersInOrder implements ‘A’‘B’...‘Z’ print (new AnUppercaseEnumeration(s)); print (new AllUppercaseLettersInOrder()); Polymorphism Syntactic Specification!