Download Generics&Collections

Document related concepts

Array data structure wikipedia , lookup

Linked list wikipedia , lookup

Java ConcurrentMap wikipedia , lookup

Transcript
Generics & Collections
CISC6795, Spring 2011
Dr. Zhang
A sideline about array
 An array: a sequence of either objects or primitives that are
all the same type and are packaged together under one
identifier name.
 Arrays are defined and used with the square brackets indexing
operator [ ].
 To define an array reference:
 int[] a1;
//Preferred by some in Java community
 Or put square brackets after identifier:
 int a1[];
//C/C++ style
 The similarity between C and Java array ends here !
2
Initializing array
 Unlike in C/C++, Java does not allow
 int a1[20];
 int a1[]; // declare a reference to an array (memory is
allocated for the reference), and there’s been no space
allocated for the array object itself.
 To create storage for the array, you must write an
initialization expression
 int[] a1 = { 1, 2, 3, 4, 5 };
 Compiler allocates storage allocation (equivalent of using new)
at this point.
 int[] a2=a1; // copying the reference,
3
Create array of primitive types
import java.util.*;
import static net.mindview.util.Print.*;
public class ArrayNew {
public static void main(String[] args) {
int[] a; // a reference to an array (of integer) object
Random rand = new Random(47);
a = new int[rand.nextInt(20)]; // create an array of size 20 integer
print("length of a = " + a.length);
print(Arrays.toString(a));
}
use new to create the elements in the array.
} /* Output:
new works even though it’s creating an array of primitives
(new won’t create a non-array primitive)
length of a = 18
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
4
Create array of non-primitive types
 If you create a non-primitive array, you create an array of
references:
public class Inventory {
public Inventory ( )
items is only an array of references
{
new is called to create the array,
items = new Item[5];
items[0] = new Item (1, "MEDIUM_PIZZA“, 1239, 0.0,10);
items[1] = new Item (2, "LARGE_PIZZA“, 1598, 0.0, 10);
reference itself is initialized by creating
a new Item object
5
Outline: next two lessons
 Generics, new feature of J2SE 5.0
 Provide compile-time type safety: catch invalid types at compile time
 Generic methods: A single method declaration => a set of methods
 Generic interfaces: A single interface declaration => a set of
interface
 Generic classes: A single class declaration => a set of classes
 Java collections framework
 Contain prepackaged data structures, interfaces, algorithms
 Use existing data structures
 Example of code reuse
 Provides reusable components
6
Motivation for Generic Methods
 Overloaded methods
 Similar methods perform same operations on different types of data
 Overloaded printArray methods to print:
 Integer array
 Double array
 Character array
 Only reference types can be used with generic methods/classes
 Type-wrapper classes in package java.lang
 Enable programmers to manipulate primitive-type values as objects
 Boolean, Byte, Character, Double, Float,
Integer, Long and Short
7
Autoboxing and Auto-Unboxing
 Boxing conversion
 Converts a value of a primitive type to an object of the
corresponding type-wrapper class
 From int to Integer, double to Double …
 Unboxing conversion
 Converts an object of a type-wrapper class to a value of the
corresponding primitive type
 From Long to long, Float to float
 J2SE 5.0 automatically performs these conversions
 Called autoboxing and auto-unboxing
8
1
// Fig. 18.1: OverloadedMethods.java
2
// Using overloaded methods to print array of different types.
3
Outline
4
public class OverloadedMethods
5
6
{
7
8
9
10
// method printArray to print Integer array
public static void printArray( Integer[] inputArray )
{
// display array elements
Method printArray
for ( Integer element : inputArray )
System.out.printf( "%s ", element );
11
12
13
9
System.out.println();
14
15
16
17
} // end method printArray
18
19
20
21
{
22
23
24
25
accepts
an array of Integer objects
// method printArray to print Double array
public static void printArray( Double[] inputArray )
// display array elements
for ( Double element : inputArray )
System.out.printf( "%s ", element );
System.out.println();
} // end method printArray
Method printArray accepts
an array of Double objects
10
26
// method printArray to print Character array
27
public static void printArray( Character[] inputArray )
28
{
Outline
29
// display array elements
30
for ( Character element : inputArray )
Method printArray accepts
an array of Character objects
System.out.printf( "%s ", element );
31
32
System.out.println();
33
34
} // end method printArray
35
36
public static void main( String args[] )
37
{
38
// create arrays of Integer, Double and Character
39
Integer[] integerArray = { 1, 2, 3, 4, 5, 6 };
40
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
41
Character[] characterArray = { 'H', 'E', 'L', 'L', 'O' };
42
Auto-boxing happens here…
System.out.println( "Array integerArray contains:" );
43
45
Outline
46
printArray( doubleArray ); // pass a Double array
47
System.out.println( "\nArray characterArray contains:" );
48
printArray( characterArray ); // pass a Character array
printArray( integerArray ); // pass an Integer array
44
System.out.println( "\nArray doubleArray contains:" );
} // end main
49
50 } // end class OverloadedMethods
Array integerArray contains:
1 2 3 4 5 6
Array doubleArray contains:
1.1 2.2 3.3 4.4 5.5 6.6 7.7
Array characterArray contains:
H E L L O
11
At compile time, compiler determines argument
integerArray’s type (i.e., Integer[]), attempts
to locate a method named printArray that
specifies a single Integer[] parameter (lines 7-14)
Motivation for Generic Methods (Cont.)
 The three printArray methods
 Array element type appears in two location
 Method header
 for statement header
 Combine three printArray methods into one
 Replace element types with a generic name E
 Declare one printArray method
 Display string representation of the elements of any array
12
Towards generic method
1
public static void printArray( E[] inputArray )
2
{
3
// display array elements
4
for ( E element : inputArray )
5
Replace the element type with
a single generic type E
System.out.printf( "%s ", element );
6
7
System.out.println();
8
} // end method printArray
 Actual syntax:
public static < E > void printArrays( E[] array)
 Type parameter section, also called formal type parameters
 Delimited by angle brackets ( < and > )
 Precede the method’s return type
 Contain one or more type parameters
13
Generic Methods: type parameter
 Type parameter, also known as type variable
 An identifier that specifies a generic type name
 Act as placeholders for the types of the argument passed to the
generic method, i.e., actual type arguments
 Usually use a capital letter
 Convention: use E (element) for a type parameter that represents the type of
an element in an array (or other collection)
 Can be used in return type, parameter types and local variable types
 Can be declared only once but can appear more than once:
public static < E > void printTwoArrays(
E[] array1, E[] array2 )
14
1
2
// Fig. 18.3: GenericMethodTest.java
// Using generic methods to print array of different types.
3
4
public class GenericMethodTest
5
{
Use the type parameter to declare
method printArray’s parameter type
// generic method printArray
public static < E > void printArray( E[] inputArray )
{
Type parameter section delimited
// display array elements
by angle brackets (< and > )
for ( E element : inputArray )
6
7
8
9
10
System.out.printf( "%s ", element );
11
12
13
System.out.println();
} // end method printArray
14
15
16
17
18
19
20
21
22
Use the type parameter to declare method
printArray’s local variable type
public static void main( String args[] )
{
// create arrays of Integer, Double and Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
15
23
System.out.println( "Array integerArray contains:" );
24
printArray( integerArray ); // pass an Integer array
25
System.out.println( "\nArray doubleArray contains:" );
26
printArray( doubleArray ); // pass a Double array
27
System.out.println( "\nArray characterArray contains:" );
28
printArray( characterArray ); // pass a Character array
29
Invoke generic method printArray
with an Integer array
} // end main
30 } // end class GenericMethodTest
Array integerArray contains:
1 2 3 4 5 6
Array doubleArray contains:
1.1 2.2 3.3 4.4 5.5 6.6 7.7
Array characterArray contains:
H E L L O
16
Invoke generic method printArray
with a Character array
Questions/Exercises
 A generic method that find the maximum value in an
array?
 Problem: need to make sure the type is comparable…
 Objects o1, and o2 of the type can be compared, using
o1.compareTo (o2) …
 Need to say the type is any type that provides compareTo()
method
 Interface ? But the parameter of compareTo is type specific,
…
 => generic interface, an parameterized interface
17
Outline
 Generics, new feature of J2SE 5.0
 Provide compile-time type safety: catch invalid types at compile
time
 Generic methods: A single method declaration => a set of related
methods
 Generic interface: a single interface declaration=> a set of related
interface
 Generic classes: A single class declaration => a set of related classes
 Java collections framework, use generics
 Contain prepackaged data structures, interfaces, algorithms
 Use existing data structures
 Example of code reuse
18
 Provides reusable components
Generic Interface: Comparable
public interface Comparable<T>
{
int compareTo(T other);
}
 compareTo(): Compare two objects (this and other) of type T
 Return 0 if two objects are equal
 Return -1 if this is less than other
 Return 1 if this is greater than other
 imposes a total ordering, or natural ordering on the objects of
each class that implements it.
 natural ordering is consistent with equals if and only if:
(e1.compareTo(e2) == 0) <=> e1.equals(e2) for every e1 and e2 of class C.
19
Generic Interface: Comparable
public interface Comparable<T>
{
int compareTo(T o);
}
 Lists (and arrays) of objects that implement this interface can
be sorted using Collections.sort (and Arrays.sort).
 Objects that implement this interface can be used as keys in a
sorted map or elements in a sorted set
20
Upper bound of type parameter
 Next example, generic method maximum (x,y,z)
 Call compareTo method to compare two objects
 Actual type must implement Comparable interface
21
1
// Fig. 18.5: MaximumTest.java
2
3
4
// Generic method maximum returns the largest of three objects.
5
{
public class MaximumTest
Type parameter is used in the
return type of method maximum
// determines the largest of three Comparable objects
public static < T extends Comparable< T > > T maximum( T x, T y, T z )
{
T max = x; // assume x is initially the largest
6
7
8
9
only object of classes that implement
interface Comparable can be used
10
11
12
if ( y.compareTo( max ) > 0 )
max = y; // y is the largest so far
13
14
if ( z.compareTo( max ) > 0 )
15
16
17
18
max = z; // z is the largest
Invokes method compareTo method
Comparable to compare z and max
return max; // returns the largest object
} // end method maximum
19
Generic interface: with a single interface declaration, a set of related types
E.g., Comparable< T >, all types that implement interface Comparable
22
Outline
20
public static void main( String args[] )
21
{
22
23
24
25
26
27
System.out.printf( "Maximum of %d, %d and %d is %d\n\n", 3, 4, 5,
maximum( 3, 4, 5 ) );
System.out.printf( "Maximum of %.1f, %.1f and %.1f is %.1f\n\n",
6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
System.out.printf( "Maximum of %s, %s and %s is %s\n", "pear",
"apple", "orange", maximum( "pear", "apple", "orange" ) );
28
} // end main
29 } // end class MaximumTest
Maximum of 3, 4 and 5 is 5
Maximum of 6.6, 8.8 and 7.7 is 8.8
Maximum of pear, apple and orange is pear
23
Invoke generic method
maximum with three strings
Compile-Time Translation
 Upper bound of type parameter: constraints on actual type
 Default is Object
 use keyword extends to specify
 E.g., T extends Comparable< T >
 When compiler translates generic method to Java bytecode
 Replaces type parameter with its upper bound
 Insert explicit cast operation
e.g., line 23 of Fig. 18.5 I preceded by an Integer cast
(Integer) maximum( 3, 4, 5 )
24
Erasure
1
public static void printArray( Object[] inputArray )
2
{
3
// display array elements
4
for ( Object element : inputArray )
System.out.printf( "%s ", element );
5
6
System.out.println();
7
8
} // end method printArray
1
public static Comparable maximum(Comparable x, Comparable y, Comparable z)
2
{
3
Comparable max = x; // assume x is initially the largest
4
5
6
if ( y.compareTo( max ) > 0 )
max = y; // y is the largest so far
7
8
9
if ( z.compareTo( max ) > 0 )
max = z; // z is the largest
10
11
return max; // returns the largest object
25 12 } // end method maximum
Erasure replaces type parameter T
with its upper bound Comparable
Overloading Generic Method
 Generic method may be overloaded
 By another generic method
 Same method name but different method parameters
 By non-generic methods
 Same method name and number of parameters
 When compiler encounters a method call
 Search for most precise matching method first
 Exact method name and argument types
 Then search for inexact but applicable matching method
 Exercise:
 Write a generic method bubbleSort based on your lab3
26
Outline
 Generics, new feature of J2SE 5.0
 Provide compile-time type safety: catch invalid types at compile
time
 Generic methods: A single method declaration => a set of related
methods
 Generic classes: A single class declaration => a set of related classes
 Java collections framework, use generics
 Contain prepackaged data structures, interfaces, algorithms
 Use existing data structures
 Example of code reuse
 Provides reusable components
27
Generic Classes
 Generic classes, parameterized classes, also called
parameterized types
 Generic class declaration, looks like a non-generic class
declaration, except class name is followed by a type parameter
section
 a simple, concise notation to indicate the actual type(s)
 We study generic class Stack that implements basic stack
operations: push a new element onto stack, pop an element
from stack,…, independent of the actual element type
 Instantiate a stack of different element type: e.g., Stack<
Double >, Stack<Integer>, Stack<Item>
28
1
2
3
4
// Fig. 18.7: Stack.java
// Generic class Stack.
public class Stack< E >
5 {
6
7
8
9
10
11
Generic class declaration, class name is
followed by a type parameter section
private final int size; // number of elements in the stack
private int top; // location of the top element
private E[] elements; // array that stores stack elements
Declareaelements
andefault
array
// no-argument constructor creates
stack of as
the
size
that stores objects of type E
public Stack()
{
12
13
14
this( 10 ); // default stack size
} // end no-argument Stack constructor
15
16
17
18
19
20
21
// constructor creates a stack of the specified number of elements
public Stack( int s )
{
size = s > 0 ? s : 10; // set size of Stack
top = -1; // Stack initially empty
elements = ( E[] ) new Object[ size ]; // create array
} // end Stack constructor
22
23
24
29
Create an array of type E. The generic
mechanism does not allow type parameter
in array-creation expressions because the
type parameter is not available at runtime
25
26
27
28
29
Outline
// push element onto stack; if successful, return true;
// otherwise, throw FullStackException
public void push( E pushValue )
{
if ( top == size - 1 ) // if stack is full
throw new FullStackException( String.format(
"Stack is full, cannot push %s", pushValue ) );
30
31
32
33
34
Method push pushes
element of type E onto stack
elements[ ++top ] = pushValue; // place pushValue on Stack
} // end method push
35
36
37
// return the top element if not empty; else throw EmptyStackException
public E pop()
38
39
40
41
{
Method pop returns the top
element, which is of type E
if ( top == -1 ) // if stack is empty
throw new EmptyStackException( "Stack is empty, cannot pop" );
42
return elements[ top-- ]; // remove and return top element of Stack
43
} // end method pop
44 } // end class Stack< E >
30
1 // Fig. 18.8: FullStackException.java
2 // Indicates a stack is full.
3 public class FullStackException extends RuntimeException
4 {
5
6
// no-argument constructor
public FullStackException()
7
8
9
{
this( "Stack is full" );
} // end no-argument FullStackException constructor
10
11
// one-argument constructor
12
13
14
public FullStackException( String exception )
{
super( exception );
15
} // end one-argument FullStackException constructor
16 } // end class FullStackException
31
1
// Fig. 18.9: EmptyStackException.java
2
// Indicates a stack is full.
3
public class EmptyStackException extends RuntimeException
4
{
Outline
5
// no-argument constructor
6
public EmptyStackException()
7
{
8
9
this( "Stack is empty" );
} // end no-argument EmptyStackException constructor
10
11
// one-argument constructor
12
13
14
public EmptyStackException( String exception )
{
super( exception );
15
} // end one-argument EmptyStackException constructor
16 } // end class EmptyStackException
32
Generic Classes (Cont.)
 Generic class at compilation time
 Compiler performs erasure on class’s type parameters
 Compiler replaces type parameters with their upper bounds
 Generic class test program at compilation time
 Compiler performs type checking
 Compiler inserts cast operations as necessary
33
1
2
// Fig. 18.10: StackTest.java
// Stack generic class test program.
3
4
5
6
7
8
9
10
11
public class StackTest
{
private double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
private int[] integerElements = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
Generic
class
Stack’s
type
private Stack< Double > doubleStack; // stack
stores
Double
objects
argument
is Double
private Stack< Integer > integerStack; // stack
stores
Integer objects
12
// test Stack objects
13
public void testStacks()
14
{
Generic class Stack’s type
argument is Integer
15
16
17
doubleStack = new Stack< Double >( 5 ); // Stack of Doubles
integerStack = new Stack< Integer >( 10 ); // Stack of Integers
18
19
20
21
testPushDouble(); // push double onto doubleStack
size 5 and ingeterStack
testPopDouble(); // pop from doubleStack
testPushInteger(); // push int onto intStack
testPopInteger(); // pop from intStack
22
23
3
4
Instantiate object doubleStack of
of size 10
} // end method testStacks
// test push method with double stack
public void testPushDouble()
26
27
{
// push elements onto stack
28
try
29
{
30
31
32
System.out.println( "\nPushing elements onto doubleStack" );
33
34
35
36
for ( double element : doubleElements )
{
System.out.printf( "%.1f ", element );
doubleStack.push( element ); // push onto doubleStack
37
38
39
40
41
42
43
44
45
3
5
Outline
24
25
// push elements to Stack
Invoke Stack’s method push to place
value onto doubleStack
} // end for
a double
} // end try
catch ( FullStackException fullStackException )
{
System.err.println();
fullStackException.printStackTrace();
} // end catch FullStackException
} // end method testPushDouble
46
// test pop method with double stack
47
public void testPopDouble()
48
{
49
// pop elements from stack
50
51
52
53
try
{
System.out.println( "\nPopping elements from doubleStack" );
double popValue; // store element removed from stack
54
55
// remove all elements from Stack
56
57
while ( true )
{
popValue = doubleStack.pop(); // pop from doubleStack
58
59
60
61
62
System.out.printf( "%.1f ", popValue );
} // end while
Auto-unboxing occurs when the value
} // end try
returned by pop (Double) is assigned
catch( EmptyStackException emptyStackException
)
to a double
primitive variable
63
64
65
66
{
67
68
3
6
System.err.println();
emptyStackException.printStackTrace();
} // end catch EmptyStackException
} // end method testPopDouble
69
70
// test push method with integer stack
public void testPushInteger()
71
{
72
// push elements to stack
73
try
74
75
76
77
78
79
80
81
{
82
83
84
85
86
87
88
89
90
3
7
Outline
System.out.println( "\nPushing elements onto intStack" );
// push elements to Stack
for ( int element : integerElements )
{
System.out.printf( "%d ", element );
integerStack.push( element ); // push onto integerStack
} // end for
Invoke Stack’s method push to place
an int value onto integerStack
} // end try
catch ( FullStackException fullStackException )
{
System.err.println();
fullStackException.printStackTrace();
} // end catch FullStackException
} // end method testPushInteger
91
92
93
94
95
96
// test pop method with integer stack
public void testPopInteger()
Outline
{
// pop elements from stack
try
{
97
98
99
100
System.out.println( "\nPopping elements from intStack" );
int popValue; // store element removed from stack
101
102
while ( true )
{
// remove all elements from Stack
popValue = integerStack.pop(); // pop from intStack
System.out.printf( "%d ", popValue );
103
104
} // end while
} // end try
catch( EmptyStackException emptyStackException )
{
105
106
107
108
System.err.println();
emptyStackException.printStackTrace();
109
110
111
112
} // end catch EmptyStackException
} // end method testPopInteger
113
114
public static void main( String args[] )
115
116
{
StackTest application = new StackTest();
117
application.testStacks();
118
} // end main
119 } // end class StackTest
38
Auto-unboxing occurs when the value
returned by pop (Integer) is assigned
to an int primitive variable
Outline
Pushing elements onto doubleStack
1.1 2.2 3.3 4.4 5.5 6.6
FullStackException: Stack is full, cannot push 6.6
at Stack.push(Stack.java:30)
at StackTest.testPushDouble(StackTest.java:36)
at StackTest.testStacks(StackTest.java:18)
at StackTest.main(StackTest.java:117)
Popping elements from doubleStack
5.5 4.4 3.3 2.2 1.1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest.testPopDouble(StackTest.java:58)
at StackTest.testStacks(StackTest.java:19)
at StackTest.main(StackTest.java:117)
Pushing elements onto integerStack
1 2 3 4 5 6 7 8 9 10 11
FullStackException: Stack is full, cannot push 11
at Stack.push(Stack.java:30)
at StackTest.testPushInteger(StackTest.java:81)
at StackTest.testStacks(StackTest.java:20)
at StackTest.main(StackTest.java:117)
Popping elements from integerStack
10 9 8 7 6 5 4 3 2 1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest.testPopInteger(StackTest.java:103)
at StackTest.testStacks(StackTest.java:21)
at StackTest.main(StackTest.java:117)
39
Generic Classes (Cont.)
 Creating generic methods to test class Stack< E >
 Method testPush
 Perform same tasks as testPushDouble and testPushInteger
 Method testPop
 Perform same tasks as testPopDouble and testPopInteger
40
Outline
4
5
6
7
8
public class StackTest2
{
private Double[] doubleElements = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6 };
private Integer[] integerElements =
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
41
// Fig. 18.11: StackTest2.java
// Stack generic class test program.
1
2
3
private Stack< Double > doubleStack; // stack stores Double objects
private Stack< Integer > integerStack; // stack stores Integer objects
// test Stack objects
public void testStacks()
{
doubleStack = new Stack< Double >( 5 ); // Stack of Doubles
integerStack = new Stack< Integer >( 10 ); // Stack of Integers
testPush( "doubleStack", doubleStack, doubleElements );
testPop( "doubleStack", doubleStack );
testPush( "integerStack", integerStack, integerElements );
testPop( "integerStack", integerStack );
} // end method testStacks
Invoke generic methods testPush and
testPop to push elements onto stack
and pop elements from stack
42
25
26
27
28
29
30
31
32
Outline
// generic method testPush pushes elements onto a Stack
public < T > void testPush( String name, Stack< T > stack,
T[] elements )
{
Generic method testPush replaces
// push elements onto stack
testPushDouble and testPushInteger
try
{
System.out.printf( "\nPushing elements onto %s\n", name );
33
34
35
36
// push elements onto Stack
for ( T element : elements )
{
System.out.printf( "%s ", element );
stack.push( element ); // push element onto stack
37
38
39
40
41
}
with type
} // end try
catch ( FullStackException fullStackException )
42
{
43
44
45
46
47
Replace element type Double/Integer
parameter T
System.out.println();
fullStackException.printStackTrace();
} // end catch FullStackException
} // end method testPush
48
49
// generic method testPop pops elements from a Stack
public < T > void testPop( String name, Stack< T > stack )
50
{
51
52
53
54
55
56
// pop elements from stack
try
{
Outline
System.out.printf( "\nPopping elements from %s\n", name );
T popValue; // store element removed from stack
type Double/Integer
with type parameter T
57
Replace
// remove elements
from element
Stack
58
59
60
61
while ( true )
{
popValue = stack.pop(); // pop from stack
System.out.printf( "%s ", popValue );
} // end while
} // end try
catch( EmptyStackException emptyStackException )
{
62
63
64
65
System.out.println();
emptyStackException.printStackTrace();
66
67
68
69
} // end catch EmptyStackException
} // end method testPop
70
71
public static void main( String args[] )
72
73
{
StackTest2 application = new StackTest2();
74
application.testStacks();
75
} // end main
76 } // end class StackTest2
43
Generic method testPop replaces
testPopDouble and testPopInteger
Pushing elements onto doubleStack
1.1 2.2 3.3 4.4 5.5 6.6
FullStackException: Stack is full, cannot push 6.6
at Stack.push(Stack.java:30)
at StackTest2.testPush(StackTest2.java:38)
at StackTest2.testStacks(StackTest2.java:19)
at StackTest2.main(StackTest2.java:74)
Outline
Popping elements from doubleStack
5.5 4.4 3.3 2.2 1.1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest2.testPop(StackTest2.java:60)
at StackTest2.testStacks(StackTest2.java:20)
at StackTest2.main(StackTest2.java:74)
Pushing elements onto integerStack
1 2 3 4 5 6 7 8 9 10 11
FullStackException: Stack is full, cannot push 11
at Stack.push(Stack.java:30)
at StackTest2.testPush(StackTest2.java:38)
at StackTest2.testStacks(StackTest2.java:21)
at StackTest2.main(StackTest2.java:74)
Popping elements from integerStack
10 9 8 7 6 5 4 3 2 1
EmptyStackException: Stack is empty, cannot pop
at Stack.pop(Stack.java:40)
at StackTest2.testPop(StackTest2.java:60)
at StackTest2.testStacks(StackTest2.java:22)
at StackTest2.main(StackTest2.java:74)
44
Outline
 Generics, new feature of J2SE 5.0
 Provide compile-time type safety: catch invalid types at compile
time
 Generic methods: A single method declaration => a set of related
methods
 Generic classes: A single class declaration => a set of related classes
 Data Structure: linked list
 Java collections framework, use generics
 Contain prepackaged data structures, interfaces, algorithms
 Use existing data structures
 Example of code reuse
45
 Provides reusable components
Primer on Data structure
*
46
How to store a collection of data
 Array: fixed-size data structure for holding reference to
objects with same type
 cannot grow and shrink at execution time
 Dynamic data structure:
 Linked list: collection of data items that link up in a chain
 Tree: collection of data items that form a tree
47
Linked list
 Self-referential class: contains an instance variable that refers
to another object of the same class type, called a link
 Drawn as an line with arrow pointing to the other object
 A null reference indicates that the link does not refer to
another object (drawn as a backslash in diagram)
 Diagram of a linked list
48
data link
1
2
3
// Fig. 17.3: List.java
// ListNode and List class definitions.
package com.deitel.jhtp6.ch17;
4
5
6
7
8
9
 List.java
// class to represent one node in a list
Field data can refer to any object
class ListNode
 (1 of 6)
{
// package access members; List can access these directly
Object data;
Stores a reference to the next
ListNode object in the linked list
10
11
ListNode nextNode;
12
// constructor creates a ListNode that refers to object
13
14
15
ListNode( Object object )
{
this( object, null );
16
17
} // end ListNode one-argument constructor
18
19
20
21
// constructor creates ListNode that refers to
// Object and to next ListNode
ListNode( Object object, ListNode node )
{
22
23
24
49
25
data = object;
nextNode = node;
} // end ListNode two-argument constructor
26
// return reference to data in node
27
Object getObject()
28
{
29
return data; // return Object in this node
30
31
} // end method getObject
 List.java
32
33
34
35
// return reference to next node in list
ListNode getNext()
{
return nextNode; // get next node

36
} // end method getNext
37 } // end class ListNode
38
39 // class List definition
40 public class List
50
Outline
(2 of 6)
References to the first and last
ListNodes in a List
41 {
42
43
44
45
private ListNode firstNode;
private ListNode lastNode;
private String name; // string like "list" used in printing
46
47
48
// constructor creates empty List with "list" as the name
public List()
{
49
50
51
this( "list" );
} // end List no-argument constructor
Call one-argument constructor
51
52
53
// constructor creates an empty List with a name
public List( String listName )
54
{
55
name = listName;
56
firstNode = lastNode = null;
Initialize both references to null
 List.java
57
58
59
60
} // end List one-argument constructor
61
62
{
63
64
65
66
67
68
69
firstNode = lastNode = new ListNode( insertItem );
else // firstNode refers to new node
firstNode = new ListNode( insertItem, firstNode );
} // end method insertAtFront
70
71
72
73
74
75
76
{

(3 of 6)
// insert Object at front of List
public void insertAtFront( Object insertItem )
if ( isEmpty() ) // firstNode and lastNode refer to same object
// insert Object at end of List
public void insertAtBack( Object insertItem )
if ( isEmpty() ) // firstNode and lastNode refer to same Object
firstNode = lastNode = new ListNode( insertItem );
else // lastNode's nextNode refers to new node
lastNode = lastNode.nextNode = new ListNode( insertItem );
} // end method insertAtBack
Order of evaluation?
77
78
// remove first node from List
public Object removeFromFront() throws EmptyListException
79
{
80
throw new EmptyListException( name );
 List.java
81
82
83
84
85
Object removedItem = firstNode.data; // retrieve data being removed
86
87
if ( firstNode == lastNode )
firstNode = lastNode = null;
88
else
89
90
91

firstNode = firstNode.nextNode;
return removedItem; // return removed node data
} // end method removeFromFront
94
// remove last node from List
95
96
97
public Object removeFromBack() throws EmptyListException
{
if ( isEmpty() ) // throw exception if List is empty
100
101
(4 of 6)
// update references firstNode and lastNode
92
93
98
99
52
if ( isEmpty() ) // throw exception if List is empty
throw new EmptyListException( name );
Object removedItem = lastNode.data; // retrieve data being removed
102
103
// update references firstNode and lastNode
if ( firstNode == lastNode )
104
105
106
firstNode = lastNode = null;
else // locate new last node
{
107
ListNode current = firstNode;
108
109
// loop while current node does not refer to lastNode
110
111
while ( current.nextNode != lastNode )
current = current.nextNode;
112
113
114
115
Outline
 List.java

(5 of 6)
lastNode = current; // current is new lastNode
current.nextNode = null;
} // end else
116
117
118
119
return removedItem; // return removed node data
} // end method removeFromBack
120
121
122
123
// determine whether list is empty
Predicate method that determines
public boolean isEmpty()
whether the list is empty
{
return firstNode == null; // return true if List is empty
124
125
} // end method isEmpty
53
126
127
// output List contents
public void print()
128
129
130
{
Display the list’s contents
if ( isEmpty() )
{
 List.java
System.out.printf( "Empty %s\n", name );
131
132
133
Outline

return;
} // end if
(6 of 6)
134
135
136
137
System.out.printf( "The %s is: ", name );
ListNode current = firstNode;
138
// while not at end of list, output current node's data
139
while ( current != null )
140
{
Output a string representation
of current.data
141
System.out.printf( "%s ", current.data );
142
current = current.nextNode;
143
} // end while
144
145
System.out.println( "\n" );
146
} // end method print
147 } // end class List
54
Move to the next node in the list
1
// Fig. 17.4: EmptyListException.java
2
// Class EmptyListException definition.
3
package com.deitel.jhtp6.ch17;
4
5
public class EmptyListException extends RuntimeException
6
{
An unchecked exception
 EmptyListE
7
8
// no-argument constructor
public EmptyListException()
9
{
10
11
this( "List" ); // call other EmptyListException constructor
} // end EmptyListException no-argument constructor
12
13
14
// one-argument constructor
public EmptyListException( String name )
15
{
16
17
super( name + " is empty" ); // call superclass constructor
} // end EmptyListException one-argument constructor
18 } // end class EmptyListException
55
xception.jav
a
1
// Fig. 17.5: ListTest.java
2
// ListTest class to demonstrate List capabilities.
3
import com.deitel.jhtp6.ch17.List;
4
5
import com.deitel.jhtp6.ch17.EmptyListException;
6
7
8
public class ListTest
{
public static void main( String args[] )
9
10
Outline
{
List list = new List(); // create the List container
11
12
// insert integers in list
13
14
list.insertAtFront( -1 );
list.print();
15
list.insertAtFront( 0 );
16
17
list.print();
list.insertAtBack( 1 );
18
19
20
21
list.print();
list.insertAtBack( 5 );
list.print();
56
22
23
// remove objects from list; print after each removal
try
24
{
25
Object removedObject = list.removeFromFront();
26
27
System.out.printf( "%s removed\n", removedObject );
list.print();
28
29
30
31
32
removedObject = list.removeFromFront();
System.out.printf( "%s removed\n", removedObject );
list.print();
33
34
35
36
removedObject = list.removeFromBack();
System.out.printf( "%s removed\n", removedObject );
list.print();
37
38
39
40
41
removedObject = list.removeFromBack();
System.out.printf( "%s removed\n", removedObject );
list.print();
} // end try
catch ( EmptyListException emptyListException )
42
43
44
45
{
emptyListException.printStackTrace();
} // end catch
} // end main
46 } // end class ListTest
57
Trees
 Trees:
 Has a single root node
 Each node has multiple links, each
referring to a child node
 Left child is the root of the left subtree
 Right child is the root of the right
subtree
 Siblings are the children of a specific
node
 A leaf node has no children, i.e., null
links
58
Trees (Cont.)
 Binary search trees
 Value stores in a node,
 Larger than values stored in its left subtree
 Smaller than values stored in its right subtree
 Searching is easy:
 Compare value to search for with root
 If smaller, goes to left subtree; if larger,
goes to right subtree; if same, return
found …
 Other algorithms:
 traversing a tree: inorder, preorder,
postorder
59
Abstract Data Structure (ADT)
 Many applications need to use collections with access constraints
 List: a collection of data stored in certain order where insertion
and deletion can be made any where in the order
 E.g. Insert an element at the 5th position
 Stack: insertion and deletion are made at one end only, i.e., top
 Used in compiler, operating system
 Queue: insertion made at one end (tail) and deletion made at
another end (head)
 Implementation details are hidden
 Can use array or linked list to implement above ADT
60
Stacks
 Stacks, Last-in, first-out (LIFO) data structure
 Method push adds a new node to the top of the stack
 Method pop removes a node from the top of the stack and
returns the data from the popped node
 Application example:
 Program execution stack
 Holds the return addresses , local variables and parameters of method
invocation
 Used by the compiler to evaluate arithmetic expressions
61
Stack Implementation option 1
 Stack class that inherits from List
 Stack methods push, pop, isEmpty and print are
performed by inherited methods insertAtFront,
removeFromFront, isEmpty and print
 push calls insertAtFront
 pop calls removeFromFront
 isEmpty and print can be called as inherited
 Other List methods are also inherited
 Including methods that should not be in the stack class’s public
interface
62
Stacks implementation option 2
 Stack class that contains a reference to a List
 Each stack method invoked delegates the call to the appropriate
List method
 method push delegates to List method insertAtFront
 method pop delegates to List method removeFromFront
 method isEmpty delegates to List method isEmpty
 method print delegates to List method print
 Enables us to hide the List methods that should not be in our
stack’s public interface
63
64
Outline
1
// Fig. 17.12: StackComposition.java
2
// Class StackComposition definition with composed List object.
3
4
package com.deitel.jhtp6.ch17;
5
6
public class StackComposition
{
7
8
9
10
11
private List stackList;
private List reference
// no-argument constructor
public StackComposition()
{
12
13
14
15
16
stackList = new List( "stack" );
} // end StackComposition no-argument constructor
17
18
19
20
{
// add object to stack
public void push( Object object )
stackList.insertAtFront( object );
} // end method push
push method delegates call to List
method insertAtFront
21
22
Outline
// remove object from stack
public Object pop() throws EmptyListException
23
24
{
25
26
27
28
29
} // end method pop
30
return stackList.removeFromFront();
// determine if stack is empty
public boolean isEmpty()
{
return stackList.isEmpty();
31
} // end method isEmpty
32
33
// output stack contents
34
35
36
public void print()
{
stackList.print();
37
} // end method print
38 } // end class StackComposition
65
Method pop delegates call to List
method removeFromFront
Method isEmpty delegates call to
List method isEmpty
Method print delegates call to
List method print
Queues
 Queue, First-in, first-out (FIFO) data structure
 Similar to a checkout line in a supermarket
 Enqueue: inserts nodes at the tail (or end)
 Dequeue: removes nodes from the head (or front)
 Application example:
 Used to support print spooling: a spooler program
manages the queue of printing jobs
 Multi-thread programming: a pool of thread, a queue
of tasks
66
Queues implementation
 Queue class that contains a reference to a List
 Method enqueue calls List method insertAtBack
 Method dequeue calls List method
removeFromFront
 Method isEmpty calls List method isEmpty
 Method print calls List method print
67
Outline
1
2
// Fig. 17.13: Queue.java
// Class Queue.
3
package com.deitel.jhtp6.ch17;
4
5
6
7
8
public class Queue
{
private List queueList;
9
// no-argument constructor
10
11
public Queue()
{
12
13
queueList = new List( "queue" );
} // end Queue no-argument constructor
14
68
15
16
// add object to queue
public void enqueue( Object object )
17
{
18
19
20
queueList.insertAtBack( object );
} // end method enqueue
An object of class List
Method enqueue calls List
method insertAtBack
21
// remove object from queue
22
23
24
public Object dequeue() throws EmptyListException
{
Method dequeue calls List
return queueList.removeFromFront();
method removeFromFront
25
} // end method dequeue
Outline
26
27
28
// determine if queue is empty
public boolean isEmpty()
29
30
{
31
32
33
} // end method isEmpty
34
35
36
public void print()
{
queueList.print();
return queueList.isEmpty();
// output queue contents
37
} // end method print
38 } // end class Queue
69
Outline
1
2
// Fig. 17.14: QueueTest.java
// Class QueueTest.
3
4
5
import com.deitel.jhtp6.ch17.Queue;
import com.deitel.jhtp6.ch17.EmptyListException;
Create a Queue
6 public class QueueTest
7 {
8
public static void main( String args[] )
9
{
Enqueue
10
Queue queue = new Queue();
11
12
// use enqueue method
70
13
queue.enqueue( -1 );
14
queue.print();
15
queue.enqueue( 0 );
16
queue.print();
17
18
queue.enqueue( 1 );
queue.print();
19
20
21
queue.enqueue( 5 );
queue.print();
object
four integers
22
// remove objects from queue
23
try
24
{
Object removedObject = null;
25
Dequeue the objects in
first-in, first-out order
26
27
while ( true )
28
{
29
removedObject = queue.dequeue(); // use dequeue method
30
System.out.printf( "%s dequeued\n", removedObject );
31
queue.print();
} // end while
32
Display the exception’s stack trace
33
} // end try
34
catch ( EmptyListException emptyListException )
35
{
emptyListException.printStackTrace();
36
} // end catch
37
} // end main
38
39 } // end class QueueTest
71
Outline
The queue is: -1
The queue is: -1 0
The queue is: -1 0 1
The queue is: -1 0 1 5
-1 dequeued
The queue is: 0 1 5
0 dequeued
The queue is: 1 5
1 dequeued
The queue is: 5
5 dequeued
Empty queue
com.deitel.jhtp6.ch17.EmptyListException: queue is empty
at com.deitel.jhtp6.ch17.List.removeFromFront(List.java:81)
at com.deitel.jhtp6.ch17.Queue.dequeue(Queue.java:24)
at QueueTest.main(QueueTest.java:29)
72
End of primer
73
Java Collections Framework
 A unified architecture for representing and manipulating
collections. It contains:
 Interfaces: abstract data types that represent collections. Interfaces
allow collections to be manipulated independently of the details of
their representation.
 Implementations: concrete implementations of collection
interfaces. They are reusable data structures.
 Algorithms: methods that perform useful computations, such as
searching and sorting, on objects that implement collection
interfaces.
 polymorphic: same method can be used on many different implementations of
the appropriate collection interface. In essence, algorithms are reusable
functionality.
74
Some collection framework interfaces
 Java Collections Framework: enhanced with generics capabilities
in J2SE 5.0
 Allow one to declare a stack of Card, a queue of Customers, using the type
parameter
 Compile-time type checking ensure only objects of given type can be
stored into the collection
 Object retrieved from the collection is cast to appropriate type
 In comparison, implementation of stack/queue seen so far store a
collection of Object
 One can store different objects into it
 Programmer needs to cast the object retrieved to its original type …
75
Java Collection Framework:
Interfaces Hierarchy
These interfaces allow collections to be manipulated independently
of the details of their representation.
76
Collection Interface hierarchy
 Collection interface: basic functionality used by all
collections, such as add and remove methods
 Set interface: does not allow duplicate elements
 useful for storing collections such as a deck of cards or student
records.
 a subinterface, SortedSet, provides for ordering of elements
 List interface: an ordered collection, provides precise control
over where each element is inserted or retrieved from
 Queue interface: additional insertion, extraction, and
inspection operations.
 elements in a Queue are typically ordered in on a FIFO basis.
77
Collection Interface hierarchy (2)
 Map interface: maps keys and values similar to a Hashtable.
 Map's subinterface, SortedMap, maintains its key-value pairs in
ascending order or in an order specified by a Comparator.
78
Collection Interfaces are generic
 All core collection interfaces are generic.
 E.g, the declaration of the Collection interface:
public interface Collection<E>...
 The <E> syntax tells you that the interface is generic.
 When you declare a Collection instance you can and should
specify the type of object contained in the collection.
 Allow compiler to verify (at compile-time) that the type of
object you put into the collection is correct, reducing errors at
runtime.
79
Collection Interface
public interface Collection<E> extends Iterable<E>
{
// Basic operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element); //optional
boolean remove(Object element); //optional
80
Collection Interface (cont’d)
Return a iterator: an object for traversing through a
Iterator<E> iterator();
collection and to remove elements from the collection
// Bulk operations
selectively
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c); //optional
boolean removeAll(Collection<?> c); //optional
boolean retainAll(Collection<?> c); //optional
void clear(); //optional
// Array operations
Object[] toArray();
<T> T[] toArray(T[] a);
}
81
General-purpose Implementations
Interface
Implementation
 Interfaces
Set
List
Implementations
Hash
Resizable Tree
Linked

Hash table Resizable
arrayHash
Tree Linked
table
array
list
table+Linked list
list Hash table + Linked list Set
HashSet
TreeSet
LinkedHashSet
HashSet
TreeSet LinkedHashSet
List ArrayList LinkedList Queue
Map
ArrayList
LinkedList
HashMap TreeMap
LinkedHashMap
Queue
Map
82
HashMap
TreeMap
LinkedHashMap
Lists: ordered collection
 List: ordered Collection that can contain
duplicates
 Implemented via interface List
 ArrayList, vector
 ArrayList behaves like Vector without
synchronization and therefore execute faster than Vectors
(no overhead of thread synchronization)
 LinkedLists can be used to create stacks,
queues, trees and deques (double-ended queues,
pronounced “decks”).
83
ArrayList and Iterator
 ArrayList example
 Demonstrate Collection interface capabilities
 Place two String arrays in ArrayLists
 Use Iterator to remove elements in ArrayList
84
1
2
// Fig. 19.3: CollectionTest.java
// Using the Collection interface.
3
import java.util.List;
4
5
6
7
8
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
Outline
public class CollectionTest
9 {
10
11
12
private static final String[] colors =
{ "MAGENTA", "RED", "WHITE", "BLUE", "CYAN" };
private static final String[] removeColors =
{ "RED", "WHITE", "BLUE" };
13
14
15
16
Create ArrayList
objects and assign
// create ArrayList, add Colors to it and manipulate
it
their references to variable list and
public CollectionTest()
17
{
18
19
20
85
removeList, respectively
List< String > list = new ArrayList< String >();
List< String > removeList = new ArrayList< String >();
21
// add elements in colors array to list
22
for ( String color : colors )
23
24
25
26
27
28
29
30
add objects to list and
removeList, respectively
// add elements in removeColors to removeList
for ( String color : removeColors )
removeList.add( color );
Get number of
ArrayList elements
System.out.println( "ArrayList: " );
31
// output list contents
32
33
34
for ( int count = 0; count < list.size(); count++ )
System.out.printf( "%s ", list.get( count ) );
35
36
37
// remove colors contained in removeList
removeColors( list, removeList );
38
System.out.println( "\n\nArrayList after calling removeColors: " );
39
40
41
42
// output list contents
for ( String color : list )
System.out.printf( "%s ", color );
43
44
86
Outline
list.add( color );
} // end CollectionTest constructor
retrieve individual element values
Method removeColors takes two
Collections as arguments; Line 36
passes two Lists, which extends
Collection, to this method
45
46
47
48
// remove colors specified in collection2 from collection1
private void removeColors(
Collection< String > collection1, Collection< String > collection2 )
Outline
{
// get iterator
Iterator< String > iterator = collection1.iterator();
49
50
51
52
53
hasNext determines whether the
Iterator contains more elements
// loop while collection has items
while ( iterator.hasNext() )
54
55
Take any Collections containing
strings as arguments
if ( collection2.contains( iterator.next() ) )
56
57
58
iterator.remove(); // remove current Color
} // end method removeColors
59
public static void main( String args[] )
60
{
61
62
new CollectionTest();
} // end main
next returns a reference
to the next element
contains determines whether
collection2 contains the element
returned by next
63 } // end class CollectionTest
ArrayList:
MAGENTA RED WHITE BLUE CYAN
ArrayList after calling removeColors:
MAGENTA CYAN
87
Use Iterator method remove to
remove String from Iterator
Common Programming Error
 If a collection is modified by one of its methods after an
iterator is created for that collection, the iterator
immediately becomes invalid—any operations
performed with the iterator after this point throw
ConcurrentModificationExceptions. For
this reason, iterators are said to be “fail fast.”
88
LinkedList
 LinkedList example
 Add elements of one List to the other
 Convert Strings to uppercase
 Delete a range of elements
89
1
// Fig. 19.4: ListTest.java
2
3
// Using LinkLists.
import java.util.List;
4
5
6
import java.util.LinkedList;
import java.util.ListIterator;
7
8
9
public class ListTest
{
private static final String colors[] = { "black", "yellow",
Outline
10
11
12
"green", "blue", "violet", "silver" };
private static final String colors2[] = { "gold", "white",
"brown", "blue", "gray", "silver" };
13
14
// set up and manipulate LinkedList objects
15
public ListTest()
16
17
{
List< String > list1 = new LinkedList< String >();
18
19
20
List< String > list2 = new LinkedList< String >();
21
22
23
for ( String color : colors )
list1.add( color );
// add elements to list link
Create two
LinkedList objects
Use List method add to append elements from
array colors to the end of list1
90
24
25
26
27
28
91
// add elements to list link2
for ( String color : colors2 )
list2.add( color );
Outline
Use List method add to append elements from
array colors2 to the end of list2
list1.addAll( list2 ); // concatenate lists
29
30
31
32
33
34
list2 = null; // release resources
printList( list1 ); // print list1 elements
Use
35
36
System.out.print( "\nDeleting elements 4 to 6..." );
removeItems( list1, 4, 7 ); // remove items 4-7 from list
List method addAll to append all
elements of list2 to the end of list1
convertToUppercaseStrings( list1 ); // convert to upper case string
printList( list1 ); // print list1 elements
37
38
39
printList( list1 ); // print list1 elements
printReversedList( list1 ); // print list in reverse order
} // end ListTest constructor
40
41
// output List contents
42
43
44
45
46
47
48
public void printList( List< String > list )
{
System.out.println( "\nlist: " );
49
50
51
System.out.println();
} // end method printList
for ( String color : list )
System.out.printf( "%s ", color );
Method printList allows any
Lists containing strings to be
passed as arguments to this method
52
53
54
55
// locate String objects and convert to uppercase
private void convertToUppercaseStrings( List< String > list )
{
ListIterator< String > iterator = list.listIterator();
56
57
58
59
60
61
62
63
while ( iterator.hasNext() )
{
String color = iterator.next(); // get item
iterator.set( color.toUpperCase() ); // convert to upper case
} // end while
} // end method convertToUppercaseStrings
64
65
// obtain sublist and use clear method to delete sublist items
private void removeItems( List< String > list, int start, int end )
66
67
68
69
70
71
72
73
74
{
92
Outline
list.subList( start, end ).clear();
} // end method removeItems
anyitems
List
// remove
that contains strings
subList: obtain a portion of the List
// print reversed list
private void printReversedList( List< String > list )
{
ListIterator< String > iterator = list.listIterator( list.size() );
calllistIterator with one argument
(starting position) to get a bidirectional
iterator
75
76
77
Outline
System.out.println( "\nReversed List:" );
// print list in reverse order
while ( iterator.hasPrevious() )
78
System.out.printf( "%s ", iterator.previous() );
79
80
hasPrevious: determine whether there are
more elements while traversing the list backward
} // end method printReversedList
81
82
public static void main( String args[] )
83
{
84
85
Invoke ListIterator method
previous to get the previous
element from the list
new ListTest();
} // end main
86 } // end class ListTest
list:
black yellow green blue violet silver gold white brown blue gray silver
list:
BLACK YELLOW GREEN BLUE VIOLET SILVER GOLD WHITE BROWN BLUE GRAY SILVER
Deleting elements 4 to 6...
list:
BLACK YELLOW GREEN BLUE WHITE BROWN BLUE GRAY SILVER
Reversed List:
SILVER GRAY BLUE BROWN WHITE BLUE GREEN YELLOW BLACK
93
Sets
 Set interface: Collection that contains unique
elements
 Implementations:
 HashSet
 Stores elements in hash table
 TreeSet
 Stores elements in tree
 Example: using HashSet to find unique elements in a
collection …
94
1
// Fig. 19.18: SetTest.java
2
// Using a HashSet to remove duplicates.
3
import java.util.List;
4
5
import java.util.Arrays;
import java.util.HashSet;
6
import java.util.Set;
7
8
import java.util.Collection;
Outline
9 public class SetTest
10 {
11
12
13
14
15
16
17
private static final String colors[] = { "red", "white", "blue",
"green", "gray", "orange", "tan", "white", "cyan",
"peach", "gray", "orange" };
// create and output ArrayList
public SetTest()
{
18
List< String > list = Arrays.asList( colors );
19
20
System.out.printf( "ArrayList: %s\n", list );
printNonDuplicates( list );
21
22
95
} // end SetTest constructor
Create a List that
contains String objects
Method printNonDuplicates accepts
a Collection of type String
23
24
25
26
27
28
29
30
31
32
// create set from array to eliminate duplicates
private void printNonDuplicates( Collection< String > collection )
Outline
{
// create a HashSet
Set< String > set = new HashSet< String >( collection );
System.out.println( "\nNonduplicates are: " );
for ( String s : set )
System.out.printf( "%s ", s );
33
34
35
36
System.out.println();
} // end method printNonDuplicates
37
38
39
40
public static void main( String args[] )
{
new SetTest();
} // end main
Conversion construct: create a
HashSet from Collection
argument
41 } // end class SetTest
ArrayList: [red, white, blue, green, gray, orange, tan, white, cyan, peach, gray,
orange]
Nonduplicates are:
red cyan white tan gray green orange blue peach
96
Software Engineering Observation
 Collection interface is used to pass around
collections of objects where maximum generality is
desired.
 The collection might be a linked list, an array list, a set , …
 E.g., All general-purpose collection implementations have a
conversion constructor that takes a Collection argument. It
initializes new collection to contain all elements in specified
collection
 Next: useful Collection methods for manipulating any
collections
97
How to iterate Collection
 for-each construct: to concisely traverse a collection or
array using a for loop.
for (Object o : collection)
System.out.println(o);
 Using Iterator: an object for traversing through a
collection and to remove elements from the collection
selectively, if desired.
 Use Iterator instead of the for-each construct when you need
to remove element.
98
Iterator
Get an Iterator for a collection by calling its iterator
method
2. Call methods of Iterator to traverse through collection
1.
Iterator interface:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); //optional
}
 hasNext: returns true if iteration has more elements
 next: returns next element in the iteration.
99
Iterator: remove method
 remove: removes last element that was returned by next
from underlying Collection.
 only safe way to modify a collection during iteration
 may be called only once per call to next and throws an exception
if this rule is violated.
 behavior is unspecified if underlying collection is modified in any other way
while iteration is in progress.
100
toArray method
 toArray: translate contents of a Collection into an array.
 a bridge between collections and older APIs that expect arrays on
input
 Object[] toArray(); //creates a new array of Object.
 <T> T[] toArray(T[] a); //allows caller to provide an
array or to choose runtime type of output array.
 E.g, to dump contents of a Collection c into a newly allocated
array of Object
 Object[] a = c.toArray();
 E.g., suppose that c is known to contain only string, to dumps
contents of c into a newly allocated array of String:
101
 String[] a = c.toArray(new String[0]);
Java Collection Framework:
Interfaces
102
Maps
 Map interface: associates keys to values, one-to-one
mapping (no duplicate keys)
 Implementation classes
Hashtable, HashMap


Store elements in hash tables
TreeMap


Store elements in trees
 Interface SortedMap
 Extends Map
 Maintains its keys in sorted order
103
hash table
 Hash tables: data structure that use hashing, an algorithm for
determining a key in table
 Each table cell is a hash “bucket”, i.e., linked list of all key-value
pairs that hash to that cell (collision)
 Load factor in a hash table: average length of bucket
Hash table
104
Outline
1
// Fig. 19.20: WordTypeCount.java
2
// Program counts the number of occurrences of each word in a string
3
import java.util.StringTokenizer;
4
5
import java.util.Map;
import java.util.HashMap;
6
import java.util.Set;
7
8
import java.util.TreeSet;
import java.util.Scanner;
9
10 public class WordTypeCount
11 {
12
13
private Map< String, Integer > map;
private Scanner scanner;
14
105
Create an empty HashMap with
a default capacity 16 and a
default load factor 0.75. The
keys are of type String and
the values are of type Integer
15
16
17
18
public WordTypeCount()
{
map = new HashMap< String, Integer >(); // create HashMap
scanner = new Scanner( System.in ); // create scanner
19
20
21
22
createMap(); // create map based on user input
displayMap(); // display map content
} // end WordTypeCount constructor
23
24
25
26
27
Outline
{
System.out.println( "Enter a string:" ); // prompt for user input
String input = scanner.nextLine();
28
29
30
31
// create StringTokenizer for input
StringTokenizer tokenizer = new StringTokenizer( input );
32
// processing input text
33
34
35
while ( tokenizer.hasMoreTokens() ) //
{
String word = tokenizer.nextToken().toLowerCase(); // get word
containsKey: whether a key
as an argument is in hash table
whilespecified
more input
36
37
// if the map contains the word
38
39
if ( map.containsKey( word ) ) // is word
{
40
41
42
int count = map.get( word ); // get current count
map.put( word, count + 1 ); // increment count
} // end if
43
44
45
46
47
106
// create map from user input
private void createMap()
Create a StringTokenizer to break
input string into individual words
Use method get to obtain the key’s
in map
associated value in the map
else
map.put( word, 1 ); // add new word with a count of 1 to map
} // end while
} // end method createMap
Increment the value and use method put
to replace the key’s associated value
Outline
48
// display map content
49
private void displayMap()
50
{
Use HashMap method keySet to
obtain a set of the keys
Set< String > keys = map.keySet(); // get keys
51
52
53
// sort keys
54
TreeSet< String > sortedKeys = new TreeSet< String >( keys );
55
System.out.println( "Map contains:\nKey\t\tValue" );
56
57
58
// generate output for each key in map
59
for ( String key : sortedKeys )
Access each key and its
value in the map
System.out.printf( "%-10s%10s\n", key, map.get( key ) );
60
61
System.out.printf(
62
"\nsize:%d\nisEmpty:%b\n", map.size(), map.isEmpty() );
63
} // end method displayMap
64
65
Call Map method size to get the
number of key-value pairs in the Map
107
Call Map method isEmpty to
determine whether the Map is empty
66
67
public static void main( String args[] )
{
68
69
new WordTypeCount();
} // end main
Outline
70 } // end class WordTypeCount
Enter a string:
To be or not to be: that is the question Whether 'tis nobler to suffer
Map contains:
Key
Value
'tis
1
be
1
be:
1
is
1
nobler
1
not
1
or
1
question
1
suffer
1
that
1
the
1
to
3
whether
1
size:13
isEmpty:false
108
Collections algorithms
 Collections framework provides set of algorithms,
implemented as static methods of Collections class
109
Algorithm
Description
sort
Sorts the elements of a List.
binarySearch
Locates an object in a List.
reverse
Reverses the elements of a List.
shuffle
Randomly orders a List’s elements.
fill
Sets every List element to refer to a specified object.
Copy
Copies references from one List into another.
min
Returns the smallest element in a Collection.
max
Returns the largest element in a Collection.
addAll
Appends all elements in an array to a collection.
frequency
Calculates how many elements in the collection are equal to the
specified element.
disjoint
Determines whether two collections have no elements in common.
Software Engineering Observation
 Collections framework algorithms are polymorphic method
 first argument is the collection on which the operation is to be
performed.
 majority of the algorithms operate on List instances,
 a few operate on arbitrary Collection instances.
 Each algorithm can operate on objects that implement specific
interfaces, regardless of the underlying implementations.
110
Algorithm sort
 sort
 Sorts List elements
 Order is determined by natural order of elements’ type
 List elements must implement the Comparable interface
 Or, pass a Comparator to method sort
 Sorting in ascending order
 Collections method sort
 Sorting in descending order
 Collections static method reverseOrder
 Sorting with a Comparator
 Create a custom Comparator class
111
Example
import java.util.*;
public class Sort {
public static void main(String[] args) {
List<String> list = Arrays.asList(args);
Collections.sort(list);
System.out.println(list);
}
}
112
1
2
// Fig. 19.8: Sort1.java
// Using algorithm sort.
3
import java.util.List;
4
import java.util.Arrays;
5
import java.util.Collections;
6
7
8
9
public class Sort1
{
private static final String suits[] =
Outline
{ "Hearts", "Diamonds", "Clubs", "Spades" };
10
11
12
// display array elements
13
public void printElements()
14
15
16
{
113
List< String > list = Arrays.asList( suits ); // create List
Create List of Strings
17
18
19
// output list
Outline
System.out.printf( "Unsorted array elements:\n%s\n", list );
Collections.sort( list ); // sort ArrayList
20
21
22
// output list
23
System.out.printf( "Sorted array elements:\n%s\n", list );
24
} // end method printElements
25
26
public static void main( String args[] )
27
{
28
Sort1 sort1 = new Sort1();
29
sort1.printElements();
30
} // end main
31 } // end class Sort1
Unsorted array elements:
[Hearts, Diamonds, Clubs, Spades]
Sorted array elements:
[Clubs, Diamonds, Hearts, Spades]
114
Implicit call to the list’
toString method to
output the list contents
Use algorithm sort to order the
elements of list in ascending order
Outline
1
// Fig. 19.9: Sort2.java
2
3
// Using a Comparator object with algorithm sort.
import java.util.List;
4
import java.util.Arrays;
5
import java.util.Collections;
6
7
public class Sort2
8
{
9
10
private static final String suits[] =
{ "Hearts", "Diamonds", "Clubs", "Spades" };
11
12
// output List elements
13
14
public void printElements()
{
15
16
115
List list = Arrays.asList( suits ); // create List
// output List elements
17
Outline
System.out.printf( "Unsorted array
18
19
Method reverseOrder of class
Collections returns a
Comparator
object that represents
elements:\n%s\n",
list );
the collection’s reverse order
20
// sort in descending order using a comparator
21
Collections.sort( list, Collections.reverseOrder() );
22
23
// output List elements
24
System.out.printf( "Sorted list elements:\n%s\n", list );
25
} // end method printElements
26
27
public static void main( String args[] )
28
{
29
Sort2 sort2 = new Sort2();
30
sort2.printElements();
31
} // end main
32 } // end class Sort2
Unsorted array elements:
[Hearts, Diamonds, Clubs, Spades]
Sorted list elements:
[Spades, Hearts, Diamonds, Clubs]
116
Method sort of class Collections can use a
Comparator object to sort a List
1
2
3
4
5
Outline
import java.util.Comparator;
public class TimeComparator implements Comparator< Time2 >
6 {
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public int compare( Time2 tim1, Time2 time2 )
{
int hourCompare = time1.getHour() - time2.getHour(); // compare hour
// test the hour first
if ( hourCompare != 0 )
return hourCompare;
Implement method compare to determine
the order of two Time2 objects
int minuteCompare =
time1.getMinute() - time2.getMinute(); // compare minute
// then test the minute
if ( minuteCompare != 0 )
return minuteCompare;
int secondCompare =
time1.getSecond() - time2.getSecond(); // compare second
return secondCompare; // return result of comparing seconds
} // end method compare
27 } // end class TimeComparator
117
Custom comparator TimeComparator
Comparator interface and
compares Time2 object
// Fig. 19.10: TimeComparator.java
implements
// Custom Comparator class that compares two Time2 objects.
1
// Fig. 19.11: Sort3.java
2
// Sort a list using the custom Comparator class TimeComparator.
3
import java.util.List;
4
import java.util.ArrayList;
5
import java.util.Collections;
Outline
6
7
8
118
public class Sort3
{
9
public void printElements()
10
{
11
12
List< Time2 > list = new ArrayList< Time2 >(); // create List
13
14
list.add( new Time2( 6, 24, 34 ) );
list.add( new Time2( 18, 14, 58 ) );
15
16
17
18
list.add( new Time2( 6, 05, 34 ) );
list.add( new Time2( 12, 14, 58 ) );
list.add( new Time2( 6, 24, 22 ) );
19
20
Outline
// output List elements
System.out.printf( "Unsorted array elements:\n%s\n", list );
21
22
// sort in order using a comparator
23
Collections.sort( list, new TimeComparator() );
24
25
26
// output List elements
System.out.printf( "Sorted list elements:\n%s\n", list );
27
28
29
30
} // end method printElements
31
Sort3 sort3 = new Sort3();
public static void main( String args[] )
{
Sort in order using a custom
comparator TimeComparator
32
sort3.printElements();
33
} // end main
34 } // end class Sort3
Unsorted array elements:
[6:24:34 AM, 6:14:58 PM, 6:05:34 AM, 12:14:58 PM, 6:24:22 AM]
Sorted list elements:
[6:05:34 AM, 6:24:22 AM, 6:24:34 AM, 12:14:58 PM, 6:14:58 PM]
119
Algorithms on List
 reverse: Reverses the order of List elements
 fill: populates List elements with values
 copy: Creates copy of a List
 max: Returns largest element in List
 min: Returns smallest element in List
 binarySearch:
120
Locates object in List
1
// Fig. 19.13: Algorithms1.java
2
// Using algorithms reverse, fill, copy, min and max.
3
4
5
Outline
import java.util.List;
import java.util.Arrays;
import java.util.Collections;
6
7 public class Algorithms1
8 {
9
private Character[] letters = { ‘P’, ‘C’, ‘M’ };
10
private Character[] lettersCopy;
11
12
private List< Character > list;
private List< Character > copyList;
13
14
15
// create a List and manipulate it with methods from Collections
public Algorithms1()
16
17
list = Arrays.asList( letters ); // get List
18
lettersCopy = new Character[ 3 ];
19
20
copyList = Arrays.asList( lettersCopy ); // list view of lettersCopy
21
22
System.out.println( "Initial list: " );
output( list );
23
24
Collections.reverse( list ); // reverse order
25
26
27
121
{
Use method reverse of
class Collections to
obtain List in reverse order
System.out.println( "\nAfter calling reverse: " );
output( list );
28
29
30
Outline
Collections.copy( copyList, list ); // copy List
System.out.println( "\nAfter copying: " );
output( copyList );
Use method copy of class
Collections to obtain copy of List
31
32
Collections.fill( list, ‘R’ ); // fill list with Rs
33
System.out.println( "\nAfter calling fill: " );
34
output( list );
35
} // end Algorithms1 constructor
36
Use method fill of class Collections
to populate List with the letter ‘R’
37
// output List information
38
private void output( List< Character > listRef )
39
{
40
System.out.print( "The list is: " );
41
42
43
for ( Character element : listRef )
System.out.printf( "%s ", element );
44
45
System.out.printf( "\nMax: %s", Collections.max( listRef ) );
46
System.out.printf( "
47
48
122
Min: %s\n", Collections.min( listRef ) );
} // end method output
Obtain minimum value in List
49
50
51
52
public static void main( String args[] )
Outline
{
new Algorithms1();
} // end main
53 } // end class Algorithms1
Initial list:
The list is: P C M
Max: P Min: C
After calling reverse:
The list is: M C P
Max: P Min: C
After copying:
The list is: M C P
Max: P Min: C
After calling fill:
The list is: R R R
Max: R Min: R
123
Algorithm binarySearch
 binarySearch locates object in List
 Returns index of object in List if object exists
 Returns negative value if Object does not exist
 Calculate insertion point: if the object is to be inserted into
the List, where should it be inserted ?
 Make the insertion point sign negative
 Subtract 1 from insertion point (Why ?)
124
1
2
3
// Fig. 19.14: BinarySearchTest.java
Outline
// Using algorithm binarySearch.
import java.util.List;
4
import java.util.Arrays;
5
6
import java.util.Collections;
import java.util.ArrayList;
7
8 public class BinarySearchTest
9 {
10
private static final String colors[] = { "red", "white",
125
11
12
13
14
15
"blue", "black", "yellow", "purple", "tan", "pink" };
private List< String > list; // ArrayList reference
16
17
18
19
20
21
{
// create, sort and output list
public BinarySearchTest()
list = new ArrayList< String >( Arrays.asList( colors ) );
Collections.sort( list ); // sort the ArrayList Sort List in
System.out.printf( "Sorted ArrayList: %s\n", list );
} // end BinarySearchTest constructor
ascending order
22
23
24
25
26
Outline
{
printSearchResults( colors[ 3 ] ); // first item
printSearchResults( colors[ 0 ] ); // middle item
27
28
29
printSearchResults( colors[ 7 ] ); // last item
printSearchResults( "aqua" ); // below lowest
printSearchResults( "gray" ); // does not exist
30
31
printSearchResults( "teal" ); // does not exist
} // end method search
32
33
34
// perform searches and display search result
private void printSearchResults( String key )
35
{
36
37
38
39
40
41
42
43
44
45
46
126
// search list for various values
private void search()
int result = 0;
Use method binarySearch
of class Collections to
search list for specified key
System.out.printf( "\nSearching for: %s\n", key );
result = Collections.binarySearch( list, key );
if ( result >= 0 )
System.out.printf( "Found at index %d\n", result );
else
System.out.printf( "Not Found (%d)\n",result );
} // end method printSearchResults
47
48
49
Outline
public static void main( String args[] )
{
BinarySearchTest binarySearchTest = new BinarySearchTest();
50
binarySearchTest.search();
51
} // end main
52 } // end class BinarySearchTest
Sorted ArrayList: [black, blue, pink, purple, red, tan, white, yellow]
Searching for: black
Found at index 0
Searching for: red
Found at index 4
Searching for: pink
Found at index 2
Searching for: aqua
Not Found (-1)
Searching for: gray
Not Found (-3)
Searching for: teal
Not Found (-7)
127
Algorithms addAll, frequency and
disjoint
 addAll
 Insert all elements of an array into a collection
 frequency
 Calculate the number of times a specific element appear in the
collection
 Disjoint
 Determine whether two collections have elements in common
128
1
2
3
4
5
6
7
8
9
Outline
import java.util.Vector;
import java.util.Arrays;
import java.util.Collections;
public class Algorithms2
{
10
11
12
13
private String[] colors = { "red", "white", "yellow", "blue" };
private List< String > list;
private Vector< String > vector = new Vector< String >();
14
15
16
// create List and Vector
// and manipulate them with methods from Collections
public Algorithms2()
17
18
19
20
21
22
{
23
24
25
129
// Fig. 19.15: Algorithms2.java
// Using algorithms addAll, frequency and disjoint.
import java.util.List;
// initialize list and vector
list = Arrays.asList( colors );
vector.add( "black" );
vector.add( "red" );
vector.add( "green" );
System.out.println( "Before addAll, vector contains: " );
26
27
28
29
30
31
32
33
Outline
// display elements in vector
for ( String s : vector )
System.out.printf( "%s ", s );
// add elements in colors to list
Collections.addAll( vector, colors );
Invoke method addAll to
add elements in array
colors to vector
System.out.println( "\n\nAfter addAll, vector contains: " );
34
35
36
// display elements in vector
for ( String s : vector )
System.out.printf( "%s ", s );
37
38
39
// get frequency of "red"
40
int frequency = Collections.frequency( vector, "red" );
41
42
43
System.out.printf(
"\n\nFrequency of red in vector: %d\n", frequency );
130
Get the frequency of String
“red” in Collection vector
using method frequency
44
45
46
Outline
// check whether list and vector have elements in common
boolean disjoint = Collections.disjoint( list, vector );
47
48
49
50
System.out.printf( "\nlist and vector %s elements
in common\n",
Invoke
method disjoint to test
( disjoint ? "do not have" : "have" ) );
whether Collections list and
} // end Algorithms2 constructor
vector have elements in common
51
52
public static void main( String args[] )
{
53
54
new Algorithms2();
} // end main
55 } // end class Algorithms2
Before addAll, vector contains:
black red green
After addAll, vector contains:
black red green red white yellow blue
Frequency of red in vector: 2
list and vector have elements in common
131
Synchronized Collections
 Built-in collections are unsynchronized
 Concurrent access to a Collection can cause errors
 Java provides synchronization wrappers to avoid this
 Via set of public static methods
public static method headers
< T > Collection< T > synchronizedCollection( Collection< T > c )
< T > List< T > synchronizedList( List< T > aList )
< T > Set< T > synchronizedSet( Set< T > s )
< T > SortedSet< T > synchronizedSortedSet( SortedSet< T > s )
< K, V > Map< K, V > synchronizedMap( Map< K, V > m )
< K, V > SortedMap< K, V > synchronizedSortedMap( SortedMap< K, V > m )
132
Unmodifiable Collections
 Unmodifiable wrapper
 Converting collections to unmodifiable collections
 Throw UnsorrtedOperationException if attempts
are made to modify the collection
public static method headers
< T > Collection< T > unmodifiableCollection( Collection< T > c )
< T > List< T > unmodifiableList( List< T > aList )
< T > Set< T > unmodifiableSet( Set< T > s )
< T > SortedSet< T > unmodifiableSortedSet( SortedSet< T > s )
< K, V > Map< K, V > unmodifiableMap( Map< K, V > m )
< K, V > SortedMap< K, V > unmodifiableSortedMap( SortedMap< K, V > m )
133