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

AhmadLang / Java, How To Program, 2004

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

vector contains: red white blue

First element: red

Last element: blue

"red" found at index 0

"red" has been removed vector contains: white blue

"red" not found

Size: 2

Capacity: 10

The application's constructor creates a Vector (line 13) of type String with an initial capacity of 10 elements and capacity increment of zero (the defaults for a Vector). Note that Vector is a generic class, which takes one argument that specifies the type of the elements stored in the Vector. A capacity increment of zero indicates that this Vector will double in size each time it needs to grow to accommodate more elements. Class Vector provides three other constructors. The constructor that takes one integer argument creates an empty Vector with the initial capacity specified by that argument. The constructor that takes two arguments creates a Vector with the initial capacity specified by the first argument and the capacity increment specified by the second argument. Each time the Vector needs to grow, it will add space for the specified number of elements in the capacity increment. The constructor that takes a Collection creates a copy of a collection's elements and stores them in the Vector.

[Page 921]

Line 18 calls Vector method add to add objects (Strings in this program) to the end of the Vector. If necessary, the Vector increases its capacity to accommodate the new element. Class Vector also provides a method add that takes two arguments. This method takes an object and an integer and inserts the object at the specified index in the Vector. Method set will replace the element at a specified position in the Vector with a specified element. Method insertElementAt provides the same functionality as the method add that takes two arguments, except that the order of the parameters is reversed.

Line 25 calls Vector method firstElement to return a reference to the first element in the Vector. Line 26 calls Vector method lastElement to return a reference to the last element in the Vector. Each of these methods throws a NoSuchElementException if there are no elements in the Vector when the method is called.

Line 35 calls Vector method contains to determine whether the Vector contains "red". The method returns true if its argument is in the Vectorotherwise, the method returns false. Method contains uses Object method equals to determine whether the search key is equal to one of the Vector's elements. 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 922]

Common Programming Error 19.4

Without overriding method equals, the program performs comparisons using operator == to determine whether two references refer to the same object in memory.

Line 37 calls Vector method indexOf to determine the index of the first location in the Vector that contains the argument. The method returns 1 if the argument is not found in the Vector. An overloaded version of this method takes a second argument specifying the index in the Vector at which the search should begin.

Performance Tip 19.6

Vector methods contains and indexOf perform linear searches of a Vector's contents. These searches are inefficient for large Vectors. If a program frequently searches for elements in a collection, consider using one of the Java Collection API's Map implementations (Section 19.10), which provide high-speed searching capabilities.

Line 41 calls Vector method remove to remove the first occurrence of its argument from the Vector. The method returns true if it finds the element in the Vector; otherwise, the method returns false. If the element is removed, all elements after that element in the Vector shift one position toward the beginning of the Vector to fill in the position of the removed element. Class Vector also provides method

removeAllElements to remove every element from a Vector and method removeElementAt to remove the element at a specified index.

Lines 5354 use Vector methods size and capacity to determine the number of elements currently in the Vector and the number of elements that can be stored in the Vector without allocating more memory, respectively.

Line 59 calls Vector method isEmpty to determine whether the Vector is empty. The method returns TRue if there are no elements in the Vector; otherwise, the method returns false. Lines 6667 use the enhanced for statement to print out all elements in the vector.

Among the methods introduced in Fig. 19.6, firstElement, lastElement and capacity can be used only with Vector. Other methods (e.g., add, contains, indexOf, remove, size and isEmpty) are declared by List, which means that they can be used by any class that implements List, such as Vector.

[Page 922 (continued)]

19.6. Collections Algorithms

The collections framework provides several high-performance algorithms for manipulating collection elements. These algorithms are implemented as static methods of class Collections (Fig. 19.7). Algorithms sort, binarySearch, reverse, shuffle, fill and copy operate on Lists. Algorithms min, max, addAll, frequency and disjoint operate on Collections.

 

[Page 923]

 

Figure 19.7. Collections algorithms.

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 19.4

The collections framework algorithms are polymorphic. That is, each algorithm can operate on objects that implement specific interfaces, regardless of the underlying implementations.

19.6.1. Algorithm sort

Algorithm sort sorts the elements of a List, which must implement the Comparable interface. The order is determined by the natural order of the elements' type as implemented by its class's compareTo method. Method compareTo is declared in interface Comparable and is sometimes called the natural comparison method. The sort call may specify as a second argument a Comparator object that determines an alternative ordering of the elements.

Sorting in Ascending Order

Figure 19.8 uses algorithm sort to order the elements of a List in ascending order (line 20). Recall that List is a generic type and accepts one type argument that specifies the list element typeline 15 declares list as a List of String. Note that lines 18 and 23 each use an implicit call to the list's toString method to output the list contents in the format shown on the second and fourth lines of the output.

