680 likes | 693 Views
Object-based Scanning. Redo the scanning solutions Monolithic, single class solutions does UI and scanning No reuse of code. Upper case printing. package warmup; public class AnUpperCasePrinter { public static void main(String[] args){ if (args.length != 1) {
E N D
Object-based Scanning • Redo the scanning solutions • Monolithic, single class solutions • does UI and scanning • No reuse of code
Upper case printing package warmup; public class AnUpperCasePrinter { publicstatic void main(String[] args){ if (args.length != 1) { System.out.println("Illegal number of arguments:" + args.length + ". Terminating program."); System.exit(-1); } System.out.println("Upper Case Letters:"); int index = 0; while (index < args[0].length()) { if (isUpperCase(args[0].charAt(index))) System.out.print(args[0].charAt(index)); index++; } } System.out.println(); } publicstaticboolean isUpperCase(char c) { return (c >= 'A') && (c <= 'Z'); } }
Forward and reverse printing package warmup; public class AReverseUpperCasePrinter { static final int MAX_CHARS = 5; static char[] upperCaseLetters = new char[MAX_CHARS]; static int numberOfUpperCaseLetters = 0; public static void main(String[] args){ if (args.length != 1) { System.out.println("Illegal number of arguments:" + args.length + ". Terminating program."); System.exit(-1); } int index = 0; System.out.println("Upper Case Letters:"); while (index < args[0].length()) { if (isUpperCase(args[0].charAt(index))) { System.out.print(args[0].charAt(index)); storeChar(args[0].charAt(index)); } index++; } System.out.println(); printReverse(); }
Forward and reverse printing (contd.) public static void storeChar(char c) { if (numberOfUpperCaseLetters == MAX_CHARS) { System.out.println("Too many upper case letters. Terminating program. "); System.exit(-1); } upperCaseLetters[numberOfUpperCaseLetters] = c; numberOfUpperCaseLetters++; } public static void printReverse() { System.out.println("Upper Case Letters in Reverse:"); for (int index =numberOfUpperCaseLetters - 1; index >= 0; index--) { System.out.print(upperCaseLetters[index]); } } }
No reuse in Monolithic Solutions int index = 0; System.out.println("Upper Case Letters :");//token processing while (index < args[0].length()) { if (Character.isUpperCase(args[0].charAt(index);)) System.out.print(args[0].charAt(index)); // token processing index++; } int index = 0; System.out.println("Upper Case Letters :");//token processing while (index < args[0].length()) { if (Character.isUpperCase(args[0].charAt(index);)) { System.out.print(args[0].charAt(index);); // token processing storeChar(args[0].charAt(index)); } index++; }
Class Decomposition? Main Class
Class Decomposition instantiate Scanner Class Scanner Object calls Scanner User Main Class (Input & Output)
Class Decomposition instantiate BufferedReader Instance BufferedReader readLine() Scanner User Main Class (Input & Output)
Scanner User-Scanner Object Interaction • BufferedReader dataIn = new BufferedReader (new InputStreamReader( System.in)); • int product = 1; • // add input list terminated by a negative number • while (true) { • int num = Integer.parseInt (dataIn.readLine()); • if (num < 0) break; • product = product*num; • } • System.out.println (product);
Constructor parameters • InputStreamReader takes System.in as parameter. • BufferedReader takes InputStreamReader as parameter. • In general, scanner takes object producing scanned stream as parameter.
BufferedReader Operations Multi-line input stream Line stream Line 1 Line 2 dataIn.readLine() Line 1 dataIn.readLine() Line 2 dataIn.readLine() IOException
Scanner Interface? Input stream Token Stream token 1 token 2 scanner.nextElement() token 1 scanner.nextElement() token 2 scanner.nextElement() ScannerException
Scanner Interface? Input stream Token Stream token 1 token 2 scanner.nextElement() token 1 scanner.nextElement() token 2 scanner.hasMoreElements() false scanner.nextElement() ???
J o h n F . K e n n e d y token 1 token 2 token 3 Uppercase Scanner Interface? scanner.nextElement() ‘J’ scanner.nextElement() ‘F’ scanner.nextElement() ‘K’ scanner.hasMoreElements() false scanner.nextElement() ???
Enumeration Interfaces • package enums; • public interface CharEnumeration { • publicchar nextElement(); • publicboolean hasMoreElements(); • } • package enums; • public interface StringEnumeration { • publicString nextElement(); • publicboolean hasMoreElements(); • } • package <P>; • public interface <Type>Enumeration { • public <Type> nextElement(); • publicboolean hasMoreElements(); • }
J o h n F . K e n n e d y token 1 token 2 token 3 Using an Enumeration Interface publicstaticvoid printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); }
package main; import enums.CharEnumeration; import enums.AnUpperCaseEnumeration; public class UpperCasePrinter { publicstaticvoid main (String args[]) { if (args.length != 1) { System.out.println("Illegal number of arguments:" + args.length + ". Terminating program."); System.exit(-1); } printUpperCase(args[0]); } publicstaticvoid printUpperCase(String s) { System.out.println("Upper Case Letters:"); printChars (new AnUpperCaseEnumeration(s)); } publicstaticvoid printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); } } Using an Enumeration Interface
Implementing Scanner • package enums; • public class AnUpperCaseEnumeration implements CharEnumeration { • … • public AnUpperCaseEnumeration(String theString) { • ... • } • publicboolean hasMoreElements() { • ... • } • publicchar nextElement() { • ...; • } • … • }
Data Structure: Scanned String • package enums; • public class AnUpperCaseEnumeration implements CharEnumeration { • String string; • … • public AnUpperCaseEnumeration(String theString) { • string = theString; • ... • } • publicboolean hasMoreElements() { • ... • } • publicchar nextElement() { • ...; • } • … • }
Data Structure: marker string J o h n F . K e n n e d y scanned part Unscanned part nextElementPos
true hasMoreElements() string J o h n F . K e n n e d y nextElementPos • publicboolean hasMoreElements() { • ... • }
true hasMoreElements() string J o h n F . K e n n e d y nextElementPos • publicboolean hasMoreElements() { • ... • }
false hasMoreElements() string J o h n F . K e n n e d y nextElementPos • publicboolean hasMoreElements() { • ... • }
hasMoreElements() string J o h n F . K e n n e d y nextElementPos • //return true if nextElementPos is beyond end of string; false otherwise • publicboolean hasMoreElements() { • ... • }
hasMoreElements() string J o h n F . K e n n e d y nextElementPos • //return false if nextElementPos is beyond end of string; true otherwise • publicboolean hasMoreElements() { • return nextElementPos < string.length(); • }
nextElement() string J o h n F . K e n n e d y nextElementPos publicchar nextElement() { }
nextElement() string J o h n F . K e n n e d y 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 publicchar nextElements() { }
Unexecuted Loop char retVal = string.charAt(nextElemPos) return retVal; nextElement() string J o h n F . K e n n e d y 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 publicchar nextElement() { } • while (!isUpperCase(string.charAt(nextElementPos))) nextElemPos++;
char retVal = extractToken(); return retVal; nextElement() string J o h n F . K e n n e d y 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 publicchar nextElements() { } movePastCurrentToken(); skipNonTokenCharacters();
nextElement() string J o h n F . K e n n e d y nextElementPos //Assume nextElemPos is at start of next token or end of string when //method is called. //returns next token if one exists publicchar extractToken() { } return string.charAt(nextElementPos);
movePastCurrentToken() string J o h n F . K e n n e d y nextElementPos //Assume nextElemPos is at start of next token or end of string when //method is called. //Moves past current token. publicvoid movePastCurrentToken() { } nextElemPos++;
StringIndexOutOfBounds skipNonTokenCharacters() string J o h n F . K e n n e d y nextElementPos // keep advancing nextElementPos until we hit the next upper case publicvoid skipNonTokenCharacters() { } • while (! isUpperCase(string.charAt(nextElementPos))) nextElemPos++;
short-circuit StringIndexOutOfBounds? skipNonTokenCharacters() string J o h n F . K e n n e d y nextElementPos // keep advancing nextElementPos until we hit the next upper case or go // beyond the end of the string. publicvoid skipNonTokenCharacters() { } • while (nextElementPos < string.length() && !Character.isUpperCase(string.charAt(nextElementPos))) nextElemPos++;
Initialization string j o h n F . K e n n e d y nextElementPos String string; int nextElementPos = 0; public AnUpperCaseEnumeration(String theString) { } string = theString; skipNonTokenCharacters();
constructor package enums; public class AnUpperCaseEnumeration implements CharEnumeration { String string; int nextElementPos = 0; public AnUpperCaseEnumeration(String theString) { string = theString; skipNonTokenCharacters(); } publicboolean hasMoreElements() { return nextElementPos < string.length();} publicchar nextElement() { char retVal = extractToken(); movePastCurrentToken(); skipNonTokenCharacters(); return retVal; } void movePastCurrentToken() {nextElementPos++;} void skipNonTokenCharacters() { while (nextElementPos < string.length() && !isUpperCase(string.charAt(nextElementPos))) nextElementPos++; } char extractToken() { return string.charAt(nextElementPos);} boolean isUpperCase (char c) { return c >= ‘A’ && c <= ‘Z’;} } Complete Scanner
package <P>; public class <Scanner Name> implements <T>Enumeration { String string; int nextElementStart = 0; int nextElementEnd = ???; public AnUpperCaseEnumeration(String theString) { string = theString; skipNonTokenCharacters(); } publicboolean hasMoreElements() { return nextElementStart < string.length();} public <T> nextElement() { <T> retVal = extractToken(tokenLength); movePastCurrentToken(tokenLength); skipNonTokenCharacters(); return retVal; } void movePastCurrentToken() {…}; void skipNonTokenCharacters() {…}; char extractToken() { …} } Scanner Pattern
Class Decomposition instantiate AnUpperCaseEnumeration instance AnUpperCaseEnumeration AnUppercasePrinter
Class Decomposition instantiate AnUpperCaseEnumeration instance AnUpperCaseEnumeration AReverseUpperCasePrinter
Reuse of Enumeration • while (charEnumeration.hasMoreElements()) { • char nextChar = charEnumeration.nextElement()); • System.out.print(nextChar); • storeChar(nextChar); • } while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement());
J o h n F . K e n n e d y token 1 token 2 token 3 Enumeration Vs Scanning • public interface CharEnumeration { • publicchar nextElement(); • publicboolean hasMoreElements(); • }
Enumeration without Scanning ‘A’ ‘B’ ... ‘Z’ AllUppercaseLettersInOrder implements • public interface CharEnumeration { • publicchar nextElement(); • publicboolean hasMoreElements(); • }