Session 5 More on Java Strings and Files - PowerPoint PPT Presentation

About This Presentation
Title:

Session 5 More on Java Strings and Files

Description:

use a stereotypical loop to process a file of lines. use of the stereotypical StringTokenizer loop as inner loop. import java.io. ... – PowerPoint PPT presentation

Number of Views:25
Avg rating:3.0/5.0
Slides: 71
Provided by: markf91
Learn more at: http://www.cs.uni.edu
Category:

less

Transcript and Presenter's Notes

Title: Session 5 More on Java Strings and Files


1
Session 5More on Java Strings and Files
Intro. to Inheritance
2
Java File I/O
  • Allows us to write and read permanent
    information to and from disk
  • How would file I/O help improve the capabilities
    of the MemoPadApp?

3
Java File I/O Example Echo.java
  • echoes all the words in one file to an output
    file, one per line.
  • java Echo hamlet.txt hamlet.out
  • less hamlet.out
  • 1604
  • the
  • tragedy
  • of
  • hamlet
  • prince
  • of
  • denmark
  • by
  • william
  • shakespeare ...

4
Study Echo.javas File I/O
  • have constructors that allow convenient and
    flexible processing
  • send input message readLine()
  • send output messages print() and println()
  • use a stereotypical loop to process a file of
    lines
  • use of the stereotypical StringTokenizer loop as
    inner loop

5
import java.io. import java.util.StringTokenizer
public class Echo public static void
main( String args ) throws IOException
String delimiters " .?!()?/\\,-\'\"\t\n
\r" BufferedReader inputFile new
BufferedReader(new FileReader(args0) )
PrintWriter outputFile new PrintWriter( new
FileWriter( args1 ) ) String buffer
null while( true ) buffer
inputFile.readLine() if ( buffer
null ) break buffer
buffer.toLowerCase() StringTokenizer
tokens new StringTokenizer( buffer, delimiters
) while( tokens.hasMoreElements() )
String word
tokens.nextToken()
outputFile.println( word ) // end
while // end while(true)... //
end main // end class Echo
6
wc - UNIX/Linux utility
  • wc prints the number of lines, words, and
    characters in a file to standard output.
  • For example
  • wc hamlet.txt
  • 4792 31957 196505 hamlet.txt

7
Exercise
  • Using Echo.java as your starting point, create a
    WordCount.java program that does the same thing
    as wc, i.e., prints the number of lines, words,
    and characters in a file to standard output. For
    example
  • java WordCount hamlet.txt
  • lines 4792 words 32889 chars 130156

8
import java.io. import java.util.StringTokenizer
public class WordCount public static
void main( String args ) throws IOException
String delimiters " .?!()?/\\,-\'\
"\t\n\r" BufferedReader inputFile new
BufferedReader( new FileReader( args0 ) )
String buffer null int chars
0 int words 0 int
lines 0 while( true )
buffer inputFile.readLine() if (
buffer null ) break lines
buffer buffer.toLowerCase()
StringTokenizer tokens new StringTokenizer(
buffer, delimiters ) while(
tokens.hasMoreElements() )
String word tokens.nextToken()
words chars word.length()
// end while // end while(
true )... System.out.println( "" lines
" " words " " chars ) // end
main // end class WordCount
9
Why the difference in the number of words and
number of characters?
  • wc hamlet.txt
  • 4792 31957 196505 hamlet.txt
  • java WordCount hamlet.txt
  • lines4792 words32889 chars130156

10
Java File I/O Example Echo.java
  • echoes all the words in one file to an output
    file, one per line.
  • java Echo hamlet.txt hamlet.out
  • less hamlet.out
  • 1604
  • the
  • tragedy
  • of
  • hamlet
  • prince
  • of
  • denmark
  • by
  • william
  • shakespeare ...

11
import java.io. import java.util.StringTokenizer
public class Echo public static void
main( String args ) throws IOException
String delimiters " .?!()?/\\,-\'\"\t\n
\r" BufferedReader inputFile new
BufferedReader(new FileReader(args0) )
PrintWriter outputFile new PrintWriter( new
FileWriter( args1 ) ) String buffer
null while( true ) buffer
inputFile.readLine() if ( buffer
null ) break buffer
buffer.toLowerCase() StringTokenizer
tokens new StringTokenizer( buffer, delimiters
) while( tokens.hasMoreElements() )
String word
tokens.nextToken()
outputFile.println( word ) // end
while // end while(true)... //
end main // end class Echo
12
Working with Standard Input and Output as Files
  • Sometimes, we'd like to give the user an option
    of providing a file name or using standard I/O.
  • We can call sort with its own file argument, or
    we can pipe the standard output of one program
    (cat hamlet.out) as the standard input to sort.
  • How can we make our Java programs do the same
    thing?

