Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

AhmadLang / Java, How To Program, 2004

.pdf
Скачиваний:
626
Добавлен:
31.05.2015
Размер:
51.82 Mб
Скачать

[Page 902 (continued)]

Answers to Self-Review Exercises

18.1 a) False. Generic methods and non-generic methods can have same method name. A generic method can overload another generic method with the same method name but different method parameters. A generic method also can be overloaded by providing non-generic methods with the same method name and number of arguments. b) False. All generic method declarations have a type parameter section that immediately precedes the method's return type. c) True. d) True. e) False. Type parameter names among different generic methods need not be unique. f) True.

18.2 a) Generic methods, generic classes. b) angle brackets (< and >). c) type parameters. d) a raw type. e) type parameter section. f) ? extends E .

[Page 902 (continued)]

Exercises

18.3Explain the use of the following notation in a Java program: public class Array< T > { }

18.4Write a generic method selectionSort based on the sort program of Fig. 16.6 and Fig. 16.7. Write a test program that inputs, sorts and outputs an Integer array and a

Float array. [Hint: Use < T extends Comparable< T > > in the type parameter section for method selectionSort, so that you can use method compareTo to compare the objects of two generic types T.]

18.5Overload generic method printArray of Fig. 18.3 so that it takes two additional integer arguments, lowSubscript and highSubscript. A call to this method prints only the designated portion of the array. Validate lowSubscript and highSubscript. If either is out-of-range, or if highSubscript is less than or equal to lowSubscript, the overloaded printArray method should throw an InvalidSubscriptException; otherwise, printArray should return the number of elements printed. Then modify main to exercise both versions of printArray on arrays integerArray, doubleArray and characterArray. Test all capabilities of both versions of printArray.

18.6Overload generic method printArray of Fig. 18.3 with a non-generic version that specifically prints an array of strings in neat, tabular format, as shown in the sample output that follows:

Array

stringArray

contains:

 

one

two

three

four

five

six

seven

eight

 

 

 

 

[Page 903]

18.7Write a simple generic version of method isEqualTo that compares its two arguments with the equals method and returns TRue if they are equal and false otherwise. Use this generic method in a program that calls isEqualTo with a variety of built-in types, such as Object or Integer. What result do you get when you attempt to run this program?

18.8Write a generic class Pair which has two type parametersF and S, each represents the type of the first and second element of the pair respectively. Add get and set methods for the first and second elements of the pair. [Hint: The class header should be public class Pair< F, S >.]

18.9Convert classes TReeNode and tree from Fig. 17.17 into generic classes. To insert an object in a tree, the object must be compared to the objects in existing treeNodes. For this reason, classes treeNode and tree should specify Comparable< E > as the upper bound of each class's type parameter. After modifying classes treeNode and tree, write a test application that creates three tree objectsone that stores Integers, one that stores Doubles and one that stores Strings. Insert 10 values into

each tree. Then output the preorder, inorder and postorder traversals for each tree.

18.10Modify your test program from Exercise 18.9 to use a generic method named testTree to test the three TRee objects. The method should be called three timesonce for each TRee object.

18.11How can generic methods be overloaded?

18.12The compiler performs a matching process to determine which method to call when a method is invoked. Under what circumstances does an attempt to make a match result in a compile-time error?

18.13Explain why a Java program might use the statement

ArrayList< Employee > workerList = new ArrayList< Employee >();

[Page 904]

Chapter 19. Collections

I think this is the most extraordinary collection of talent, of human knowledge, that has ever been gathered together at the White Housewith the possible exception of when Thomas Jefferson dined alone.

John F. Kennedy

The shapes a bright container can contain!

Theodore Roethke

Journey over all the universe in a map.

Miguel de Cervantes

Not by age but by capacity is wisdom acquired.

Titus Maccius Plautus

It is a riddle wrapped in a mystery inside an enigma.

Winston Churchill

OBJECTIVES

In this chapter you will learn:

What collections are.

To use class Arrays for array manipulations.

To use the collections framework (prepackaged data structure) implementations.

To use collections framework algorithms to manipulate (such as search, sort and fill) collections.

To use the collections framework interfaces to program with collections polymorphically.

To use iterators to "walk through" a collection.

To use persistent hash tables manipulated with objects of class Properties.

To use synchronization and modifiability wrappers.

[Page 905]

Outline

19.1 Introduction

19.2 Collections Overview

19.3 Class Arrays

19.4 Interface Collection and Class Collections

19.5 Lists

19.5.1 ArrayList and Iterator

19.5.2 LinkedList

19.5.3 Vector

19.6 Collections Algorithms

19.6.1 Algorithm sort

19.6.2 Algorithm shuffle

19.6.3 Algorithms reverse, fill, copy, max and min

19.6.4 Algorithm binarySearch

19.6.5 Algorithms addAll, frequency and disjoint

19.7 Stack Class of Package java.util

19.8 Class PriorityQueue and Interface Queue

19.9 Sets

19.10 Maps

19.11 Properties Class

19.12 Synchronized Collections

