session 4 command-line arguments, strings, and files
TRANSCRIPT
Options for User Input
• Options for getting information from the user– Write event-driven code
• Con: requires a significant amount of new code to set-up• Pro: the most versatile.
– Use System.in• Con: less versatile then event-driven• Pro: requires less new code
– Use the command line (String[ ] args)• Con: very limited in its use• Pro: the simplest to set up
Using the command line
• Remember what causes the “big bang” in our programs?
public static void main (String [] args) {
• main expects an array of strings as a parameter.
• The fact of the matter is that this array has been a null array in each of our programs so far.
Using the command line
• However, we can give this array values by providing command line arguments when we start a program running.
$ java MyProgram String1 String2 String3
args[0] args[1] args[2]
Fixing this problempublic class MyEcho2 {
public static void main( String[] args ) {
if (args.length == 2) {
System.out.println("args[0] is ” + args[0]);
System.out.println("args[1] is " + args[1]);
} else {
System.out.println( "Usage: java MyEcho2 "
+ "string1 string2");
} // end if
} // end main
} // end MyEcho2
$ java MyEcho2 Mark
Usage: java MyEcho2 string1 string2
$ java MyEcho2 Mark Alan Fienup
Usage: java MyEcho2 string1 string2
Your turn to write a simple program using the command line
• Write a program to echo all command-line arguments to System.out$ java EchoAll This is a long line
args[0] is This
args[1] is is
args[2] is a
args[3] is long
args[4] is line
First Attempt - What’s wrong?public class Calculate {
public static void main( String[] args ) {
int operand1 = args[0];
String operator = args[1];
int operand2 = args[2];
if ( operator.equals("+") ) {
System.out.println( operand1 + operand2 );
} else if ( operator.equals("-") ) {
System.out.println( operand1 - operand2 );
} else {
System.out.println("Invalid operator: " + operator);
} // end if
} // end main
} // end Calculate
$ javac Calculate.java
Calculate.java:3: incompatible types
found : java.lang.String
required: int
int operand1 = args[0];
^
Correct Calculatepublic class Calculate {
public static void main( String[] args ) {
int operand1 = Integer.parseInt( args[0] );
String operator = args[1];
int operand2 = Integer.parseInt( args[2] );
if ( operator.equals("+") ) {
System.out.println( operand1 + operand2 );
} else if ( operator.equals("-") ) {
System.out.println( operand1 - operand2 );
} else {
System.out.println( "Invalid operator: "
+ operator );
} // end if
} // end main
} // end Calculate
The wrapper classes
• Primitive data types (int, double, boolean, etc.) are not actually objects. Because of this, you can’t use them easily in certain OO situations
• Therefore, Java has “wrapper classes” such as Integer, Double, and Boolean.
• These are true classes in the OO sense of the word since they contain data which store information (often the value in it’s corresponding primitive data type) and methods that can act on this data.
But wait a minute!
• How is it that we can use the parseInt() method from the Integer class without actually creating an instance of Integer class.
Lifetime Modifiers
What does static mean?
• The item being declared is a feature of the class – what we usually call “class methods” or “class variables.”
• The item being declared exists at load time, before any instance is created.
Lifetime Modifiers
• A “class method” is one that can be invoked without sending a message to an instance of the class.
the main method of MemoPadApp
int operand1 = Integer.parseInt(args[0]);
double myRandom = Math.random();
Lifetime Modifiers
• A “class variable” is one that every instance has access to and shares.
In chapter 5, Budd creates windows in which bouncing balls live. Every instance of his BallWorld class shares the same height and width dimensions, implemented as static class variables:
public static int frameWidth=200;public static int frameHeight=250;
Lifetime Modifiers
• We will use these rarely in the code we write.– The more you use static stuff, the less flexible
and modifiable your code tends to be.
• The Java class library uses these more frequently. Budd will use them occasionally.– Thus, you will still get to see plenty of
examples before we are done!
Homework #2 – Constructors and Command-line Arguments
• Goals for this assignment: practice implementing constructors
practice factoring common behavior into helper methods
experience working with command-line arguments
• You will continue to work with the MemoPad program for this assignment, including the database class that you implemented for Homework 1
Homework #2 • For this homework, you will modify the
MemoPadApp class to accept some optional command-line arguments.
java MemoPadApp Use the original
DefaultMemoDatabase
java MemoPadApp –d Use the original
DefaultMemoDatabase
java MemoPadApp -s Use your original student
version of MyMemoDatabase
from homework 1
java MemoPadApp -s 100 Use your MyMemoDatabase
that is created by a new constructor that limits the database to the specified maximum size (in this example it is 100)
Homework #2 - Tasks1. Add a new constructor to your MyMemoDatabase class
that takes one argument: the maximum number of memos that can be stored.
2. Eliminate any code duplication in your MyMemoDatabase class's constructors.
3. Add a new constructor to the MemoPad class that takes one argument: the MemoDatabase that it uses to store the memos.
4. Change the original "default" constructor back to its original form, from before Homework 1: initialize the database variable to be a DefaultMemoDatabase.
5. Eliminate any code duplication in the MemoPad constructors.
6. Modify the main() method in the MemoPadApp driver to accept up to two optional arguments that control the kind of MemoDatabase to be used.
Homework #2 - Sample Executionsjava MemoPadApp MemoPadApp uses the
default constructor of MemoPad
java MemoPadApp -d MemoPadApp creates a DefaultMemoDatabase and passes it to the new MemoPad constructor that takes a MemoDatabase parameter
java MemoPadApp -s MemoPadApp creates an instance of your MyMemoDatabase (use default constructor) and passes it to the new MemoPad constructor
Homework #2 - Sample Executions– java MemoPadApp -s 100 MemoPadApp
creates an instance of your MyMemoDatabase using the new constructor that takes an int parameter, and then passes it to the new MemoPad constructor
Homework #2 - Sample Executions
• If the user gives any other command-line argument, print an error message and return without creating any objects. For example:
$ java MemoPadApp -oops
Usage: java MemoPadApp
java MemoPadApp -d
java MemoPadApp -s [size]
ExerciseComplete the “quick-and-dirty” class CharacterCounter
containing only a main() method that displays the number of non-space characters on the command line after the command. For example:
$ java CharacterCounter
0
$ java CharacterCounter a
1
$ java CharacterCounter a bc def ghij
10
CharacterCount template
public class CharacterCounter {
public static void main( String[] args ) {
int characterCount = 0 ;
} // end main
} // end class CharacterCounter
StringTokenizer
• Useful tool for processing a String object
• Allows you to sequentially walk down a String and extract “words”/tokens that are delimited by specified characters
• What delimiter normally aids us in parsing a long string into words?
StringTokenizer
General usage of a StringTokenizer:
– create one using a constructor that takes a string argument to process
– send one of two messages: hasMoreTokens() and nextToken
– use a stereotypical loop to process a sequence of strings
A default StringTokenizer uses spaces as delimiters.
StringTokenizer Exampleimport java.util.StringTokenizer;
public class EchoWordsInArgumentV1 {
public static void main( String[] args ) {
StringTokenizer words = new StringTokenizer(args[0]);
while( words.hasMoreElements() ) {
String word = words.nextToken();
System.out.println( word );
} // end while
} // end main
} // end class EchoWordsInArgumentV1
StringTokenizer Example$ java EchoWordsInArgumentV1 "StringTokenizer, please process
me."
StringTokenizer,
please
process
me.
• Notice the quotes (“”) in the command line so the whole string is read as args[0].
• The comma (“,”) and period (“.”)are part of the words and not delimiters by default.
StringTokenizer Example 2
• Fortunately, we can construct a StringTokenizer that uses specified characters for delimiters.
• The designer of the StringTokenizer was planning ahead for future usage!!!
$ java EchoWordsInArgumentV2 "StringTokenizer, please process me."
StringTokenizer
please
process
me
StringTokenizer Example 2import java.util.StringTokenizer;
public class EchoWordsInArgumentV2 {
public static void main( String[] args ) {
String delimiters = " .?!()[]{}|?/&\\,;:-\'\"\t\n\r";
StringTokenizer words = new StringTokenizer( args[0], delimiters );
while( words.hasMoreElements() ) {
String word = words.nextToken();
System.out.println( word );
} // end while
} // end main
} // end class EchoWordsInArgumentV2
Split – alternative to StringTokenizer
public String[] split(String regex) Splits this string around matches of the given regular expression. This method
works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
The string "boo:and:foo", for example, yields the following results with these expressions:
Regex Result : { "boo", "and", "foo" } o { "b", "", ":and:f" }Parameters:
regex - the delimiting regular expression Returns:
the array of strings computed by splitting this string around matches of the given regular expression
Throws: PatternSyntaxException - if the regular expression's syntax is invalid
Since:1.4
UNIX/Linux pipe
• “|” character on the command line• Allows the output of one program to be sent as
input to another program, like the UNIX “sort” utility.
$ java EchoWordsInArgumentV2 "StringTokenizer, please process me.” | sort
StringTokenizer
me
please
process
• Is this sorted? How can we fix this?
StringTokenizer Example 3import java.util.StringTokenizer;
public class EchoWordsInArgumentV3 {
public static void main( String[] args ) {
String delimiters = " .?!()[]{}|?/&\\,;:-\'\"\t\n\r";
StringTokenizer words = new StringTokenizer( args[0],
delimiters );
while( words.hasMoreElements() ) {
String word = words.nextToken();
word = word.toLowerCase();
System.out.println( word );
} // end while
} // end main
} // end class EchoWordsInArgumentV3
StringTokenizer Example 3$ java EchoWordsInArgumentV3 "StringTokenizer, please process me." | sort
me
please
process
stringtokenizer
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?
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 ...
Study Echo.java’s 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
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(args[0]) ); PrintWriter outputFile = new PrintWriter( new FileWriter( args[1] ) );
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