13
Streams vs. Readers and Writers
  • a stream is a device for transmitting or
    receiving a sequence of byte (8-bit) values
  • emphasis on reading/writing -- not on data itself
  • network and file systems are based on byte unit
  • Readers and Writers use 16-bit Unicode
  • useful for I/O of textual values as opposed to
    binary data such as images, colors, etc.
  • for example, BufferedRead has readLine method

14
Working with Standard Input and Output as Files
  • Standard input is an instance of the InputStream
    class and does not respond to readLine(), which
    is how we would like to grab lines of text as
    Strings.
  • Standard output does respond to println()
    messages, but it is a PrintStream, which cannot
    be stored in a PrintWriter variable.

15
What can we do?
  • We could write duplicate code for the four
    different cases. (file-file, file-stdout,
    stdin-file, stdin-stdout)
  • Every case would look the same except for one or
    two lines.
  • That doesn't seem to be the correct solution.
  • Maybe we can find a way to have them talk to
    objects that talk to standard input and output...

16
A Solution
  • Let's take advantage of an object-oriented idea
    We ought to be able to substitute an object with
    a common interface, even if somewhat different
    behavior, in place of one another, and let the
    new object fulfill the responsibilities of the
    replaced one.
  • While BufferedReaders and PrintWriters don't know
    how to talk to standard input and output,
    respectively, we can use a translator to serve as
    a go-between.
  • Java give us the classes we need
    InputStreamReader and OutputStreamWriter.

17
import java.io. import java.util.StringTokenizer
public class EchoStandard public static
void main( String args ) throws IOException
String delimiters " .?!()?/\\,-\'\"\
t\n\r" BufferedReader inputFile new
BufferedReader(
new InputStreamReader( System.in ) )
PrintWriter outputFile new PrintWriter(
new OutputStreamWriter(
System.out ) ) String buffer null
while( true ) buffer
inputFile.readLine() if ( buffer
null ) break buffer
buffer.toLowerCase() StringTokenizer
tokens new StringTokenizer(buffer,delimiters)
while( tokens.hasMoreElements() )
String word tokens.nextToken()
outputFile.println( word ) // end
while // end while( true )... // end
main // end class EchoStandard
18
Echo
  • BufferedReader inputFile new BufferedReader(
  • new
    FileReader( args0) )
  • PrintWriter outputFile new PrintWriter(
  • new
    FileWriter( args1) )
  • vs. EchoStandard
  • BufferedReader inputFile new BufferedReader(
  • new InputStreamReader(
    System.in ) )
  • PrintWriter outputFile new PrintWriter(
  • new OutputStreamWriter(
    System.out ) )

19
Exercise
  • Turn Echo.java into EchoV2.java, which behaves
    just like Echo, except that it takes two optional
    command-line arguments the names of the input
    file and output file, respectively.
  • If the user omits the second argument, the
    program writes to standard output.
  • If the user omits both arguments, the program
    reads from standard output and writes to standard
    output. For example
  • java EchoV2 hamlet.txt hamlet.out
  • less hamlet.out
  • 1604
  • the
  • tragedy
  • of
  • ...

20
Exercise - More Examples
  • java EchoV2 EchoV2.java
  • ...
  • java EchoV2 hamlet.txt less (interesting
    that the pipe is not args1)
  • 1604
  • the
  • tragedy
  • of
  • ...
  • java EchoV2
  • ...
  • cat hamlet.txt java EchoV2 less
  • 1604
  • the
  • tragedy
  • of
  • ...

21
Introduction to Inheritance
22
Accumulator Example
  • a simple calculator app
  • classes needed
  • AdderApp - contains main
  • AddingFrame - GUI
  • CloseableFrame - allows X button
  • Accumulator - internal representation and
    implementation of the accumulator

