Worksheet: J3
Worksheets are self-guided activities that reinforce lectures. They are not graded for accuracy, only for completion. Worksheets are due by Sunday night before the next lecture.
- Github Classroom Link: https://classroom.github.com/a/DwSWNF2X
Note
Attempt to answer these questions before running the code. This will improve your ability to analyize and reason about code without an IDE or compiler. This skill we be helpful on the exams.
Questions
-
Consider the class declaration below:
// Is this possible? public class Lion extends Mammal, Carnivor { // ... }
- Explain why the following class declaration is not possible in Java.
- What are the limitations of the
extends
key word? - How can you accomplish this inheritance structure task in Java?
-
What are some of the functional differences between an
abstract class
and aninterface
? Use the example below to answer this question.public abstract class Employee { // ... } // vs. public interface Employee { //... }
-
Consider the interfaces for a
Stack
andQueue
ofint
s.public interface Stack{ public void push(int v); public int pop(); public int peek(); } public interface Queue{ public void enqueue(int v); public int dequeue(); public int peek(); }
Now suppose you had a
LinkedList
implementation to storeint
s with the following methods defined.public class LinkedList implements Stack, Queue{ public LinkedList(){/*...*/} public void addToFront(int v){/*...*/} public int rmFromFront(){/*...*/} public void addToBack(int v){/*...*/} public void rmFromBack(){/*...*/} //FINISH HERE }
Using those methods in
LinkedList
complete the realization of a Stack and Queue? -
Rewrite the
Stack
andQueue
interfaces from above to be generic, as well as theLinkedList
. Explain how this is now generic to manage collections of any class. -
Suppose you have interfaces
Adder
andMultiplier
:public interface Adder<T> { T add(T a, T b); }
public interface Multiplier<T> { T multiply(T a, T b); }
Finish the implementation of the
IntegerCalculator
andFloatCalculator
classes below.public class IntegerCalculator implements Adder<Integer>, Multiplier<Integer> { private String calculatorName; public IntegerCalculator(String calculatorName) { this.calculatorName = calculatorName; } public String getCalculatorName() { return calculatorName; } // TODO: add the methods needed to implement the adder and multiplier interfaces. }
public class FloatCalculator implements Adder<Float>, Multiplier<Float>{ private String calculatorName; public FloatCalculator(String calculatorName) { this.calculatorName = calculatorName; } public String getCalculatorName() { return calculatorName; } // TODO: add the methods needed to implement the adder and multiplier interfaces. }
-
Review the following Java util data structures:
For each,
- Provide a two-to-three sentence description of each class
- For each interface realized by these classes, also provide a two-to-three sentence description.
- Finally draw a UML diagram that connects all of these classes back to object
-
Take a look at the documentation for LinkedHashSet: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedHashSet.html
and HashSet:
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/HashSet.htmlWhen would it be preferable to use a LinkedHashSet instead of a HashSet?
-
The code below does not use Java generics. Update it to do so. Notably, there should not need casting, but no, the solution isn’t just removing the
(String)
casting before the.get
method.import java.util.HashMap; public class TestHashMap { public static void main (String[] argv) { // Create a new hashmap. Hashtable fabFour = new HashMap(); // Insert four key and value pairs. fabFour.put("John", "John Lennon"); fabFour.put("Paul", "Paul McCartney"); fabFour.put("George", "George Harrison"); fabFour.put("Ringo", "Ringo Star"); // Use a key to retrieve a value. String fullName = (String) fabFour.get("Ringo"); // Prints "Ringo Star" System.out.println(fullName); } }
-
Provide a 1-to-2 paragraph explanation for why we need Generics? You can use the sample code (above and below) to over this explanation.
-
What is “Erasure” with java generics?
For the code below, what does the code “erase” to?
public static void main(final String args[]) { Shelf<String> favorite_words = shelfBuilder(); favorite_words.addItem("Zoetrope"); favorite_words.addItem("Succinct"); //... String s = favorite_words.getItem(1); System.out.println(s); }
-
Why is the following code invalid in Java? Use the erasure to show why it fails after the generic is erased.
public class FooBarBaz<T>{ T array[]; public FooBarBaz{ array = new T[]; } }
-
Finish the
main
method in theTestShelf
class above.Expected output:
Shakespeare Characters: Hamlet Othello Cordelia Juliet Famous Integers: 13 23 42 1729
import java.util.ArrayList; import java.util.List; public class Shelf<T> { private List<T> shelfItems; private String shelfName; public Shelf(String shelfName) { this.shelfName = shelfName; shelfItems = new ArrayList<T>(); } public int addItem(T item) { shelfItems.add(item); return shelfItems.size(); } public void printShelf() { System.out.print(shelfName + ": "); for(T item: shelfItems) { System.out.print(item.toString() + " "); } System.out.println(); } }
public class TestShelf { public static void main(final String args[]) { // TODO: Create a shelf to store Shakespeare character names: // Hamlet, Othello, Cordelia, and Juliet // TODO: Then print the shelf. // TODO: Create a shelf to store famous integers: // 13, 23, 42, 1729, // TODO: Then print the shelf. } }
-
Consider the following code snippets for a
LinkedList
you may implement and a main method:public class LinkedList{ private class Node{ int data; Node next; } Node head; void add(int data); int get(int idx); //...
public class TestingLinkedList{ public class static main(String args[]){ LinkedList ll = new LinkedList(); for(int i=0;i<100000;i++){ ll.add(i*3); } for(int i=0;i<100000;i++){ System.out.println(""+ll.get(i)); //<-- MARK } } }
Explain why the line with
MARK
is extremely inefficient? Use Big-O to explain. -
Continuing with the example above, explain why expanding
LinkedList
to implementIterable
solves the inefficiency problem you described above. -
Finish the
main
method below to use the fibonacci iterator to print out the sequence:1 2 3 5 8 13 21 ...
import java.util.Iterator; class Fibonacci implements Iterable<Integer> { public static void main(final String args[]) { Fibonacci fibonacci = new Fibonacci(21); // TODO: Use the fibonacci iterator to print out the sequence: 1 2 3 5 8 13 21 } private int max; public Fibonacci(int max) { this.max = max; } public Iterator<Integer> iterator() { return new FibonacciIterator(); } private class FibonacciIterator implements Iterator<Integer> { int current = 1; int previous = 0; @Override public boolean hasNext() { return current + previous <= max; } @Override public Integer next() { int tmp = current; current += previous; previous = tmp; return current; } } }
-
Explain why the
Comparable
interface is an interface rather than class? -
Add the
compareTo
method in theCar
class above. So that the main method will print out:Name: Lamborghini Top Speed: 225 Name: Porsche Top Speed: 202 Name: Mustang Top Speed: 144 Name: Jeep Top Speed: 110
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Car implements Comparable<Car> { public static void main(String[] args) { List<Car> carsList = new ArrayList<>(); carsList.add(new Car("Porsche", 202)); carsList.add(new Car("Jeep", 110)); carsList.add(new Car("Mustang", 144)); carsList.add(new Car("Lamborghini", 225)); Collections.sort(carsList); for(Car car : carsList) { System.out.println("Name: " + car.getName() + " Top Speed: " + car.getTopSpeed()); } } private String name; private Integer topSpeed; public Car(String name, Integer topSpeed) { this.name = name; this.topSpeed = topSpeed; } public String getName() { return name; } public Integer getTopSpeed() { return topSpeed; } // TODO: Complete the Car class by adding the compareTo method // needed to correctly implement Comparable<Car>. }