Worksheet: J3 | CS 2113 Software Engineering - Fall 2021

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.

Questions

  1. Consider the class declearation 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?

    Reveal Solution

  2. What are some of the functional differences between an abstract class and an interface? Use the example below to answer this question.

    public abstract class Employee {
        // ...
    }
    
    // vs.
    
    public interface Employee {
        //...
    }
    

    Reveal Solution

  3. Suppose you have interfaces Adder and Multiplier:

    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 and FloatCalculator 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.
    }
    

    Reveal Solution

  4. Read about the ArrayList class provided in the Java util package.

    • Provide a one paragraph description of an ArrayList implementation in Java.
    • Draw a UML diagram of ArrayList to Object.
    • What is ArrayList’s direct ancestor class?
    • What interfaces does ArrayList implement?
    • Choose one of the interfaces and explain what property of the class come from that interface.

    Reveal Solution

  5. Read about the Hashtable class provided in the Java util package.:

    • Provide a one paragraph description of a Hashtable implementation in Java.
    • Draw a UML diagram of Hashtable to Object.
    • What interfaces does Hashtable implement?
    • Do any other classes in the Java util realize a Dictionary and a implement a Map?
    • Choose one of the interfaces and explain what property of the class come from that interface.

    Reveal Solution

  6. Read about the TreeMap class provided in the Java util package.

    • Provide a one paragraph description of a TreeMap implementation in Java.
    • Draw a UML diagram of TreeMap to Object.
    • What is TreeMaps’s direct ancestor class?
    • What interfaces does TreeMap implement?
    • Choose one of the interfaces and explain what property of the class come from that interface.

    Reveal Solution

  7. 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.html

    When would it be preferable to use a LinkedHashSet instead of a HashSet?

    Reveal Solution

  8. Modify the code below to use Java generics. Your code should not need casting, remove 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);
        }
    }
    

    Reveal Solution

  9. 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.

    Reveal Solution

  10. What is the output of this program? Please explain.

    public class TestHashMap {
    
        public static void main(String[] argv) {
            // Create a new hashtable.
            HashMap<String, Integer> carsTable = new HashMap<String, Integer>();
    
            // Insert key and value pairs
            carsTable.put("Lamborghini", 225);
            carsTable.put("Porsche", 202);
            carsTable.put("Jeep", 110);
            carsTable.put("Mustang", 144);
            carsTable.put("Jeep", 90);
    
            Integer topSpeedOfJeep = carsTable.get("Jeep");
            System.out.println(topSpeedOfJeep);
        }
    }
    

    Reveal Solution

  11. 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);
        }
    

    Reveal Solution

  12. 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[];
       }
    }
    

    Reveal Solution

  13. Finish the main method in the TestShelf 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.
    
    
        }
    }
    

    Reveal Solution

  14. 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 push(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.push(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.

    Reveal Solution

  15. Continuing with the example above, explain why expanding LinkedList to implement Iteraable solves the inefficiency problem you described above.

    Reveal Solution

  16. 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;
            }
        }
    }
    

    Reveal Solution

  17. Explain why the Comparable interface is an interface rather than class?

    Reveal Solution

  18. Add the compareTo method in the Car 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>.
    
    }
    
    

    Reveal Solution

  19. Find a natural hierarchy Object-Oriented relationship, such as the GWPerson, GWFaculty, GWStudent and GWStaff relationship. Develop an OOP design for these this natural hierarchy and label items as class, abstract classes, and interfaces. Provide a UML diagram and one paragraph describing the relationships.

    Reveal Solution