Chapter 1. Introduction


Generics and collections work well with a number of other new features introduced in the latest versions of Java, including boxing and unboxing, a new form of loop, and functions that accept a variable number of arguments. We begin with an example that illustrates all of these. As we shall see, combining them is synergistic: the whole is greater than the sum of its parts.

Taking that as our motto, let's do something simple with sums: put three numbers into a list and add them together. Here is how to do it in Java with generics:

 List<Integer> ints = Arrays.asList(1,2,3); int s = 0; for (int n : ints) { s += n; } assert s == 6; 

You can probably read this code without much explanation, but let's touch on the key features. The interface List and the class Arrays are part of the Collections Framework (both are found in the package java.util). The type List is now generic; you write List<E> to indicate a list with elements of type E. Here we write List<Integer> to indicate that the elements of the list belong to the class Integer, the wrapper class that corresponds to the primitive type int. Boxing and unboxing operations, used to convert from the primitive type to the wrapper class, are automatically inserted. The static method asList takes any number of arguments, places them into an array, and returns a new list backed by the array. The new loop form, foreach, is used to bind a variable successively to each element of the list, and the loop body adds these into the sum. The assertion statement (introduced in Java 1.4), is used to check that the sum is correct; when assertions are enabled, it throws an error if the condition does not evaluate to TRue.

Here is how the same code looks in Java before generics:

 List ints = Arrays.asList( new Integer[] {   new Integer(1), new Integer(2), new Integer(3) } ); int s = 0; for (Iterator it = ints.iterator(); it.hasNext(); ) {   int n = ((Integer)it.next()).intValue();   s += n; } assert s == 6; 

Reading this code is not quite so easy. Without generics, there is no way to indicate in the type declaration what kind of elements you intend to store in the list, so instead of writing List<Integer>, you write List. Now it is the coder rather than the compiler who is responsible for remembering the type of the list elements, so you must write the cast to (Integer) when extracting elements from the list. Without boxing and unboxing, you must explicitly allocate each object belonging to the wrapper class Integer and use the intValue method to extract the corresponding primitive int. Without functions that accept a variable number of arguments, you must explicitly allocate an array to pass to the asList method. Without the new form of loop, you must explicitly declare an iterator and advance it through the list.

By the way, here is how to do the same thing with an array in Java before generics:

 int[] ints = new int[] { 1,2,3 }; int s = 0; for (int i = 0; i < ints.size; i++) { s += ints[i]; } assert s == 6; 

This is slightly longer than the corresponding code that uses generics and collections, is arguably a bit less readable, and is certainly less flexible. Collections let you easily grow or shrink the size of the collection, or switch to a different representation when appropriate, such as a linked list or hash table or ordered tree. The introduction of generics, boxing and unboxing, foreach loops, and varargs in Java marks the first time that using collections is just as simple, perhaps even simpler, than using arrays.

Now let's look at each of these features in a little more detail.




Java Generics and Collections
Java Generics and Collections
ISBN: 0596527756
EAN: 2147483647
Year: 2006
Pages: 136

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net