Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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