Lab 11: Alias Grace
Due by midnight tonight
An alias is another name that a person might use. For example, Lewis Carroll is the well-known alias of Charles Lutwidge Dodgson. The lab today will read a list of aliases from a file and merge them so that all the aliases for a single person can be listed at once.
This lab will use the ArrayList
class, which implements the List
interface, and the TreeSet
class, which implements the Set
interface. Classes that implement the List
interface are useful because they allow us to store an ordered collection of items where repetition is possible. Likewise, classes that implement the Set
interface are useful in slightly different circumstances because they allow us to store an unordered collection of items where repetition is impossible.
The basic idea behind this lab is to build up our sets so that a given set will contain all the aliases for a single person. Each line of a file will contain two names. If we find a set that contains one of the existing names, we add the other name to it and add that set to a list of changed sets. After processing the two names, there will be a list of affected sets, all of which must contain aliases for the same person. Thus, we should put everything from all of those sets into the first affected set and remove the rest from our list of sets, since they're redundant.
Specification
Create a project called Lab11
. Add a class called Aliases
.
The program expects a text file where each line has a name, a colon, and another name. There might be extra white space around the colon, and each name might contain whitespace or other punctuation as well. Below we provide a file listing aliases. Right-click on the link below and save it into your project folder Lab11
(but not in the src
or bin
sub-folders).
All of the functionality for this lab can be completed in one large main()
method divided into three sections. First, we must open the file listing all the aliases. Second, we must read in each line, defining a new alias, and check our sets of aliases to see which should be updated. Last, we print out each set of aliases, revealing all the aliases each person has.
Opening the file
Declare a Scanner
named file
and initialize it to null
. As with other file exercises, run a while
loop as long as file
is null
. Prompt the user ("Enter file name: "
), read in the next line of input, and try to open a Scanner
built from a File
with the name specified. Enclose the input and Scanner
creation inside a try
block with a catch
block that catches a FileNotFoundException
and prints "Invalid file."
Processing the aliases
With the file open, we now need a place to store all the aliases. Declare a list of sets of String
values as follows.
List<Set<String>> sets = new ArrayList<>();
Then, follow these steps:
- As long as
file
has another line to read: - Read a line
- Use the
split()
method to split the line on":"
, which is what's used to separate the two names - The
split()
method returns an array ofString
values - Let
name1
be the result of trimming the firstString
(at array index 0) - Let
name2
be the result of trimming the firstString
(at array index 1) - Create an empty list of sets of
String
values calledchanged
, using syntax as shown above - Iterate over all the sets in
sets
- If a set contains
name1
- Add
name2
to the set - Add the set to
changed
- Otherwise, if a set contains
name2
- Add
name1
to the set - Add the set to
changed
- If there's nothing in
changed
: - No existing sets contained either
name1
orname2
, but they match each other - Create a new
TreeSet
ofString
values - Put
name1
andname2
into it - Add this new set to
sets
- Otherwise:
- Get the first set in
changed
and call itresult
- Loop through the remaining sets in
changed
: - For each one of these sets, put everything inside it into
result
, using theaddAll()
method - Then, remove each of these sets from
sets
, since its contents have been merged withresults
- Close
file
Printing out the unified aliases
The hard work is done. You have a list of sets where each set contains all the known aliases for a particular person.
First print out Aliases
and then a blank line. Then, loop over all the sets in sets
. For each one, print out the current index of the set (plus 1, to be more human-readable). Finally, print out each String
in a given set, with " AKA "
in between.
Printing these AKAs correctly is a small challenge, since we want to print one fewer AKA than aliases. The trick I recommend is to set a variable called first
to true
before looping through the names. Inside the loop, if first
is true
, set it to false
. Otherwise, print out " AKA "
. Either way, print the name. This approach prints an " AKA "
before every name except the first, which has the effect of putting them between each pair of names.
Sample Output
Here is sample output for a program that reads from the provided file aliases.txt
. Your output should match as closely as possible.
Enter file name: aliases.txt Aliases 1. GZA AKA Gary E. Grice AKA The Genius 2. Jimmy the Octopus AKA Slick James 3. Billy the Kid AKA Henry McCarty AKA William H. Bonney 4. Clifford Smith AKA Method Man AKA Tical 5. Prince Rakim AKA RZA 6. Clark Kent AKA Superman 7. Dennis Coles AKA Ghostface Killah AKA Tony Starks
Turn In
Turn in your code by uploading Aliases.java
from the Lab11\src
folder inside your workspace folder to Blackboard. Do not upload the entire project. I only want the Aliases.java
file.
All work must be done individually. Never look at someone else's code. Please refer to the course policies if you have any questions about academic integrity. If you have trouble with the assignment, I am always available for assistance.