23
AdderApp
  • contains the main() method that serves as the
    "Big Bang" for this part of the world
  • public class AdderApp
  • public static void main( String args )
  • AddingFrame f new AddingFrame()
  • f.show()
  • // end main
  • // end class AdderApp

24
AddingFrame
  • Provides the graphical interaction between the
    user and the actual calculator methods
  • AddingFrame extends CloseableFrame extends
    JFrame.
  • AddingFrame depends on the Accumulator class do
    the mathematics for the program.

25
Accumulator Class
  • Recall from CS I that a class contains three
    things.
  • Data / Instance Variables
  • Method(s)
  • Constructor(s)

26
Accumulator Class
  • What Data / Instance Variables are needed?

27
Accumulator Class
  • Data / Instance Variables needed
  • currentSum the current value accumulated by
    the accumulator.
  • currentNumber the number that has been entered
    by the user. The value that will be added or
    subtracted.
  • displayValue the value visible on the graphical
    calculator. (Needed because sometimes we display
    the number the user is entering (currentNumber)
    and sometimes it is the current accumulated value
    (currentSum), so we will maintain a new value
    which holds whatever is on display.)

28
Accumulator Class
  • What methods would the accumulator class need
    (hint, there are five of them)?

29
Accumulator Class
  • Needed methods
  • plus adds the last number entered to the
    currentSum.
  • minus subtracts the last number entered from
    the currentSum.
  • clear sets everything back to zero
  • addDigit adjusts the currentNumber upon input
    of an additional integer
  • getDisplay returns the current displayValue.
    (This is necessary because our graphical class
    will want to know what value to display any time
    some action occurs.)

30
Accumulator Class
  • What would the constructor do?

31
AccumulatorV1
  • public class AccumulatorV1
  • private int currentSum
  • private int currentNumber
  • private int displayNumber
  • public Accumulator()
  • currentSum0
  • currentNumber0
  • displayNumber0
  • public void clear()
  • currentSum0
  • currentNumber0
  • displayNumber0
  • public void addDigit( int digit )
  • public void plus()
  • currentSumcurrentNumber
  • currentNumber0
  • displayNumbercurrentSum
  • public void minus()
  • currentSum-currentNumber
  • currentNumber0
  • displayNumbercurrentSum
  • public int getDisplay()
  • return displayNumber
  • // end class AccumulatorV1

32
Refactoring Accumulator
  • What is refactoring?
  • Changing a program in a way that does not change
    its functionality.
  • Why do it?
  • To improve the structure of your code based on
    what you have learned since writing it.
  • What common code can we refactor?

33
Refactoring Accumulator
  • Using the clear() method in the constructor
  • Refactoring the plus() and minus() methods to
    call a private helper method.

34
Refactoring Accumulator
public void plus() currentSumcurrentNu
mber prepareForNextNumber()
public void minus() currentSum-currentNumber
prepareForNextNumber()
private void prepareForNextNumber()
currentNumber0 displayNumbercurrentSum
public int getDisplay() return
displayNumber // end class AccumulatorV2
public class AccumulatorV2 private int
currentSum private int currentNumber
private int displayNumber public
Accumulator() clear()
public void clear() currentSum0
currentNumber0 displayNumber0
public void addDigit( int digit )
currentNumbercurrentNumber10digit
displayNumbercurrentNumber
35
Reinforcing the refactoring
  • There is an old programmers adage that states
  •         "There are only two numbers 1 and
    many"
  • Once you start to repeat code, it is time to
    start to think about refactoring and adding in a
    helper method.

36
Alternative structure of the program
  • The complete calculator consists of four
    classes.
  • AdderApp
  • AddingFrame
  • CloseableFrame
  • Accumulator

37
Alternative structure of the program
  • We can think of the relationships between these
    four classes as being narrow and deep
  • AdderApp creates an instance of AddingFrame which
    creates an instance of Accumulator.
  • This is a good example of data hiding since
    AdderApp doesnt know/care that there is an
    instance of the Accumulator class.

