Nutshell Handbook, the Nutshell Handbook logo, and the O'Reilly logo are registered trademarks of O'Reilly Media, Inc. Java Generics and Collections, the alligator image, and associated trade dress are trademarks of O'Reilly Media, Inc.
Preface
One could say that generics and collections were made for each other, and indeed, the ease of use of collections was one of the main reasons for introducing generics in the first place. We believe these developments mark the beginning of a change in programming style, with greater use of the Collections Framework and, in particular, the increased use of collections in favor of arrays.
Obtaining the Example Programs
How to Contact Us
Conventions Used in This Book
Using Code Examples
Safari® Books Online
Acknowledgments
Generics
Introduction
- Generics
- Boxing and Unboxing
- Foreach
- Generic Methods and Varargs
- Assertions
Unlocking occurs when each integer in the ints list is bound to the variable n of type int. In the second example, without the type parameter there is too much information for the type inference algorithm to infer the correct type.
Subtyping and Wildcards
- Subtyping and the Substitution Principle
- Wildcards with extends
- Wildcards with super
- The Get and Put Principle
- Arrays
- Wildcards Versus Type Parameters
- Wildcard Capture
- Restrictions on Wildcards
It is not always safe to assign a value of type List
Comparison and Bounds
- Comparable
- Maximum of a Collection
- A Fruity Example
- Comparator
- Enumerated Types
- Multiple Bounds
- Bridges
- Covariant Overriding
The marked phrase in square brackets at the beginning of the type signature declares a variable of type T, and we say that T is bounded by Comparable
Declarations
- Constructors
- Static Members
- Nested Classes
- How Erasure Works
Cell
Evolution, Not Revolution
- Legacy Library with Legacy Client
- Generic Library with Generic Client
- Generic Library with Legacy Client
- Legacy Library with Generic Client
- Evolving a Library using Minimal Changes
- Evolving a Library using Stubs
- Evolving a Library using Wrappers
- Conclusions
The interface now takes a type parameter that becomes Stack
Reification
Reifiable Types
If each element in the list were an integer, we wouldn't be able to tell if we had an ArrayList
Instance Tests and Casts
This code does not work because List
Exception Handling
As another example of using unchecked conversions, in Section 6.5 we will see code that uses an unchecked conversion from type Object[] to type T[]. Unchecked conversions in C (and in its descendant C++) are much more dangerous than unchecked conversions in Java. Unlike C, the Java runtime provides important safety features even in the presence of unchecked conversions; for example, an array with an index outside the bounds of the array is never allowed to be accessed.
Array Creation
The first line assigns a new array with reified type information indicating that it is an array of integers. The assignment on the third line raises an array save exception at runtime because the assigned value is of type double, which is incompatible with the reified type attached to the array. The best solution is to use an ArrayList or some other class from the collection framework instead of an array.
The Principle of Truth in Advertising
Truth-in-Advertising Principle: An object type of a string must be a delete subtype of its static type. When programmers often encounter this design, they assume that the array argument exists primarily for efficiency, to reduce allocations by reusing 6.5 The Principle of Truth in Advertising | 85. The conversion method is now passed a String.class token instead of an array of strings.
The Principle of Indecent Exposure
We can define a variant of our previous method that accepts a class token of type Class
How to Define ArrayList
Following the previous model, it is not difficult to create your own version of the Innocent Client that throws a class placement error at the point where there is no conversion, where in this case the official Java library plays the role of DeceptiveLibrary. There's something to be said for that point, although there's also something to be said for the style we've used here, which minimizes the need for untested casts. As before, there is an array of arguments, and if this is not large enough to hold the collection, reflection is used to allocate a new array with the same reified type.
Array Creation and Varargs
The first two calls are fine, but since List> x = Arrays.asList( a, b);. A generic array warning is like an unchecked warning in that it voids the rock-solid warranty that comes with generics.
Arrays as a Deprecated Type?
This workaround is not available for creating arrays that implicitly involve using varargs, so in this case creating generic arrays produces a warning instead of an error. It's not too difficult to take any of the previous examples where an accident occurs due to an unchecked warning, and create a similar example using varargs, using a generic array creation warning instead datum. If a vararg is bound to actual arguments of the unreverable type, a general array creation warning is issued (which raises the same concerns as an unchecked warning).
Summing Up
Reflection
- Generics for Reflection
- Reflected Types are Reifiable Types
- Reflection for Primitive Types
- A Generic Reflection Library
- Reflection for Generics
- Reflecting Generic Types
Wherever a type of the form Class
Effective Generics
- Take Care when Calling Legacy Code
- Use Checked Collections to Enforce Security
- Specialize to Create Reifiable Types
- Maintain Binary Compatibility
Converting from List to List
Design Patterns
- Visitor
- Interpreter
- Function
- Strategy
- Subject-Observer
An example of the use of a type variable in a throws statement is shown in Example 9-5. In this case, the computeTax method of TaxStrategy
expects an argument of type P, where P must be a subclass of TaxPayer. An Advanced Strategy Pattern with Recursive Bounds abstract class TaxPayer
>.
Collections
The Main Interfaces of the Java Collections Framework
First, however, in Chapter 11, we need to cover some preliminary ideas that pervade the entire Framework design. java.lang) Iterable
Preliminaries
- Iterable and Iterators
- Implementations
- Efficiency and the O-Notation
- Contracts
- Collections and Thread Safety
- Synchronization and the Legacy Collections
- JDK 1.2: Synchronized Collections and Fail-Fast Iterators
- Concurrent Collections: Java 5 and Beyond
They also form an important part of the mechanism for implementing hash tables (discussed shortly). This is called synchronizing a critical section of code, in this case the entire push method. In this example, as in synchronized collections, the wrapper methods are 11.5 Collections and Thread Safety | 157. synchronized in the wrapping object itself.
The Collection Interface
Using the Methods of Collection
Note that phoneTuesdayTasks has the type List
Implementing Collection
Suppose we are meticulous people who like to keep all our lists of tasks in ascending order, and we want to merge two lists of tasks into a single list, while preserving the order. Example 12-2 shows how we can merge two sets into a third, provided the iterators of each return their elements in ascending natural order. This method relies on the fact that the sets to be merged do not contain any null elements; if one is encountered, the method throws a NullPointerException.
Collection Constructors
The first of these creates an empty array, and the second an array that will contain the elements of any collection of the parametric type - or one of its subtypes, of course. Not all collection classes have constructors of both forms - ArrayBlockingQueue, for example, cannot be created without adjusting its capacity, and SynchronousQueue cannot hold elements at all, so neither form constructor is suitable. In addition, many collection classes have constructors other than these two, but which ones they have depends not on the interface they implement, but on the underlying implementation; these additional constructors are used to configure the implementation.
Sets
Implementing Set
- HashSet
- LinkedHashSet
- CopyOnWriteArraySet
- EnumSet
- NavigableSet
It does this by maintaining a linked list of array elements, as shown by the curved arrows in Figure 13-3. When they are created, they are attached to the backing group instance that is being used by the group at that time. Note that the arguments of these operations need not be array members themselves.