Figure 19.8. Collections method sort.

(This item is displayed on page 924 in the print version)

1// Fig. 19.8: Sort1.java

2// Using algorithm sort.

3import java.util.List;

4import java.util.Arrays;

5import java.util.Collections;

7public class Sort1

8{

9private static final String suits[] =

10{ "Hearts", "Diamonds", "Clubs", "Spades" };

12// display array elements

13public void printElements()

14{

15List< String > list = Arrays.asList( suits ); // create List

17// output list

18System.out.printf( "Unsorted array elements:\n%s\n", list );

20Collections.sort( list ); // sort ArrayList

22// output list

23System.out.printf( "Sorted array elements:\n%s\n", list );

24} // end method printElements

26public static void main( String args[] )

27{

28Sort1 sort1 = new Sort1();

29sort1.printElements();

30} // end main

31} // end class Sort1

Unsorted array elements:

[Hearts, Diamonds, Clubs, Spades] Sorted array elements:

[Clubs, Diamonds, Hearts, Spades]

Sorting in Descending Order

Figure 19.9 sorts the same list of strings used in Fig. 19.8 in descending order. The example introduces the Comparator interface, which is used for sorting a Collection's elements in a different order. Line 21 calls Collections's method sort to order the List in descending order. The static Collections method reverseOrder returns a Comparator object that orders the collection's elements in reverse order.

Figure 19.9. Collections method sort with a Comparator object.

(This item is displayed on pages 924 - 925 in the print version)

1 // Fig. 19.9: Sort2.java

2 // Using a Comparator object with algorithm sort.

3import java.util.List;

4import java.util.Arrays;

5import java.util.Collections;

7public class Sort2

8{

9private static final String suits[] =

10{ "Hearts", "Diamonds", "Clubs", "Spades" };

12// output List elements

13public void printElements()

14{

15List list = Arrays.asList( suits ); // create List

17// output List elements

18System.out.printf( "Unsorted array elements:\n%s\n", list );

20// sort in descending order using a comparator

21Collections.sort( list, Collections.reverseOrder() );

23// output List elements

24System.out.printf( "Sorted list elements:\n%s\n", list );

25} // end method printElements

27public static void main( String args[] )

28{

29Sort2 sort2 = new Sort2();

30sort2.printElements();

31} // end main

32} // end class Sort2

Unsorted array elements:

[Hearts, Diamonds, Clubs, Spades] Sorted list elements:

[Spades, Hearts, Diamonds, Clubs]

[Page 925]

Sorting with a Comparator

Figure 19.10 creates a custom Comparator class, named TimeComparator, that implements interface Comparator to compare two Time2 objects. Class Time2, declared in Fig. 8.5, represents times with hours, minutes and seconds.

Figure 19.10. Custom Comparator class that compares two Time2 objects.

 

 

(This item is displayed on page 926 in the print version)

1

// Fig. 19.10: TimeComparator.java

2

// Custom Comparator class that compares two Time2 objects.

3

import

java.util.Comparator;

4

 

 

5

public

class TimeComparator implements Comparator< Time2 >

6

{

 

7 public int compare( Time2 tim1, Time2 time2 )

8{

9int hourCompare = time1.getHour() - time2.getHour(); // compare hour

11// test the hour first

12if ( hourCompare != 0 )

13

return hourCompare;

14

 

15int minuteCompare =

16time1.getMinute() - time2.getMinute(); // compare minute

18// then test the minute

19if ( minuteCompare != 0 )

20

return minuteCompare;

21

 

22int secondCompare =

23time1.getSecond() - time2.getSecond(); // compare second

25return secondCompare; // return result of comparing seconds

26} // end method compare

27} // end class TimeComparator

Class TimeComparator implements interface Comparator, a generic type that takes one argument (in this case Time2). Method compare (lines 726) performs comparisons between Time2 objects. Line 9 compares the two hours of the Time2 objects. If the hours are different (line 12), then we return this value. If this value is positive, then the first hour is greater than the second and the first time is greater than the second. If this value is negative, then the first hour is less than the second and the first time is less than the second. If this value is zero, the hours are the same and we must test the minutes (and maybe the seconds) to determine which time is greater.

Figure 19.11 sorts a list using the custom Comparator class TimeComparator. Line 11 creates an ArrayList of Time2 objects. Recall that both ArrayList and List are generic types and accept a type argument that specifies the element type of the collection. Lines 1317 create five Time2 objects and add them to this list. Line 23 calls method sort, passing it an object of our TimeComparator class (Fig. 19.10).

Figure 19.11. Collections method sort with a custom Comparator object.

(This item is displayed on pages 926 - 927 in the print version)

1 // Fig. 19.11: Sort3.java

2 // Sort a list using the custom Comparator class TimeComparator.

3import java.util.List;