public class AdderApp public static void
main( String args ) AddingFrame f new
AddingFrame() f.show() // end main
// end class AdderApp
public class AddingFrame extends CloseableFrame
private Accumulator myAccumulator ...
public AddingFrame( ) // create
frame and accumulator myAccumulator new
Accumulator() ...
38
Alternative structure of the program
  • But another way to structure this program would
    be to create a relationship which is wide and
    shallow
  • AdderApp creates an an instance of Accumulator
    which it passes to an instance of AddingFrame.
  • public class AdderApp
  • public static void main( String args
    )
  • Accumulator a new Accumulator()
  • AddingFrame f new AddingFrame(a)
  • f.show()
  • // end main
  • // end class AdderApp
  • This is a good example of composition.
  • We emphasize that AddingFrame is composed of an
    Accumulator
  • This is a good example of writing code that is
    modular.
  • Now that we know the composition relation, we can
    compose solutions using variations of Accumulator.

39
CountedAccumulator Extension
  • Suppose we need a new kind of object, an
    Accumulator that counts how many operations it
    executes. Lets call this class
    CountedAccumulator.
  • It responds to all the same messages as a regular
    Accumulator and also responds to an
    operationsExecuted() message, by returning its
    count.
  • What changes would you need to make to
    Accumulator?

40
Adding Behavior to a Class
  • Any time that we need to add behavior to a class
    we have at least three options
  • Add code to the class itself, keeping the
    original class.
  • Copy all the old code into a new class and add
    code to this new class.
  • Create a subclass that extends the original
    class' behavior.

41
Pros and Cons
  • Add code to the class itself, keeping the
    original class.
  • Pros Quick. Convenient. Simple.
  • Cons May change the behavior of the class.
    Thus, it isnt always an option.

42
Pros and Cons
  • Add code to the class itself, keeping the
    original class.
  • Pros Quick. Convenient. Simple.
  • Cons May change the behavior of the class.
    Thus, it isnt always an option.

43
Pros and Cons
  • Add code to the class itself, keeping the
    original class.
  • Pros Quick. Convenient. Simple.
  • Cons May change the behavior of the class.
    Thus, it isnt always an option.

44
Pros and Cons
  • Copy all the old code into a new class and add
    code to this new class.
  • Pros Quick. Convenient. Simple.
  • Cons Duplicated code. Error trap! Error trap!

45
Pros and Cons
  • Copy all the old code into a new class and add
    code to this new class.
  • Pros Quick. Convenient. Simple.
  • Cons Duplicated code. Error trap! Error trap!

46
Pros and Cons
  • Copy all the old code into a new class and add
    code to this new class.
  • Pros Quick. Convenient. Simple.
  • Cons Duplicated code. Error trap! Error trap!

47
Pros and Cons
  • Create a subclass that extends the original
    class' behavior.
  • Pros Doesnt break existing code. Virtually
    eliminates duplicate code. Provides the most
    flexibility.
  • Cons Slightly more time consuming.

48
Pros and Cons
  • Create a subclass that extends the original
    class' behavior.
  • Pros Doesnt break existing code. Virtually
    eliminates duplicate code. Provides the most
    flexibility.
  • Cons Slightly more time consuming.

49
Pros and Cons
  • Create a subclass that extends the original
    class' behavior.
  • Pros Doesnt break existing code. Virtually
    eliminates duplicate code. Provides the most
    flexibility.
  • Cons Slightly more time consuming.

50
Developing an Extended Class
  • There are typically four steps in developing an
    extended class.
  • declare the class
  • declare the new data
  • create the constructors  
  • adjust the methods

51
Developing an Extended Class
  • declare the class
  • public class CountedAccumulator extends
    Accumulator

52
Developing an Extended Class
  • declare the new data
  • private int numberOfOperations

53
Developing an Extended Class
  • create the constructor        
  • public CountedAccumulator ()
  • super()
  • numberOfOperations0

54
Developing an Extended Class
  •   Leave inherited methods alone
  • clear() and prepareForNextNumber() are both
    inherited from Accumulator and there is no need
    to change them.

55
Developing an Extended Class
  • Modify/Override inherited methods
  • plus() and minus() are inherited, but they don't
    do what we want them to. 
  • We can make them do more without completely
    replacing the code however.
  • public void plus()
  • super.plus()
  • numberOfOperations

56
Developing an Extended Class
  • Add completely new methods
  • We need an accessor method for numberOfOperations
  • public void operationsExecuted()
  •         return numberOfOperations

57
CountedAccumulator Solution
  • public class CountedAccumulator extends
    Accumulator
  • private int numberOfOperations
  • public CountedAccumulator()
  • super() // calls the superclass
    constructor
  • numberOfOperations0
  • public void plus()
  • super.plus()
  • numberOfOperations
  • public void minus()
  • super.minus()
  • numberOfOperations
  • public int getOperations()