19.13 Unmodifiable Collections

19.14 Abstract Implementations

19.15 Wrap-Up

Summary

Terminology

Self-Review Exercises

Answers to Self-Review Exercises

Exercises

[Page 905 (continued)]

19.1. Introduction

In Chapter 17, we discussed how to create and manipulate data structures. The discussion was "low level" in the sense that we painstakingly created each element of each data structure dynamically and modified the data structures by directly manipulating their elements and the references to their elements. In this chapter, we consider the Java collections framework, which contains prepackaged data structures, interfaces and algorithms for manipulating those data structures. Some examples of collections are the cards you hold in a card game, your favorite songs stored in your computer, the members of a sports team and the real-estate records in your local registry of deeds (which map book numbers and page numbers to property owners). In this chapter, we also discuss how generics (see Chapter 18) are used in the Java collections framework.

With collections, programmers use existing data structures, without concern for how they are implemented. This is a marvelous example of code reuse. Programmers can code faster and can expect excellent performance, maximizing execution speed and minimizing memory consumption. In this chapter, we discuss the collections framework interfaces that list the capabilities of each collection type, the implementation classes, the algorithms that process the collections, and the so-called iterators and enhanced for statement syntax that "walk through" collections. This chapter provides an introduction to the collections framework. For complete details, visit java.sun.com/j2se/5.0/docs/guide/collections.

[Page 906]

The Java collections framework provides ready-to-go, reusable componentryyou do not need to write your own collection classes, but you can if you wish to. The collections are standardized so that applications can share them easily without concern with for details of their implementation. The collections framework encourages further reusability. As new data structures and algorithms are developed that fit this framework, a large base of programmers will already be familiar with the interfaces and algorithms implemented by those data structures.

[Page 906 (continued)]

19.2. Collections Overview

A collection is a data structureactually, an objectthat can hold references to other objects. Usually, collections contain references to objects that are all of the same type. The collections framework interfaces declare the operations to be performed generically on various types of collections. Figure 19.1 lists some of the interfaces of the collections framework. Several implementations of these interfaces are provided within the framework. Programmers may also provide implementations specific to their own requirements.

Figure 19.1. Some collection framework interfaces.

Interface

Description

 

 

Collection

The root interface in the collections hierarchy from which interfaces

 

Set, Queue and List are derived.

Set

A collection that does not contain duplicates.

List

An ordered collection that can contain duplicate elements.

Map

Associates keys to values and cannot contain duplicate keys.

Queue

Typically a first-in, first-out collection that models a waiting line;

 

other orders can be specified.

 

 

The collections framework provides high-performance, high-quality implementations of common data structures and enables software reuse. These features minimize the amount of coding programmers need to do to create and manipulate collections. The classes and interfaces of the collections framework are members of package java.util. In the next section, we begin our discussion by examining the collections framework capabilities for array manipulation.

In earlier versions of Java, the classes in the collections framework stored and manipulated Object references. Thus, you could store any object in a collection. One inconvenient aspect of storing Object references occurs when retrieving them from a collection. A program normally has the need to process specific types of objects. As a result, the Object references obtained from a collection typically need to be cast to an appropriate type to allow the program to process the objects correctly.

In J2SE 5.0, the collections framework has been enhanced with the generics capabilities we introduced in Chapter 18. This means that you can specify the exact type that will be stored in a collection. You also receive the benefits of compile-time type checkingthe compiler ensures that you are using appropriate types with your collection and, if not, issues compile-time error messages. Also, once you specify the type stored in a collection, any reference you retrieve from the collection will have the specified type. This eliminates the need for explicit type casts that can throw ClassCastExceptions if the referenced object is not of the appropriate type. Programs that were implemented with prior java versions and that use collections can compile properly because the compiler automatically uses raw types when it encounters collections for which type arguments were not specified.

[Page 907]

[Page 907 (continued)]

19.3. Class Arrays

Class Arrays provides static methods for manipulating arrays. In Chapter 7, our discussion of array manipulation was low level in the sense that we wrote the actual code to sort and search arrays. Class Arrays provides high-level methods, such as sort for sorting an array, binarySearch for searching a sorted array, equals for comparing arrays and fill for placing values into an array. These methods are overloaded for primitive-type arrays and Object arrays. In addition, methods sort and binarySearch are overloaded with generic versions that allow programmers to sort and search arrays containing objects of any type. Figure 19.2 demonstrates methods fill, sort, binarySearch and equals. Method main (lines 6585) creates a UsingArrays object and invokes its methods.

Figure 19.2. Arrays class methods.

(This item is displayed on pages 908 - 909 in the print version)

1// Fig. 19.2: UsingArrays.java

2// Using Java arrays.

3import java.util.Arrays;

4

5public class UsingArrays

