Summary

PECS

  • producer extends; consumer super
  • when to use the upper/lower bounded wildcards
  • producer can produce T so it can produce any subtype, since the base information is still there
  • consumer can store T so it can store any supertype,

Upper-bounded wildcard

  • ? can be substituted for a subtype of T
  • mimicking covariance
java
L<? extends A>

extends.png

Lower-bounded wildcard

  • ? can be substituted for a supertype of T
  • mimicking contravariance
java
A<? super T>

super.png

Concept

Java generics classes are invariant

Unbounded wildcard

  • ? can be substituted for any type
java
L<?>

Diamond operator

  • not a rawtype, has angled brackets
  • makes code less verbose
  • Java will figure out what types to put in
java
L<A> a = new L<>();

Type inference

  • infer type argument automatically
  • if there are multiple, pick the most specific one

Application

Sequence, copying

java
class Seq<T> {
	...

	public void copyFrom(Seq<? extends T> src) { // accepts all Seq<S> where S<:T
		int len = Math.min(this.array.length, src.arracy.length);
		for (int i = 0; i < len; i++ ) {
			this.set(i, src.get(i)); // src is used to produce, hence extends
		}
	}

	public void copyTo(Seq<? super T> dest) { // accepts all Seq<S> where T<:S
		int len = Math.min(this.array.length, src.arracy.length);
		for (int i = 0; i < len; i++ ) {
			dest.set(i, this.get(i)); // something is done to dest, dest consumes, hence super
		}
	}
}

// Circle <: Shape
Seq<Shape> shapes = new Seq<>(1);
Seq<Circle> circles = new Seq<>(1);

shapes.copyFrom(circles); // works, Seq<Circle> <: Seq<? extends Shape>
shapes.copyTo(circles);   // error, Seq<Circle> </: Seq<? super Shape>

circles.copyFrom(shapes); // error, Seq<Shape> </: Seq<? extends Circle>
circles.copyTo(shapes);   // works, Seq<Shape> <: Seq<? super Circle>

Type inference, solve for constrains on T

java
...<T>
... boolean contains(T[] seq, T obj)

A.contains(stringArray, 123); // String[], Integer
java
... <T extends GetAreable>
... T findLargest(Seq<? extends T> seq)

Shape s = A.findLergest(new Seq<Circle>(0));
java
... <T extends GetAreable>
... T findLargest(Seq<? extends T> seq)

ColoredCircle s = A.findLergest(new Seq<Circle>(0));
java
... <S>
... boolean contains(Seq<? extends S> seq, S obj)

A.contains(shapeSeq, "Hello"); // Seq<Shape>, String