Java Cookbook, Second Edition

Problem

You want to store your data in one of the Collection classes defined in Chapter 7 but have it treated as though it were homogeneous.

Solution

Use the JDK 1.5 Generic Types mechanism, and declare the Collection with reference to the given type. The type name appears in angle brackets after the declaration and instantiation. For example, to declare an ArrayList for holding String object references:

List<String> myList = new ArrayList<String>( );

Discussion

When you instantiate a Collection (or any other class using Generic Types), the class appears to be instantiated with the type given in angle brackets becoming the type of arguments passed in, values returned, and so on. Recipe 8.3 provides some details on the implementation. As an example, consider the code in Example 8-1, which creates and uses an ArrayList specialized to contain String objects.

Example 8-1. ArrayListGenericDemo.java

import java.util.*; public class ArrayListGenericDemo { public static void main(String[] args) { ArrayList<String> data = new ArrayList<String>( ); data.add("hello"); data.add("goodbye"); // data.add(new Date( )); This won't compile! Iterator<String> it = data.iterator( ); while (it.hasNext( )) { String s = it.next( ); System.out.println(s); } } }

As you know from the ArrayList example in Recipe 7.3, prior to Generics, the references obtained from a Collection or Iterator would have to be downcasted to their specific type, often after testing with the instanceof operator. A key benefit of Generic Types is that they obviate this testing and downcasting by doing more work at compile time.

You can still instantiate classes such as ArrayList without using a specific type. In this case, they behave as in 1.4 that is, the objects returned from a Collection or Iterator are typed as java.lang.Object and must be downcasted before use.

As a further example, consider the Map interface mentioned in Chapter 7. A Map requires Keys and Values in its put( ) method. A Map, therefore, has two parameterized types. To set up a Map whose keys are Person objects and whose values are Address objects (assuming these two classes exist in your application), you could define it as:

Map<Person, Address> addressMap = new HashMap<Person, Addresss>( );

This Map would expect a Person as its key and an Address as its value in the put( ) method; the get( ) method would return an Address object. The keySet( ) method would return Set<Person> a Set specialized for Person objects and so on.

Категории