Generic Classes
Goals
- Understand that a generic class is a polymorphic class. It can take many forms because it can work with a variety of types.
- Learn how to use and create generic classes.
Overview
- Demo #1: we provide a simple generic class,
Pair, and show you how to use it.
- Exercise #1: we ask you to write a generic class called
Triplet, similar to Pair.
- Exercise #2 (challenge problem): we ask you to complete a generic
Dictionary class, which operates on keys and values.
Demo: A Generic Pair Class
We will work with a Pair class. A Pair can hold a pair of any two things of the same (non-primitive) type.
For example, we can create a Pair of Strings, or a Pair of Widgets.
- Download Pair.java
- In the class header:
public class Pair<Element>{
The word Element inside the angle brackets is simply a placeholder for a type. Instead of using the word Element throughout the code, we could have used E or Stuff or any number of words.
- Example of a Pair of Strings:
> Pair p1 = new Pair("hello", "world");
> p1
[hello, world]
> p1.swap();
> p1
[world, hello]
- WARNING: The DrJava Interactions Pane does not handle generics well. The interactions pane will in many cases give false results. (We got lucky that the example above worked.) We recommend that when coding with generics, that you create a test class. (Use compiled, not interpreted code). We demonstrate how to do this next.
- Download and compile Widget.java and PairTest.java.
- Run the test code, which swaps a Pair of Strings and then swaps a Pair of Widgets:
> java PairTest
Before swap():
[hello, world]
After swap():
[world, hello]
Before swap():
[50, 100]
After swap():
[100, 50]
- Notice that the Pair class works equally well for Strings and Widgets, as it will for any non-primitive type.
- Warning: Here is some code that should, but does not work in the interactions pane. (The DrJava interprter can't figure out, at runtime, the return type of getFirst(..) becuase it is a generic type, so it assumes its return type is Object. But Object does not have a getNum() method.):
> Pair<Widget> p = new Pair<Widget>(new Widget(50), new Widget(100));
> p.getFirst().getNum()
Error: No 'getNum' method in 'java.lang.Object' with arguments: ()
Exercise #1: A Generic Triplet Class
Create a generic class called Triplet which is similar to pair except that it holds three things. Instead of a swap() method, the Triplet
class should have the method shiftLeft() that behaves as shown below. Download TripletTest.java to test it.
> java TripletTest
Before shiftLeft():
[hello, there, world]
After shiftLeft():
[there, world, hello]
Before shiftLeft():
[25, 50, 100]
After shiftLeft():
[50, 100, 25]
Exercise #2 (Challenge Problem): A Generic Dictionary Class
Here we work with a dictionary that contains (key, value) pairs. Download:
Compile the files. Run the DictTest test program (java DictTest), which should print
harry
16
The supplied Dict class stores just one value for every key,
regardless of how many entries with a given key are added. Leaving the Entry class as-is,
modify the Dict class so that for each key it stores a List of values,
which the lookup method returns. Download DictSltnTest.java.
It should produce the following output:
> java DictSltnTest
harry
hermoine
ron
16
17
15