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 of String values
    • Let name1 be the result of trimming the first String (at array index 0)
    • Let name2 be the result of trimming the first String (at array index 1)
    • Create an empty list of sets of String values called changed, 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 or name2, but they match each other
      • Create a new TreeSet of String values
      • Put name1 and name2 into it
      • Add this new set to sets
    • Otherwise:
      • Get the first set in changed and call it result
      • Loop through the remaining sets in changed:
        • For each one of these sets, put everything inside it into result, using the addAll() method
        • Then, remove each of these sets from sets, since its contents have been merged with results
  • 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.