Abstract: Java Generics and Collections is the "companion book" to The Java Specialists' Newsletter. A well written book that explains generics really nicely, including some difficult concepts. In addition, they cover all the new collection classes up to Java 6 Mustang.
Welcome to the 140th edition of The Java(tm) Specialists' Newsletter, now sent to 113 countries with the recent addition of Jordan. This morning, my wife Helene, our baby Evangeline and I went for a lovely walk on Kalathas Beach, a versatile and wholly pleasant beach, close to where we live. The sand is soft, the water shallow (perfect for kids) but gets deeper after a while (perfect for dad). There is a rocky outcrop a bit further out, from which you can jump into the water. There are more fish than at other beaches. They have a fantastic restaurant on the beach that serves genuine Cretan cooking. It is a great all-round beach :)
javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.
The companion book to The Java(tm) Specialists' Newsletter!
Occasionally, books are written that appeal to Java specialists (unfortunately not often enough). Java Generics and Collections [ISBN 0596527756] is such a book. Here are some fascinating nuggets that I found - there are many more.
Mixing generic methods and varargs produces some side effects that result in strange syntax, which most Java programmers don't know. Let's start with the following class:
import java.util.*; public class Lists { public static <T> List<T> toList(T... arr) { List<T> list = new ArrayList<T>(); for (T t : arr) list.add(t); return list; } }
We can now use this to produce lists of ints or Strings:
List<Integer> ints = Lists.toList(1, 2, 3); List<String> words = Lists.toList("hello", "world");
At runtime, the arguments are packed into an array, which is passed to the method toList().
Now comes the catch: What is the generic type that comes back when you pass different types of objects to the toList() method, for example:
List<?> something = Lists.toList("one", 2, 3.0);
You would expect that you can simply write:
List<Object> objects = Lists.toList("one", 2, 3.0); // does not compile!
However, this is not possible, since there is a lower common
class, in this case java.io.Serializable
.
If you want to bind T to a particular class, for example
Object, you need to use explicit parameters:
List<Object> objects = Lists.<Object>toList("one", 2, 3.0);
You cannot mix explicit parameters with static imports. The Java grammar requires that type parameters may appear only in method invocations that use a dotted form.
Although I am certain this appears in other publications, this book is the first place I read such a clear explanation.
In chapter 5: "Evolution, Not Revolution", we see various approaches we can use when migrating from legacy code to generics.
Migrating is migrane and grating rolled into one!
They offer various solutions for legacy and generic clients and libraries combinations. The most interesting combination is where you have a legacy library and a generic client. There are various alternatives:
@SuppressWarnings("unchecked)
annotations. We
can only do that if we have access to the source.
The book then continues by describing reification and the effects this has. After that comes reflection with generics. Both are interesting chapters for Java specialists.
In chapter 9, we see several design patterns implemented with generics, including our popular strategy pattern newsletter, which is reprinted in the book (with permission). They also show the Visitor, Interpreter, Function and Observer patterns.
The book then goes on to Java 5 and Java 6 collections, including the latest Deque and NavigableMap classes.
Each collection chapter ends with a table of big O notation for each operations. This is only meant as a guideline in deciding which implementation to choose. TreeMap can quite easily outperform HashMap depending on the complexity of the hashCode(), equals() and compareTo() methods.
One area that the book did not pick up on is the significance
of the EnumSet.noneOf()
method. This is
actually a factory method that returns different
implementations of EnumSet depending on the key universe.
If the key universe is larger than 64, it creates a
JumboEnumSet, if it is smaller, a RegularEnumSet.
The JumboEnumSet represents the bitset as a
long[]
, whereas the RegularEnumSet
simply contains a long
.
I suspect that the authors felt this going too deep into
implementation details.
import java.util.EnumSet; public class EnumSetTest { public enum SMALL { A0, A1, A2 } public enum MEDIUM { A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60, A61, A62, A63 } public enum LARGE { A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24, A25, A26, A27, A28, A29, A30, A31, A32, A33, A34, A35, A36, A37, A38, A39, A40, A41, A42, A43, A44, A45, A46, A47, A48, A49, A50, A51, A52, A53, A54, A55, A56, A57, A58, A59, A60, A61, A62, A63, A64 } public static void main(String[] args) { System.out.println(EnumSet.noneOf(SMALL.class).getClass()); System.out.println(EnumSet.noneOf(MEDIUM.class).getClass()); System.out.println(EnumSet.noneOf(LARGE.class).getClass()); } }
When we run this, we see as output:
class java.util.RegularEnumSet class java.util.RegularEnumSet class java.util.JumboEnumSet
The book has a lot more fascinating information about generics and collections than I could describe in one newsletter.
If possible, please consider supporting the authors by purchasing the book [ISBN 0596527756] , and not downloading the PDF from the internet somewhere :-)
Kind regards from Europe
Heinz
P.S. Have you already bought the book? Let me know if you liked it (or not)!
We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)
We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.