Title: Chapter 5 Generic Programming
1Chapter 5Generic Programming
- CS 260 Data Structures
- Indiana University Purdue University Fort Wayne
2Generic Programming
- Chapter objectives
- What generic programming is
- Javas Object type and casting
- Wrapper classes
- Generic methods
- Generic classes
- Develop generic ArrayBag class
- Conversion of collection class to generic
collection class - Review the Java interface
- Develop a generalized iterator class
3Generic Programming
- Instead of developing a separate collection class
for each kind of element, it is advantageous to
design a collection class for any kind of element - Imagine the need for various kinds of bag classes
- IntArrayBag
- DoubleArrayBag
- StringArrayBag
- Etc.
- To work with a new kind of element, it is
necessary to rewrite a bag class for the new kind
of data
4Generic Programming
- It would be better to write a bag class once and
include a parameter that would establish the type
of element at the time of instantiation - We will see how to do this a little later using
Java - J2SE 5.0 has new features for implementing
generic classes
5Javas Object type
- Class String is a subclass of class Object
- A String object s is also an Object
- However, an Object obj may or may not be a String
Object
Throttle
Vector
String
Stack
6Java casting
String s new String( Message ) Object
obj obj s // This is a widening conversion
(automatic in Java) s obj //
Compiler error s (String) obj
// This is a narrowing conversion
- A narrowing conversion requires an explicit
typecast - The narrowing conversion produces a runtime error
if obj does not refer to a String object - The compiler takes the programmers word for the
validity of the explicit typecast - The virtual machine checks the validity
7Wrapper classes
- How can we have Object obj refer to a primitive
value? - Answer Use a wrapper class
int i 7 // i is a primitive
value Integer w new Integer( i ) //
Integer is the int wrapper class obj w
// Widening
conversion int j w.intValue( )
// Extracts the int value
7
anInteger
i w obj
7
8Wrapper classes
- Wrapper classes were not convenient in earlier
versions of Java - The operator could not be used to combine
objects - To add w and w2, the following was needed
- J2SE 5.0 specifies automatic boxing and
unboxing - Automatic conversion between primitive and
wrapper values - The following now compile and execute properly
Integer w2 new Integer( 3 ) // Another int
wrapper w w w2
// Caused a compiler error
w new Integer( w.intValue() w2.intValue() )
Integer w 7 w w w2 int i w
9Object methods and generic methods
- Consider the following method that returns an
element from near the middle of the array
parameter - We would have to rewrite this method to work with
an array of doubles or and array of characters
static Integer middle( Integer data ) if (
data.length 0 ) return null else
return data data.length/2
10Object method example
- One possible solution
- However, certain programming errors cannot be
caught at compile time - If a is an array of Integer, then the compiler
wont catch the following error
static Object middle( Object data ) if (
data.length 0 ) return null else
return data data.length/2
Character c (Character) middle( a ) -- this
does generate a runtime ClassCastException
11Generic method example
- It is better to use the following generic method
- Here ltTgt represents a generic type parameter
- Generic type parameters always appear in angle
brackets ltgt right before the return type in the
header - By convention, generic type parameters should be
just a single capital letter
static ltTgt T middle( T data ) if (
data.length 0 ) return null else
return data data.length/2
12Generic method example
- Note how the method header indicates to the
compiler that the return type in this case is
identical to the type of data in the array
parameter - Now, if c is a Character variable and a is an
array of Integer, the compiler determines that
the return type must be Character and detects the
error - Note No explicit casting to Character is needed
static ltTgt T middle( T data )
c middle( a )
c (Character) middle( a )
13Generic method example
- Generic methods may have any number of generic
parameters - Restrictions
- The generic data type inferred by the compiler
must never be one of the primitive types - Cannot call a constructor for a generic type
- May not create a new array of elements of the
generic type
static ltS,T,Ugt T myMethod( S a, U target )
14Generic classes
- Generic classes also involve generic type
parameters - As with generic methods, generic classes also
refer to one or more underlying but unspecified
data types - The angle brackets must appear immediately after
the class name
public class ArrayBagltEgt implements Cloneable
private E data private int
manyItems ???
15Generic classes
- An application using a generic class must
instantiate the class with an actual type
substituted for the generic type parameter - Then instance methods may be called as usual
- Automatic boxing and unboxing works as usual in
the case of myIntBag
ArrayBagltIntegergt myIntBag new
ArrayBagltIntegergt() ArrayBagltStringgt myStringBag
new ArrayBagltStringgt()
myIntBag.add( 123 ) myStringBag.add( This is a
test )
16Generic classes
- Generic classes provide the same compile-time
type checking advantages as to generic methods - Restrictions
- Types used for instantiation must not be any of
the eight primitive types - A constructor for the generic type may not be
called - Cannot create a new array of elements of the
generic type
17ArrayBag implementation issues
- See pp. 260-268 for a complete implementation of
the generic ArrayBag class - To overcome the restriction on no new array of
E-type objects, typecasting is used in the
constructor
public ArrayBag() final int
INITIAL_CAPACITY 10 manyItems 0
data (E ) new Object INITIAL_CAPACITY
18ArrayBag implementation issues
- When ArrayBag instance methods involve ArrayBag
parameters or an ArrayBag return type, specify
the data type as ArrayBagltEgt - This prevents a bag of elements of one type to be
added to a bag of elements of a different type
public void addAll( ArrayBagltEgt addend ) ???
19ArrayBag implementation issues
- When a generic collection tests ltEgt type elements
for equality, it should use an equals method
rather than the operator - All classes that are part of Java have equals
methods - Including wrapper classes
- Set unused pointers to null
- For example, this should be done in the remove
method - Then garbage collection can recycle unused storage
20Conversion of a collection class to a generic
class
- See pp. 258 259 for eight steps for converting
a non-generic class to a generic class - Update the name of the class by adding ltEgt
- Find all places where the type of the underlying
element should be changed to E - Change any static methods to generic static
methods - Dont create new E objects or arrays
- Replace any primitive equality test or !
by calls to equals - Decide if null is ever allowed as an element
- If so, then equals( ) cannot be applied to null
elements - Set unused reference variables to null
- Update all documentation
21Implementing a generic Node class
public class NodeltEgt // private E
data private NodeltEgt link //
public Node( E initialData, NodeltEgt initialLink )
data initialData link
initialLink public void addNodeAftert(
E element ) link new NodeltEgt(
element, link )
- For more details, see Appendix E, pp. 764 - 771
22Java interfaces
- Recall that Java defines interfaces
- An interface . . .
- is a list of related methods that may represent
some standard behavior to included as part of a
new class - requires that the methods specified by the
interface be implemented by any class that
implements the interface - Standard interfaces are well known
- If you know that a certain class implements a
standard interface, then you can rely on the
specified methods being available - Format
public class MyClass implements SomeInterface
23Generic interfaces
- A generic interface is like an ordinary
interface, except the methods depend on one or
more unspecified classes - Example the IteratorltEgt generic interface
- Java 5.0 defines a generic interface called
IteratorltEgt that depends on an unspecified class
E - Any class that implements the IteratorltEgt
interface must be a generic class with its own
generic type parameter E
24Behavior of the IteratorltEgt interface
- Behavior of IteratorltEgt
- public boolean hasNext( )
- public E next( )
- public void remove( )
- Any class implementing the Iterator interface
must implement these methods - These methods are what are needed to iterate over
a collection of E-type objects
25The Lister class
- We develop a generalized iterator class named
Lister - Lister will implement the IteratorltEgt interface
- Objects of type Lister will be external iterators
that iterate over collections built with linked
lists - An external iterator maintains its own copy of
the cursor - The constructor initializes Lister instance
variable current to the head of a linked list - The collection itself doesnt need a cursor
variable
26The Lister class
- An external iterator allows multiple iterations
to occur over some collection object
simultaneously - Perhaps you have nested loops
- Each loop needs to separately iterate over the
collection - Just define as many iterator objects as you need
- The Lister class we will develop works with
generic linked lists built out of generic Nodes
27The Lister class
- ADT invariant of the Lister class
- The instance variable current is the head
reference for the linked list that - contains the elements that have not yet been
provided by the next method - If there are no more elements to provide, then
current is the null reference
import java.util.Iterator import
java.util.NoSuchElementException public class
ListerltEgt implements IteratorltEgt //
private NodeltEgt current // current is a
cursor for the linked list of a collection
// public Lister( NodeltEgt head )
current head public boolean hasNext(
) return ( current ! null )
28The Lister class
// Returns the next element and advances the
cursor to the subsequent element public E
next( ) E answer if ( ! hasNext( )
) throw new NoSuchElementException( "The
Lister is empty ) answer
current.getData( ) current
current.getLink( ) return answer
// // We dont want the remove method, but we
have to implement something public void
remove( ) throw new UnsupportedOperationEx
ception( "Lister has no remove method )
// end class Iterator
29Using the Lister class
- We still need to tie the Lister instance variable
current to a node in the linked list - Suppose we have a generic LinkedBagltEgt class
- Like IntLinkedBag but elements are of class E
- However, suppose LinkedBagltEgt implements the
IteratorltEgt interface and eliminates the internal
iterator - We will place int values in the LinkedBag in
wrappers - See Appendix F in the text, pages 772 777
- A special method needs to be added to LinkedBag
to attach the external iterator to the linked
list within the LinkedBag - This method is iterator( )
public ListerltEgt iterator( ) return new
ListerltEgt( head )
30Using the Lister class
- Now we can iterate over LinkedBagltIntegergt
LinkedBagltIntegergt b new LinkedBagltIntegergt(
) ListerltIntegergt list int sum 0 b.add( new
Integer( 11 ) ) b.add( new Integer( 7 )
// Iterate over the bag and add up all the
ints list b.iterator( )
// this attaches lis to bs linked list while (
list.hasNext( ) ) sum sum list.next( )
//automatic unboxing is used
31Using the Lister class
- Java 5.0 has an enhanced for loop that can be
used with any class that implements the
IterableltEgt interface
// Iterate over the bag and add up all the
ints list b.iterator( )
// this attaches lis to bs linked list for (
Integer next list ) sum sum next
//automatic unboxing is used
32The Java CollectionltEgt interface
- Generic Java collection classes may implement the
generic CollectionltEgt interface - Behavior of CollectionltEgt classes
- Some Java classes implementing this interface
add equals removeAll addAll hashCode retainAll
clear isEmpty size contains iterator toArray co
ntainsAll remove
Vector Set List ArrayList SortedList HashSet
33The Java TreeMapltK,Vgt class
- A map is a collection class in which key-value
pairs may be added - A pair can be retrieved or removed by specifying
just its key - Java has a Map interface that requires behavior
needed by maps - The generic TreeMapltK,Vgt class . . .
- Implements the Map interface
- Has two generic type parameters
- K for the type of keys
- V for the type of values
- The keys must come from a class that implements
the generic ComparableltKgt interface - This allows keys to be compared as follows
key1.compareTo( key2 )
34The Java TreeMapltK,Vgt class
- Some behavior of the TreeMapltK,Vgt class
- public void clear( )
- public boolean containsKey( K key )
- public V get( K key )
- public SetltKgt keySet( )
- public V put( K key, V value )
- public int size( )