4import java.util.ArrayList;

5import java.util.Collections;

7public class Sort3

8{

9public void printElements()

10{

11

List< Time2 >

list =

new

ArrayList< Time2 >(); // create List

12

 

 

 

 

 

 

 

 

13

list.add(

new

Time2(

6

,

24, 34 ) );

14

list.add(

new

Time2(

18

,

14, 58

)

);

15

list.add(

new

Time2(

6

,

05, 34

)

);

16

list.add(

new

Time2(

12

,

14, 58

)

);

17

list.add(

new

Time2(

6

,

24, 22

)

);

18

 

 

 

 

 

 

 

 

19// output List elements

20System.out.printf( "Unsorted array elements:\n%s\n", list );

22// sort in order using a comparator

23Collections.sort( list, new TimeComparator() );

25// output List elements

26System.out.printf( "Sorted list elements:\n%s\n", list );

27} // end method printElements

29public static void main( String args[] )

30{

public static enum Face { Ace, Deuce, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King };
public static enum Suit { Clubs, Diamonds, Hearts, Spades };

31Sort3 sort3 = new Sort3();

32sort3.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]

[Page 927]

19.6.2. Algorithm shuffle

Algorithm shuffle randomly orders a List's elements. In Chapter 7, we presented a card shuffling and dealing simulation that used a loop to shuffle a deck of cards. In Fig. 19.12, we use algorithm shuffle to shuffle a deck of Card objects that might be used in a card game simulator.

Figure 19.12. Card shuffling and dealing with Collections method

shuffle.

(This item is displayed on pages 927 - 929 in the print version)

1// Fig. 19.12: DeckOfCards.java

2// Using algorithm shuffle.

3import java.util.List;

4import java.util.Arrays;

5import java.util.Collections;

6

7 // class to represent a Card in a deck of cards

8class Card

9{

10

11

12

13

14private final Face face; // face of card

15private final Suit suit; // suit of card

17// two-argument constructor

18public Card( Face cardFace, Suit cardSuit )

19{

20face = cardFace; // initialize face of card

21suit = cardSuit; // initialize suit of card

22} // end two-argument Card constructor

23

24// return face of the card

25public Face getFace()

26{

27return face;

28} // end method getFace

29

30// return suit of Card

31public Suit getSuit()

32{

33return suit;

34} // end method getSuit

36// return String representation of Card

37public String toString()

38{

39return String.format( "%s of %s", face, suit );

40} // end method toString

41} // end class Card

42

43// class DeckOfCards declaration

44public class DeckOfCards

45{

46

private List< Card > list; // declare List that will store Cards

47

 

48// set up deck of Cards and shuffle

49public DeckOfCards()

50{

51Card[] deck = new Card[ 52 ];

52int count = 0; // number of cards

54// populate deck with Card objects

55for ( Card.Suit suit : Card.Suit.values() )

56{

57for ( Card.Face face : Card.Face.values() )

58{

59

deck[ count ] = new Card( face, suit );

60

count++;

61} // end for

62} // end for

63

64list = Arrays.asList( deck ); // get List

65Collections.shuffle( list ); // shuffle deck

66} // end DeckOfCards constructor

67

68// output deck

69public void printCards()

70{

71// display 52 cards in two columns

72

for (

int

i

=

0; i <

list.size(); i++

)

 

73

System.out

.printf(

"%-20s%s", list.get(

i ),

74

 

( (

i

+

1 ) % 2

== 0 ) ? "\n" : "\t"

);

75

} // end

method

 

printCards

 

 

76

 

 

 

 

 

 

 

 

77public static void main( String args[] )

78{

79DeckOfCards cards = new DeckOfCards();

80cards.printCards();

81} // end main

82} // end class DeckOfCards

King

 

of

 

Diamonds

Jack

 

of

Spades

Four

 

of

 

Diamonds

Six

of

Clubs

King

 

of

 

Hearts

Nine

 

of

Diamonds

Three

of

Spades

Four

 

of

Spades

Four

 

of

 

Hearts

Seven

 

of

Spades

Five

 

of

 

Diamonds

Eight

 

of

Hearts

Queen

of

Diamonds

Five

 

of

Hearts

Seven

of

Diamonds

Seven

 

of

Hearts

Nine

 

of

 

Hearts

Three

 

of

Clubs

Ten

of

Spades

Deuce

 

of

Hearts

Three

of

Hearts

Ace

of

Spades

Six

of

Hearts

Eight

 

of

Diamonds

Six

of

Diamonds

Deuce

 

of

Clubs

Ace

of

Clubs

Ten

of

Diamonds

Eight

of

Clubs

Queen

 

of

Hearts

Jack

 

of

 

Clubs

Ten

of

Clubs

Seven

of

Clubs

Queen

 

of

Spades

Five

 

of

 

Clubs

Six

of

Spades

Nine

 

of

 

Spades

Nine

 

of

Clubs

King

 

of

 

Spades

Ace

of

Diamonds

Ten

of

Hearts

Ace

of

Hearts

Queen

of

Clubs

Deuce

 

of

Spades

Three

of

Diamonds

King

 

of

Clubs

Four

 

of

 

Clubs

Jack

 

of

Diamonds

Eight

of

Spades

Five

 

of

Spades

Jack of Hearts

Deuce of Diamonds

 

 

Class Card (lines 841) represents a card in a deck of cards. Each Card has a face and a suit. Lines 1012 declare two enum typesFace and Suitwhich represent the face and the suit of the card, respectively. Method toString (lines 3740) returns a String containing the face and suit of the Card separated by the string " of ". When an enum constant is converted to a string, the constant's identifier is used as the string representation. Normally we would use all uppercase letters for enum constants. In this example, we chose to use capital letters for only the first letter of each enum constant because we want the card to be displayed with initial capital letters for the face and the suit (e.g., "Ace of Spades").

[Page 929]

Lines 5562 populate the deck array with cards that have unique face and suit combinations. Both Face and Suit are public static enum types of class Card. To use these enum types outside of class Card, you must qualify each enum's type name with the name of the class in which it resides (i.e., Card) and a dot (.) separator. Hence, lines 55 and 57 use Card.Suit and Card.Face to declare the control variables of the for statements. Recall that method values of an enum type returns an array that contains all the constants of the enum type. Lines 5562 use enhanced for statements to construct 52 new Cards.

[Page 930]

The shuffling occurs in line 65, which calls static method shuffle of class Collections to shuffle the elements of the array. Method shuffle requires a List argument, so we must obtain a List view of the array before we can shuffle it. Line 64 invokes static method asList of class Arrays to get a List view of the deck array.

Method printCards (lines 6975) displays the deck of cards in two columns. In each iteration of the loop, lines 7374 output a card left justified in a 20-character field followed by either a newline or an empty string based on the number of cards output so far. If the number of cards is even, a newline is output; otherwise, a tab is output.

19.6.3. Algorithms reverse, fill, copy, max and min

Class Collections provides algorithms for reversing, filling and copying Lists. Algorithm reverse reverses the order of the elements in a List, and algorithm fill overwrites elements in a List with a specified value. The fill operation is useful for reinitializing a List. Algorithm copy takes two argumentsa destination List and a source List. Each source List element is copied to the destination List. The destination List must be at least as long as the source List; otherwise, an IndexOutOfBoundsException occurs. If the destination List is longer, the elements not overwritten are unchanged.

Each of the algorithms we have seen so far operates on Lists. Algorithms min and max each operate on any Collection. Algorithm min returns the smallest element in a Collection, and algorithm max returns the largest element in a Collection. Both of these algorithms can be called with a Comparator object as a second argument to perform custom comparisons of objects, such as the TimeComparator in Fig. 19.11. Figure 19.13 demonstrates the use of algorithms reverse, fill, copy, min and max. Note that the generic type List is declared to store Characters.

Figure 19.13. Collections methods reverse, fill, copy, max and min.

(This item is displayed on pages 930 - 931 in the print version)

1 // Fig. 19.13: Algorithms1.java

2 // Using algorithms reverse, fill, copy, min and max.

3import java.util.List;

4import java.util.Arrays;

5import java.util.Collections;

7public class Algorithms1

8{

9 private Character[] letters = { 'P', 'C', 'M' };

10private Character[] lettersCopy;

11private List< Character > list;

12private List< Character > copyList;

14// create a List and manipulate it with methods from Collections

15public Algorithms1()

16{

17list = Arrays.asList( letters ); // get List

18lettersCopy = new Character[ 3 ];

19copyList = Arrays.asList( lettersCopy ); // list view of lettersCopy

21System.out.println( "Initial list: " );

22output( list );

24Collections.reverse( list ); // reverse order

25System.out.println( "\nAfter calling reverse: " );

26output( list );

28Collections.copy( copyList, list ); // copy List

29System.out.println( "\nAfter copying: " );

30output( copyList );

32Collections.fill( list, 'R' ); // fill list with Rs

33System.out.println( "\nAfter calling fill: " );

34output( list );

35} // end Algorithms1 constructor

37// output List information

38private void output( List< Character > listRef )

39{

40System.out.print( "The list is: " );

42for ( Character element : listRef )

43System.out.printf( "%s ", element );

45System.out.printf( "\nMax: %s", Collections.max( listRef ) );

46System.out.printf( " Min: %s\n", Collections.min( listRef ) );

47} // end method output

49public static void main( String args[] )

50{

51new Algorithms1();

52} // 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

[Page 931]