Before proceeding, finish up the previous lab and be sure that you have handed it in.
This lab continues working with classes from the
Java Collections framework
(ArrayList
, HashMap
, HashSet
,
and Iterator
), along with introducing the
StringTokenizer
class. You'll be creating a
new version of the program that you wrote for the last lab.
In the code from the last lab, note how you did the following things:
Iterator
generic class explicitly in order
to step through the items in an ArrayList
or a
HashMap
's set of keys;
compareTo()
method for the class
SIPair
, so that it would implement the
Comparable
interface; and
Collections.sort()
to sort
an ArrayList
of SIPair
s.
Make sure you understand what you had to do for each of these things.
Also make sure that all of your changes are committed to your Mercurial repository.
for-each
loopCopy the FileProcessor.java
code to make a new class
FileProcessor2
. To do that, first use hg
copy
to copy it to a new file, then edit that file and change
its class name to match the file name.
In the previous lab, you stepped through collections by explicitly
creating an instance of Iterator
and calling its
hasNext()
and next
methods. That pattern of
access is common enough that Java provides a special version of the
for
statement to do it. For any iterable collection
coll
with an element type T
, you can write a
loop as
for (T x: coll) { process element x }
Because the body is executed for each element in the collection,
this is usually called a for-each loop. Note that
coll
has to be something that has a method
iterator()
.
Rewrite each of your for
loops that processes a
collection to use a for-each loop. (You need to be careful
with your HashMap
, because you can't iterate over the map
itself.)
Test your new program and commit it to the repository.
You were provided with a class FileAux
with a method
fileToWords()
to do the initial processing of the file input.
You are now going to write your own method to do that, using
the file input classes that were introduced yesterday.
Create a file FileWords.java
that includes a
declaration of a static method fileToWords()
that will be
able to take the place of the one that was provided to you. You can
figure out its parameter types and return type from where it will be
called in FileProcessor2
.
Tell Mercurial about this new file:
hg add FileWords.java
Now you need to fill in your new method. It needs to
open the named file and make a Scanner
for it, then read
and process each line from the file. The processing for each line
involves splitting it into words and adding each of those words to the
ArrayList
that will be returned.
It probably makes sense to write this and test it in
stages. You can do the testing by writing a main()
method in
the new class. I'd suggest first getting the file opened and read
(and print) each line from it. Then go back and set up the list, add
each line to it, and print the entire list at the end. Then worry
about the inner loop that does the breaking a line into words.
Tips:
FileInputStream
throws a
FileNotFoundException
, which you will have to catch.
If the open fails, it is reasonable to print a message and then call
System.exit(1)
to end the program.
StringTokenizer
to break up each line. The set of characters to use as separators is
digits, space, and the following punctuation:
!()-;:",.'?Note that at least one of those characters will need to be escaped to put it inside a string literal.
Once you have that working, commit it to your repository. Fix the
call at the beginning of main()
to call your method
If you think about how the apostrophe (single quote) is used in English, it is not always correct to use it to split words: we should treat contractions (such as "don't") and possessives (such as "God's") as single words. The method you were orginally provided does that, but the one you have written does not.
To fix that behavior, you need to take the single-quote out of the set of delimiters. But then it behaves oddly when used as a quotation mark. So the answer is to not treat it as a delimiter, but to put in an explicit test that strips off a single-quote that either begins or ends a token.
Make that fix. Test it and make sure that it is working, and commit it to your repository.
Make a typescript showing your program FileProcessor2
running on one of the sample files given.
Turn in your source files and typescript with a command like
/cslab/class/csci235/bin/handin lab13 *.java typescript