Appendix A. Generics and Java 8

Background

Generics capabilities were added in Java way back in version J2SE 1.5, but most Java developers only learned the minimum they needed to know about them to get the job done. With the advent of Java 8, suddenly the Javadocs are filled with method signatures like this one from java.util.Map.Entry:

static <K extends Comparable<? super K>,V> Comparator<Map.Entry<K,V>>
    comparingByKey()

or this one from java.util.Comparator:

static <T,U extends Comparable<? super U>> Comparator<T> comparing(
    Function<? super T,? extends U> keyExtractor)

or even this monster from java.util.stream.Collectors:

static <T,K,D,A,M extends Map<K, D>> Collector<T,?,M> groupingBy(
    Function<? super T,? extends K> classifier, Supplier<M> mapFactory,
    Collector<? super T,A,D> downstream)

Understanding the minimum isn’t going to be enough anymore. The purpose of this appendix is to help you break down similar signatures into understandable parts so that you can use the API productively.

What Everybody Knows

When you want to use a collection like List or Set, you declare the type of the contained elements by placing their class name in angle brackets:

List<String> strings = new ArrayList<String>();
Set<Employee> employees = new HashSet<Employee>();
Note

Java 7 made the syntax a bit easier by introducing the diamond operator used in the following code samples. Since the reference on the lefthand side declares the collection along with its contained type, like List<String> ...

Get Modern Java Recipes now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.