6{

7

private int

intArray[] = { 1

,

2,

3

, 4

, 5

,

6 };

 

8

private

double doubleArray[]

 

= {

8

.4,

9.

3

, 0.

2

, 7.9, 3.4 };

9

private

int

filledIntArray[],

intArrayCopy[];

 

 

10

11// constructor initializes arrays

12public UsingArrays()

13{

14

filledIntArray

= new int

[ 10 ]; // create int array with 10 elements

15

intArrayCopy =

new int [

intArray.length ];

16

 

 

 

17Arrays.fill( filledIntArray, 7 ); // fill with 7s

18Arrays.sort( doubleArray ); // sort doubleArray ascending

20// copy array intArray into array intArrayCopy

21System.arraycopy( intArray, 0, intArrayCopy,

220, intArray.length );

23} // end UsingArrays constructor

25// output values in each array

26public void printArrays()

27{

28System.out.print( "doubleArray: " );

29for ( double doubleValue : doubleArray )

30System.out.printf( "%.1f ", doubleValue );

32System.out.print( "\nintArray: " );

33for ( int intValue : intArray )

34

System.out.printf( "%d ", intValue );

35

 

36System.out.print( "\nfilledIntArray: " );

37for ( int intValue : filledIntArray )

38System.out.printf( "%d ", intValue );

40System.out.print( "\nintArrayCopy: " );

41for ( int intValue : intArrayCopy )

42

System.out.printf( "%d ", intValue );

43

 

44System.out.println( "\n" );

45} // end method printArrays

46

47// find value in array intArray

48public int searchForInt( int value )

49{

50return Arrays.binarySearch( intArray, value );

51 } // end method searchForInt

52

53// compare array contents

54public void printEquality()

55{

56boolean b = Arrays.equals( intArray, intArrayCopy );

57System.out.printf( "intArray %s intArrayCopy\n",

58( b ? "==" : "!=" ) );

59

60b = Arrays.equals( intArray, filledIntArray );

61System.out.printf( "intArray %s filledIntArray\n",

62( b ? "==" : "!=" ) );

63} // end method printEquality

64

65public static void main( String args[] )

66{

67UsingArrays usingArrays = new UsingArrays();

69usingArrays.printArrays();

70usingArrays.printEquality();

72int location = usingArrays.searchForInt( 5 );

73if ( location >= 0 )

74

System.out.printf(

75

"Found 5 at element %d in intArray\n", location );

76else

77System.out.println( "5 not found in intArray" );

79location = usingArrays.searchForInt( 8763 );

80if ( location >= 0 )

81

System.out.printf(

82

"Found 8763 at element %d in intArray\n", location );

83else

84System.out.println( "8763 not found in intArray" );

85} // end main

86} // end class UsingArrays

doubleArray: 0.2 3.4 7.9 8.4 9.3 intArray: 1 2 3 4 5 6 filledIntArray: 7 7 7 7 7 7 7 7 7 7 intArrayCopy: 1 2 3 4 5 6

intArray == intArrayCopy intArray != filledIntArray

Found 5 at element 4 in intArray 8763 not found in intArray

Line 17 calls static method fill of class Arrays to populate all 10 elements of filledIntArray with 7s. Overloaded versions of fill allow the programmer to populate a specific range of elements with the same value.

Line 18 sorts the elements of array doubleArray. The static method sort of class Arrays orders the array's elements in ascending order by default. We discuss how to sort in descending order later in the chapter. Overloaded versions of sort allow the programmer to sort a specific range of elements.

Lines 2122 copy array intArray into array intArrayCopy. The first argument (intArray) passed to System method arraycopy is the array from which elements are to be copied. The second argument (0) is the index that specifies the starting point in the range of elements to copy from the array. This value can be any valid array index. The third argument (intArrayCopy) specifies the destination array that will store the copy. The fourth argument (0) specifies the index in the destination array where the first copied element should be stored. The last argument specifies the number of elements to copy from the array in the first argument. In this case, we copy all the elements in the array.

Line 50 calls static method binarySearch of class Arrays to perform a binary search on intArray, using value as the key. If value is found, binarySearch returns the index of the element; otherwise,

binarySearch returns a negative value. The negative value returned is based on the search key's insertion pointthe index where the key would be inserted in the array if we were performing an insert operation. After binarySearch determines the insertion point, it changes its sign to negative and subtracts 1 to obtain the return value. For example, in Fig. 19.2, the insertion point for the value 8763 is the element with index 6 in the array. Method binarySearch changes the insertion point to 6, subtracts 1 from it and returns the value 7. Subtracting 1 from the insertion point guarantees that method binarySearch returns positive values (>=0) if and only if the key is found. This return value is useful for inserting elements in a sorted array. Chapter 16, Searching and Sorting, discusses binary searching in detail.

[Page 909]

Common Programming Error 19.1

Passing an unsorted array to binarySearch is a logic errorthe value returned is undefined.

Lines 56 and 60 call static method equals of class Arrays to determine whether the elements of two arrays are equivalent. If the arrays contain the same elements in the same order, the method returns true; otherwise, it returns false. The equality of each element is compared using Object method equals. Many classes override method equals to perform the comparisons in a manner specific to those classes. For example, class String declares equals to compare the individual characters in the two Strings being compared. If method equals is not overridden, the original version of method equals inherited from class Object is used.

[Page 910]