Today’s lab will be a review of topics covered in Unit 3. We will focus on the topics that were introduced for the first time in this unit, to reinforce your skills in preparation for your exam.
Because there is such a variety of topics in this unit, we will be creating methods for each topic, rather than a cohesive program. Refer to previous labs if you’d like to see more in-depth examples of the topic.
We have provided a constructor and toString for the Review class that will do much of the work for you when testing these methods. The order of method calls in the constructor is intentional, so be careful if making any modifications to test incrementally.
Use the ReviewMain class to test your methods in both the Review and ReviewChild classes.
Step 1: File Output - Review.writeFile()
You have worked with file input and output previously. Recall that when reading from a file, we can use a Scanner, and when writing to a file, we can use a printWriter.
Both of these tools are objects that the Java language conveniently provides to us, but remember that to use them, we must include the appropriate import statements at the top of the class.
In this method, called writeFile, you will be writing to a file based on a decoded string, given to you by the returned String from the convertString method.
The method writeFile takes two parameters, a string s and a string outfile. String s holds the decoded string, and the string outfile holds the name of the file you will be writing to.
Using a try-catch block, create a PrintWriter object that writes to the file given by the file name in the String parameter.
Then, write the string given to the writeFile method.
Don’t forget to close the print writer, or your changes to the output file won’t show!
Step 2: More Branching - Review.convertString()
In this unit, we expanded our knowledge of branching to include switch statements. You will be using this knowledge to create a switch statement in the convertString method of the Review class.
This method works to finish decoding the partially decoded string from the readFile method using a switch statement. Review the code provided to you in the readFile method for an example illustrating the functionality of a switch statement.
The convertString method takes a single string as a parameter, and uses a StringBuilder object to concatenate a new string that is fully decoded. The method iterates through the string using a for loop, and you will be responsible for checking each character in the string, and appending the corresponding character to the new string, based on the following cases:
- If the character in the original string is a ‘.’, add a space character to the new string.
- If the character in the original string is a ‘/’, add a period character to the new string.
- If the character in the original string is a ‘-‘, *append the following character to the new string, but convert it to uppercase.
- Otherwise, as long as the character isn’t preceded by a ‘-‘ character, add it as is to the new string.
For example, if the original string includes “abc/.-d”, the new string would be “abc. D”.
Step 3: Recursion - Review.reverseList()
In the reverseList method of the Review class, you will be reversing a list recursively.
The method has two parameters, an ArrayList of characters called list, and ArrayList of characters called reversedList. Remember that the two Array Lists are objects that are passed into methods by reference, so we don’t need to worry about a return type. If we modify and add elements to the reversedList, and remove elements from the original list, those changes will be reflected everywhere that list exists by its reference, even outside the method.
For that reason, we’ve given you two helper methods - initializeList and copyList.
The initializeList method will allow you to initialize an ArrayList of characters based on a string passed into the method. We can use this method to initialize a list from a string like the one returned by the convertString method from earlier.
The copyList method allows us to copy the elements of one list to another. This is helpful in our case, since our recursive method will remove characters from our original list when reversing it. The Collections class has methods that sort and copy objects that would be useful for similar purposes to today’s lab, but we want to be clearly identify what’s actually happening when we modify these ArrayLists, and practice with them alongside recursion.
Now that we’ve set the foundation for the reverseList method, let us talk about how it will actually work.
The method takes two parameters that are ArrayLists, and places the elements in the original list into the reversed list in opposite order.
It operates recursively, which means that it has a base case, and a recursive case, and will call its own method again in the recursive case.
We will give you the recursive case, and challenge you to consider the base case - how we know when to stop continuously calling the method.
- Add the last element of the original list to the reversed list.
- Remove the last element of the original list from the original list.
- Call reverseList() again with the newly modified lists.
Step 4: Inheritance - ReviewChild.reverseList()
In this method reverseList we will be practicing with inheritance, specifically by defining a derived class and overriding a method.
Ensure that the ReviewChild class inherits from the Review class. What keyword should you use in the class declaration?
Now, define a method with an identical signature to the Review method reverseList().
This method will be performing the same function as its parent class’s method, but instead of performing it recursively, it will perform it iteratively.
Use a loop to iterate from the last element in the original list, adding element by element to the reversed list.