CSE 331�Software Design & Implementation
Spring 2026
Section 7 – Generics
Administrivia
Type Bounds
Upper Bound: extends
Lower Bound: super
Type Constraints: Extends
Ex:
List<? extends Unicorn> unicorns = new ArrayList<Unicorn>()
unicorns = new ArrayList<Rarity> // okay!
unicorns = new ArrayList<RainbowDash> // error!
Pony
RainbowDash
Unicorn
Rarity
Type Constraints: Super
Ex:
List<? super Unicorn> ponies = new Arraylist<Pony>()
ponies = new ArrayList<Rarity> // error!
ponies = new ArrayList<Pony> // ok!
Pony
RainbowDash
Unicorn
Rarity
Type Constraints on Methods
Code can only use methods from type bounds
Ex:
class PinkyPie<E extends Pony>{
public string magic(E arg) {
return arg.magic(); // error! (Pony not guaranteed to magic())
}
}
class Twilight<E extends Unicorn>{
public string magic(E arg) {
return arg.magic(); // okay! (Unicorn is guaranteed to magic())
}
}
Pony
RainbowDash
Unicorn
Rarity
Task 1 – We Game To Please
class Game {..}
class CardGame extends Game {..}
class VideoGame extends Game {..}
class GoFish extends CardGame {..}
For each line of code below, state whether the call is legal or illegal. If it is illegal, briefly explain why.
Object this;
Game game; List<Game> games;
CardGame cardGame; List<? extends CardGame> cardGames;
VideoGame videoGame; List<VideoGame> videoGames;
GoFish goFish; List<? super GoFish> goFishGames;
Generics
class MySet<T> { // generic class
private List<T> list;
private T lastAccessed;
…
}�
// generic method
static <T extends Number> double sum(List<T> list) {
double result = 0;
for (T n : list) {
result += n.doubleValue(); // Legal since T extends Number
}
return result;
}
Wildcards: ?
?: Concise way of writing some generics
? vs Object:
Generics: T vs ?
Ex:
Both of these functions are equivalent:
If you want both lists to have the same type, you must use T:
Generic Method Declarations
Strength rules:
Generics Control Strength
When comparing declarations, ask:
If yes, it is stronger. (weaker precondition)
Guidelines:
If neither allows strictly more calls or has stronger guarantees → incomparable
Task 2 – A Compare To Remember
Answer each of the following questions about generic method declarations.
a) Consider the following alternative method declarations:
A: int find(Collection<?> sub, Collection<?> list)
B: int find(Collection<Object> sub, Collection<Object> list)
C: <T> int find(Collection<T> sub, Collection<T> list)
D: <T> int find(Collection<? extends T> sub, Collection<? super T> list)
a) Is A stronger, weaker, or incomparable to B? Briefly explain your answer:
b) Is A stronger, weaker, or incomparable to C? Briefly explain your answer:
c) Is B stronger, weaker, or incomparable to C? Briefly explain your answer:
d) Is C stronger, weaker, or incomparable to D? Briefly explain your answer:
Task 2 – A Compare To Remember
b) The following type declaration is legal, but probably does not make sense. Why not? Collection<? extends Comparable<?>>
Task 3 – Nothing Is Certain But Death and Maxes
Revisit the specification of MutableIntSet. We are adding a max operation to the ADT that finds the largest element in the set.
/**
* Returns the largest value in the set, which must be non-empty.
* @requires len(this) != 0
* @return the largest integer in the set
*/
public int max();
In this problem, we will change the interface to store data other than integers by introducing a type parameter T for the type of data stored in the set.
Task 3 – Nothing Is Certain But Death and Maxes
Revisit the specification of MutableIntSet. We are adding a max operation to the ADT that finds the largest element in the set.
/**
* Returns the largest value in the set, which must be non-empty.
* @requires len(this) != 0
* @return the largest integer in the set
*/
public int max();
b) What bounds should we put on T?
Task 3 – Nothing Is Certain But Death and Maxes
Revisit the specification of MutableIntSet. We are adding a max operation to the ADT that finds the largest element in the set.
c) Next, we will make the change. Make MutableIntSet into a generic interface MutableSet that can store other types of data.
Task 3 – Nothing Is Certain But Death and Maxes
Revisit the specification of MutableIntSet. We are adding a max operation to the ADT that finds the largest element in the set.
d) Do the documentation/specifications still make sense? If not, what do we need to fix?
End
Please turn in your half-sheets!