58
CountedAccumulator Solution
  • Now, before we can really work with this we need
    to modify other files in our application. 
  • We need to set up the AddingFrame so that it
    works with a CountedAccumulator rather than a
    regular Accumulator.  We do this in the AdderApp
    class for simplicity.
  • Accumulator a new CountedAccumulator()
  • AddingFrame f new AddingFrame(a)

59
A solution
  • Why do we do this in the AdderApp rather than
    leave it alone and modify the AddingFrame? 
  • Because in the end this makes our AddingFrame
    slightly more versatile. 
  • Think about it...AddingFrame works with an
    Accumulator (or CountedAccumulator).  If one is
    provided, it uses it.  If one is not provided, it
    creates it. 
  • THAT, is more versatile than telling an
    AddingFrame to now always create a
    CountedAccumulator.

60
A solution
  • Now we can run this...
  • Notice that we have basically returned to having
    a Accumulator.  Why?
  • Notice that even though I have private data and
    methods in Accumulator, I didn't have to change
    this here.  Why?

61
A solution that USES the counting functionality
  • If we want to actually use the functionality of
    this new class, then something needs to call the
    new method in CountedAccumulator.
  • Without discussing the details of exception
    handling, we could do this by writing
  • try Thread.sleep(10000)
    catch(Exception e) System.out.println("Perfo
    rmed a.getOperations()"operations")

62
Another Exercise
  • Create a class named EvenOddAccumulator that
    subclasses Accumulator to implement this
    behavior.
  • EvenOddAccumulators respond to all the same
    messages as regular Accumulators. But, in
    response to plus() and minus() messages, an
    EvenOddAccumulator both computes the new sum and
    writes a congratulatory message if the sum is
    even.

63
Toward a Solution
  • Here is the critical new piece of the
    EvenOddAccumulator class
  • if ( currentSum 2 0 )
  • System.out.println( "Hurray! You made an even
    number." )
  • The big question is, what else is a part of the
    class?

64
Toward a Solution
  • Lets look at one version of this

65
A Problem Accessing Inherited Data
  • javac EvenOddAccumulator.java
  • EvenOddAccumulator.java17 currentSum
  • has private access in Accumulator
  • if ( currentSum 2 0 )
  • EvenOddAccumulator.java24 currentSum
  • has private access in Accumulator
  • if ( currentSum 2 0 )
  • 2 errors
  • Oops!
  • currentSum is declared as a private instance
    variable in class Accumulator.
  • private means private no code outside the
    Accumulator class can access that variable.

66
A Possible Solution for Accessing Inherited Data
  • Change currentSum to be public or protected.
  • public class Accumulator
  • protected int currentSum
  • ...

67
A Better Solutionfor Accessing Inherited Data
  • (2) Add a protected accessor method to the
  • Accumulator class. Use that method to access the
  • currentSum instance variable in the subclass.
  • public class Accumulator
  • ...
  • protected int currentSum()
  • return currentSum
  • Then use currentSum() in EvenOddAccumulator.

68
Programming with Inheritance
  • Inheritance is an object-oriented programming
    construct that enables us to add behavior to an
    existing system without modifying the existing
    classes.

69
Programming with Inheritance
  • Our new EvenOddAccumulator class adds behavior to
    a program that uses Accumulators without
    modifying
  • the behavior of the existing Accumulator class or
  • the existing AddingFrame class!
  • That means...
  • No chance of introducing an unnecessary,
    unexpected errors into the working Accumulator
    class.
  • No need to modify programs that use instances of
    Accumulator but which dont need instances of
    EvenOddAccumulator.
  • The ability to use EvenOddAccumulators in
    programs that expect to use Accumulators.

70
Programming with Inheritance
  • We could have achieved some of these results
    without using inheritance by creating a new class
    named EvenOddAccumulator that simply duplicated
    the behavior of existing Accumulator class.
  • Using inheritance means that...
  • No need to reimplement existing methods.
  • No need to duplicate code.
  • One of the most important features of
    object-oriented programming is that it encourages
    us to create new classes that reuse existing code
    as much as possible. Without inheritance, you
    have only one tool for doing that, composition.
    With inheritance, you have two tools.
Write a Comment
User Comments (0)
About PowerShow.com