0% found this document useful (0 votes)
2 views

Java Structures Data Structures In Java For The Principled Programmer 2nd Edition 2nd Duane Bailey pdf download

The document is about 'Java Structures: Data Structures in Java for the Principled Programmer, 2nd Edition' by Duane A. Bailey, which covers various data structures and algorithms in Java. It includes topics such as object-oriented methods, generics, design fundamentals, and sorting techniques. Additionally, it provides links to related ebooks and resources for further exploration.

Uploaded by

tamoyabihong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Java Structures Data Structures In Java For The Principled Programmer 2nd Edition 2nd Duane Bailey pdf download

The document is about 'Java Structures: Data Structures in Java for the Principled Programmer, 2nd Edition' by Duane A. Bailey, which covers various data structures and algorithms in Java. It includes topics such as object-oriented methods, generics, design fundamentals, and sorting techniques. Additionally, it provides links to related ebooks and resources for further exploration.

Uploaded by

tamoyabihong
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 80

Java Structures Data Structures In Java For The

Principled Programmer 2nd Edition 2nd Duane


Bailey download

https://ebookbell.com/product/java-structures-data-structures-in-
java-for-the-principled-programmer-2nd-edition-2nd-duane-
bailey-2541116

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Data Structures And Algorithms Made Easy With Java Learn Data
Structure Using Java In 7 Days Data Structures And Algorithmic Puzzles
For Beginners To Professional Rahul Maurya

https://ebookbell.com/product/data-structures-and-algorithms-made-
easy-with-java-learn-data-structure-using-java-in-7-days-data-
structures-and-algorithmic-puzzles-for-beginners-to-professional-
rahul-maurya-11751050

Data Structures In Java Oswald Campesato

https://ebookbell.com/product/data-structures-in-java-oswald-
campesato-52042454

Data Structures In Java A Laboratory Course 1st Edition Sandra


Andersen

https://ebookbell.com/product/data-structures-in-java-a-laboratory-
course-1st-edition-sandra-andersen-972674

Data Structures And Algorithms Made Easy In Java Data Structures And
Algorithmic Puzzles Narasimha Karumanchi

https://ebookbell.com/product/data-structures-and-algorithms-made-
easy-in-java-data-structures-and-algorithmic-puzzles-narasimha-
karumanchi-11240034
Data Structures And Algorithms In Java Michael T Goodrich Roberto
Tamassia

https://ebookbell.com/product/data-structures-and-algorithms-in-java-
michael-t-goodrich-roberto-tamassia-53645826

Data Structures And Algorithms In Java Drake Peter

https://ebookbell.com/product/data-structures-and-algorithms-in-java-
drake-peter-22041228

Data Structures And Algorithms In Java 2nd Edition Lafore Robert

https://ebookbell.com/product/data-structures-and-algorithms-in-
java-2nd-edition-lafore-robert-22061902

Data Structures And Algorithms In Java 2nd Ed 2nd Edition Adam Drozdek

https://ebookbell.com/product/data-structures-and-algorithms-in-
java-2nd-ed-2nd-edition-adam-drozdek-22711616

Data Structures And Algorithms In Java 5th International Student


Edition 5th International Student Edition Mt Goodrich And R Tamassia

https://ebookbell.com/product/data-structures-and-algorithms-in-
java-5th-international-student-edition-5th-international-student-
edition-mt-goodrich-and-r-tamassia-2395922
Java Structures

Data Structures in Java for the Principled Programmer


The 7 Edition
(Software release 33)

Duane A. Bailey

Williams College
September 2007

This 7 text copyrighted 2005-2007 by

All rights are reserved by The Author.


No part of this draft publiciation may be reproduced or distributed in any form
without prior, written consent of the author.
Contents

Preface to First Edition xi

Preface to the Second Edition xiii

Preface to the “Root 7” Edition xv

0 Introduction 1
0.1 Read Me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
0.2 He Can’t Say That, Can He? . . . . . . . . . . . . . . . . . . . . . 2

1 The Object-Oriented Method 5


1.1 Data Abstraction and Encapsulation . . . . . . . . . . . . . . . . . 6
1.2 The Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Object-Oriented Terminology . . . . . . . . . . . . . . . . . . . . 8
1.4 A Special-Purpose Class: A Bank Account . . . . . . . . . . . . . . 11
1.5 A General-Purpose Class: An Association . . . . . . . . . . . . . . 14
1.6 Sketching an Example: A Word List . . . . . . . . . . . . . . . . . 18
1.7 Sketching an Example: A Rectangle Class . . . . . . . . . . . . . 20
1.8 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.9 Who Is the User? . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.10 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.11 Laboratory: The Day of the Week Calculator . . . . . . . . . . . . 29

2 Comments, Conditions, and Assertions 33


2.1 Pre- and Postconditions . . . . . . . . . . . . . . . . . . . . . . . 34
2.2 Assertions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.3 Craftsmanship . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.5 Laboratory: Using Javadoc Commenting . . . . . . . . . . . . . . 39

3 Vectors 43
3.1 The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.2 Example: The Word List Revisited . . . . . . . . . . . . . . . . . . 47
3.3 Example: Word Frequency . . . . . . . . . . . . . . . . . . . . . . 48
3.4 The Implementation . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.5 Extensibility: A Feature . . . . . . . . . . . . . . . . . . . . . . . . 53
3.6 Example: L-Systems . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.7 Example: Vector-Based Sets . . . . . . . . . . . . . . . . . . . . . 57
3.8 Example: The Matrix Class . . . . . . . . . . . . . . . . . . . . . . 60
3.9 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
iv Contents

3.10 Laboratory: The Silver Dollar Game . . . . . . . . . . . . . . . . . 67

4 Generics 69
4.1 Motivation (in case we need some) . . . . . . . . . . . . . . . . . 70
4.1.1 Possible Solution: Specialization . . . . . . . . . . . . . . 71
4.2 Implementing Generic Container Classes . . . . . . . . . . . . . . 72
4.2.1 Generic Associations . . . . . . . . . . . . . . . . . . . . 72
4.2.2 Parameterizing the Vector Class . . . . . . . . . . . . . . 74
4.2.3 Restricting Parameters . . . . . . . . . . . . . . . . . . . . 79
4.3 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

5 Design Fundamentals 81
5.1 Asymptotic Analysis Tools . . . . . . . . . . . . . . . . . . . . . . 81
5.1.1 Time and Space Complexity . . . . . . . . . . . . . . . . . 82
5.1.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.1.3 The Trading of Time and Space . . . . . . . . . . . . . . . 91
5.1.4 Back-of-the-Envelope Estimations . . . . . . . . . . . . . . 92
5.2 Self-Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.2.1 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.2.2 Mathematical Induction . . . . . . . . . . . . . . . . . . . 101
5.3 Properties of Design . . . . . . . . . . . . . . . . . . . . . . . . . 108
5.3.1 Symmetry . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
5.3.2 Friction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.5 Laboratory: How Fast Is Java? . . . . . . . . . . . . . . . . . . . . 115

6 Sorting 119
6.1 Approaching the Problem . . . . . . . . . . . . . . . . . . . . . . 119
6.2 Selection Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
6.3 Insertion Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
6.4 Mergesort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
6.5 Quicksort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
6.6 Radix Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
6.7 Sorting Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
6.8 Ordering Objects Using Comparators . . . . . . . . . . . . . . . . 140
6.9 Vector-Based Sorting . . . . . . . . . . . . . . . . . . . . . . . . . 143
6.10 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
6.11 Laboratory: Sorting with Comparators . . . . . . . . . . . . . . . 147

7 A Design Method 149


7.1 The Interface-Based Approach . . . . . . . . . . . . . . . . . . . . 149
7.1.1 Design of the Interface . . . . . . . . . . . . . . . . . . . . 150
7.1.2 Development of an Abstract Implementation . . . . . . . . 151
7.1.3 Implementation . . . . . . . . . . . . . . . . . . . . . . . . 152
7.2 Example: Development of Generators . . . . . . . . . . . . . . . . 152
7.3 Example: Playing Cards . . . . . . . . . . . . . . . . . . . . . . . 155
Contents v

7.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160

8 Iterators 161
8.1 Java’s Enumeration Interface . . . . . . . . . . . . . . . . . . . . 161
8.2 The Iterator Interface . . . . . . . . . . . . . . . . . . . . . . . . . 163
8.3 Example: Vector Iterators . . . . . . . . . . . . . . . . . . . . . . 165
8.4 Example: Rethinking Generators . . . . . . . . . . . . . . . . . . 167
8.5 Example: Filtering Iterators . . . . . . . . . . . . . . . . . . . . . 170
8.6 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
8.7 Laboratory: The Two-Towers Problem . . . . . . . . . . . . . . . 175

9 Lists 179
9.1 Example: A Unique Program . . . . . . . . . . . . . . . . . . . . . 182
9.2 Example: Free Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 183
9.3 Partial Implementation: Abstract Lists . . . . . . . . . . . . . . . 186
9.4 Implementation: Singly Linked Lists . . . . . . . . . . . . . . . . 188
9.5 Implementation: Doubly Linked Lists . . . . . . . . . . . . . . . . 201
9.6 Implementation: Circularly Linked Lists . . . . . . . . . . . . . . 206
9.7 Implementation: Vectors . . . . . . . . . . . . . . . . . . . . . . . 209
9.8 List Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
9.9 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
9.10 Laboratory: Lists with Dummy Nodes . . . . . . . . . . . . . . . . 215

10 Linear Structures 219


10.1 Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
10.1.1 Example: Simulating Recursion . . . . . . . . . . . . . . . 222
10.1.2 Vector-Based Stacks . . . . . . . . . . . . . . . . . . . . . 225
10.1.3 List-Based Stacks . . . . . . . . . . . . . . . . . . . . . . . 227
10.1.4 Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . 228
10.2 Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
10.2.1 Example: Solving a Coin Puzzle . . . . . . . . . . . . . . . 231
10.2.2 List-Based Queues . . . . . . . . . . . . . . . . . . . . . . 234
10.2.3 Vector-Based Queues . . . . . . . . . . . . . . . . . . . . . 235
10.2.4 Array-Based Queues . . . . . . . . . . . . . . . . . . . . . 238
10.3 Example: Solving Mazes . . . . . . . . . . . . . . . . . . . . . . . 242
10.4 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
10.5 Laboratory: A Stack-Based Language . . . . . . . . . . . . . . . . 247
10.6 Laboratory: The Web Crawler . . . . . . . . . . . . . . . . . . . . 251

11 Ordered Structures 253


11.1 Comparable Objects Revisited . . . . . . . . . . . . . . . . . . . . 253
11.1.1 Example: Comparable Ratios . . . . . . . . . . . . . . . . 254
11.1.2 Example: Comparable Associations . . . . . . . . . . . . . 256
11.2 Keeping Structures Ordered . . . . . . . . . . . . . . . . . . . . . 258
11.2.1 The OrderedStructure Interface . . . . . . . . . . . . . . . 258
11.2.2 The Ordered Vector and Binary Search . . . . . . . . . . . 259
vi Contents

11.2.3 Example: Sorting Revisited . . . . . . . . . . . . . . . . . 264


11.2.4 A Comparator-based Approach . . . . . . . . . . . . . . . 265
11.2.5 The Ordered List . . . . . . . . . . . . . . . . . . . . . . . 267
11.2.6 Example: The Modified Parking Lot . . . . . . . . . . . . . 270
11.3 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
11.4 Laboratory: Computing the “Best Of” . . . . . . . . . . . . . . . . 275

12 Binary Trees 277


12.1 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
12.2 Example: Pedigree Charts . . . . . . . . . . . . . . . . . . . . . . 280
12.3 Example: Expression Trees . . . . . . . . . . . . . . . . . . . . . . 281
12.4 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
12.4.1 The BinaryTree Implementation . . . . . . . . . . . . . . . 284
12.5 Example: An Expert System . . . . . . . . . . . . . . . . . . . . . 287
12.6 Traversals of Binary Trees . . . . . . . . . . . . . . . . . . . . . . 290
12.6.1 Preorder Traversal . . . . . . . . . . . . . . . . . . . . . . 291
12.6.2 In-order Traversal . . . . . . . . . . . . . . . . . . . . . . 293
12.6.3 Postorder Traversal . . . . . . . . . . . . . . . . . . . . . . 295
12.6.4 Level-order Traversal . . . . . . . . . . . . . . . . . . . . . 296
12.6.5 Recursion in Iterators . . . . . . . . . . . . . . . . . . . . 297
12.7 Property-Based Methods . . . . . . . . . . . . . . . . . . . . . . . 299
12.8 Example: Huffman Compression . . . . . . . . . . . . . . . . . . 303
12.9 Example Implementation: Ahnentafel . . . . . . . . . . . . . . . . 307
12.10Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
12.11Laboratory: Playing Gardner’s Hex-a-Pawn . . . . . . . . . . . . . 313

13 Priority Queues 315


13.1 The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
13.2 Example: Improving the Huffman Code . . . . . . . . . . . . . . 317
13.3 A Vector-Based Implementation . . . . . . . . . . . . . . . . . . . 318
13.4 A Heap Implementation . . . . . . . . . . . . . . . . . . . . . . . 319
13.4.1 Vector-Based Heaps . . . . . . . . . . . . . . . . . . . . . 320
13.4.2 Example: Heapsort . . . . . . . . . . . . . . . . . . . . . . 326
13.4.3 Skew Heaps . . . . . . . . . . . . . . . . . . . . . . . . . . 329
13.5 Example: Circuit Simulation . . . . . . . . . . . . . . . . . . . . . 333
13.6 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
13.7 Laboratory: Simulating Business . . . . . . . . . . . . . . . . . . 341

14 Search Trees 343


14.1 Binary Search Trees . . . . . . . . . . . . . . . . . . . . . . . . . . 343
14.2 Example: Tree Sort . . . . . . . . . . . . . . . . . . . . . . . . . . 345
14.3 Example: Associative Structures . . . . . . . . . . . . . . . . . . . 345
14.4 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
14.5 Splay Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
14.6 Splay Tree Implementation . . . . . . . . . . . . . . . . . . . . . 357
14.7 An Alternative: Red-Black Trees . . . . . . . . . . . . . . . . . . . 361
Contents vii

14.8 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363


14.9 Laboratory: Improving the BinarySearchTree . . . . . . . . . . . . 367

15 Maps 369
15.1 Example Revisited: The Symbol Table . . . . . . . . . . . . . . . . 369
15.2 The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
15.3 Simple Implementation: MapList . . . . . . . . . . . . . . . . . . 372
15.4 Constant Time Maps: Hash Tables . . . . . . . . . . . . . . . . . . 374
15.4.1 Open Addressing . . . . . . . . . . . . . . . . . . . . . . . 375
15.4.2 External Chaining . . . . . . . . . . . . . . . . . . . . . . 383
15.4.3 Generation of Hash Codes . . . . . . . . . . . . . . . . . . 385
15.4.4 Hash Codes for Collection Classes . . . . . . . . . . . . . . 391
15.4.5 Performance Analysis . . . . . . . . . . . . . . . . . . . . . 392
15.5 Ordered Maps and Tables . . . . . . . . . . . . . . . . . . . . . . 392
15.6 Example: Document Indexing . . . . . . . . . . . . . . . . . . . . 395
15.7 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
15.8 Laboratory: The Soundex Name Lookup System . . . . . . . . . . 401

16 Graphs 403
16.1 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
16.2 The Graph Interface . . . . . . . . . . . . . . . . . . . . . . . . . 404
16.3 Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
16.3.1 Abstract Classes Reemphasized . . . . . . . . . . . . . . . 408
16.3.2 Adjacency Matrices . . . . . . . . . . . . . . . . . . . . . . 410
16.3.3 Adjacency Lists . . . . . . . . . . . . . . . . . . . . . . . . 416
16.4 Examples: Common Graph Algorithms . . . . . . . . . . . . . . . 422
16.4.1 Reachability . . . . . . . . . . . . . . . . . . . . . . . . . . 422
16.4.2 Topological Sorting . . . . . . . . . . . . . . . . . . . . . . 424
16.4.3 Transitive Closure . . . . . . . . . . . . . . . . . . . . . . 427
16.4.4 All Pairs Minimum Distance . . . . . . . . . . . . . . . . . 428
16.4.5 Greedy Algorithms . . . . . . . . . . . . . . . . . . . . . . 429
16.5 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
16.6 Laboratory: Converting Between Units . . . . . . . . . . . . . . . 439

A Answers 441
A.1 Solutions to Self Check Problems . . . . . . . . . . . . . . . . . . 441
A.2 Solutions to Odd-Numbered Problems . . . . . . . . . . . . . . . 451

B Beginning with Java 489


B.1 A First Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
B.2 Declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491
B.2.1 Primitive Types . . . . . . . . . . . . . . . . . . . . . . . . 491
B.2.2 Reference Types . . . . . . . . . . . . . . . . . . . . . . . 493
B.3 Important Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
B.3.1 The structure.ReadStream Class . . . . . . . . . . . . . . . 494
B.3.2 The java.util.Scanner Class . . . . . . . . . . . . . . . . . 495
viii Contents

B.3.3 The PrintStream Class . . . . . . . . . . . . . . . . . . . . 496


B.3.4 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
B.4 Control Constructs . . . . . . . . . . . . . . . . . . . . . . . . . . 498
B.4.1 Conditional Statements . . . . . . . . . . . . . . . . . . . 498
B.4.2 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
B.5 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
B.6 Inheritance and Subtyping . . . . . . . . . . . . . . . . . . . . . . 502
B.6.1 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . 502
B.6.2 Subtyping . . . . . . . . . . . . . . . . . . . . . . . . . . . 503
B.6.3 Interfaces and Abstract Classes . . . . . . . . . . . . . . . 504
B.7 Use of the Assert Command . . . . . . . . . . . . . . . . . . . . . 506
B.8 Use of the Keyword Protected . . . . . . . . . . . . . . . . . . . 507

C Collections 511
C.1 Collection Class Features . . . . . . . . . . . . . . . . . . . . . . . 511
C.2 Parallel Features . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
C.3 Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512

D Documentation 513
D.1 Structure Package Hierarchy . . . . . . . . . . . . . . . . . . . . . 513
D.2 Principles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515

Index 517
for Mary,
my wife and best friend

without
the model of my mentors,
the comments of my colleagues,
the support of my students,
the friendship of my family
this book would never be

thank you!
Preface to the First Edition
“I T ’ S A WONDERFUL TIME TO BE ALIVE .” At least that’s what I’ve found myself
saying over the past couple of decades. When I first started working with com-
puters, they were resources used by a privileged (or in my case, persistent) few.
They were physically large, and logically small. They were cast from iron. The
challenge was to make these behemoths solve complex problems quickly.
Today, computers are everywhere. They are in the office and at home. They
speak to us on telephones; they zap our food in the microwave. They make
starting cars in New England a possibility. Everyone’s using them. What has
aided their introduction into society is their diminished size and cost, and in-
creased capability. The challenge is to make these behemoths solve complex
problems quickly.
Thus, while the computer and its applications have changed over time, the
challenge remains the same: How can we get the best performance out of the
current technology? The design and analysis of data structures lay the funda-
mental groundwork for a scientific understanding of what computers can do
efficiently. The motivations for data structure design work accomplished three
decades ago in assembly language at the keypunch are just as familiar to us to-
day as we practice our craft in modern languages on computers on our laps. The
focus of this material is the identification and development of relatively abstract
principles for structuring data in ways that make programs efficient in terms of
their consumption of resources, as well as efficient in terms of “programmability.”
In the past, my students have encountered this material in Pascal, Modula-2,
and, most recently, C++. None of these languages has been ideal, but each has
been met with increasing expectation. This text uses The Java Programming
Language1 —“Java”—to structure data. Java is a new and exciting language
that has received considerable public attention. At the time of this writing, for
example, Java is one of the few tools that can effectively use the Internet as a
computing resource. That particular aspect of Java is not touched on greatly
in this text. Still, Internet-driven applications in Java will need supporting data
structures. This book attempts to provide a fresh and focused approach to the
design and implementation of classic structures in a manner that meshes well
with existing Java packages. It is hoped that learning this material in Java
will improve the way working programmers craft programs, and the way future
designers craft languages.
Pedagogical Implications. This text was developed specifically for use with
CS2 in a standard Computer Science curriculum. It is succinct in its approach,
and requires, perhaps, a little more effort to read. I hope, though, that this text

1 Java is a trademark of Sun Microsystems, Incorporated.


xii Preface to the First Edition

becomes not a brief encounter with object-oriented data structure design, but a
touchstone for one’s programming future.
The material presented in this text follows the syllabus I have used for sev-
eral years at Williams. As students come to this course with experience using
Java, the outline of the text may be followed directly. Where students are new
to Java, a couple of weeks early in the semester will be necessary with a good
N
companion text to introduce the student to new concepts, and an introductory
NW

NE

Java language text or reference manual is recommended. For students that need
W

a quick introduction to Java we provide a tutorial in Appendix B. While the text


SW

SE

was designed as a whole, some may wish to eliminate less important topics
and expand upon others. Students may wish to drop (or consider!) the sec-
tion on induction (Section 5.2.2). The more nontraditional topics—including,
for example, iteration and the notions of symmetry and friction—have been in-
cluded because I believe they arm programmers with important mechanisms for
implementing and analyzing problems. In many departments the subtleties of
more advanced structures—maps (Chapter 15) and graphs (Chapter 16)—may
be considered in an algorithms course. Chapter 6, a discussion of sorting, pro-
vides very important motivating examples and also begins an early investigation
of algorithms. The chapter may be dropped when better examples are at hand,
but students may find the refinements on implementing sorting interesting.
Associated with this text is a Java package of data structures that is freely
available over the Internet for noncommercial purposes. I encourage students,
educators, and budding software engineers to download it, tear it down, build it
List up, and generally enjoy it. In particular, students of this material are encouraged
to follow along with the code online as they read. Also included is extensive
documentation gleaned from the code by javadoc. All documentation—within
the book and on the Web—includes pre- and postconditions. The motivation for
this style of commenting is provided in Chapter 2. While it’s hard to be militant
about commenting, this style of documentation provides an obvious, structured
approach to minimally documenting one’s methods that students can appreciate
and users will welcome. These resources, as well as many others, are available
from McGraw-Hill at http://www.mhhe.com/javastructures.
Three icons appear throughout the text, as they do in the margin. The
top “compass” icon highlights the statement of a principle—a statement that
nim encourages abstract discussion. The middle icon marks the first appearance of
a particular class from the structure package. Students will find these files at
McGraw-Hill, or locally, if they’ve been downloaded. The bottom icon similarly
marks the appearance of example code.
Finally, I’d like to note an unfortunate movement away from studying the
implementation of data structures, in favor of studying applications. In the
extreme this is a disappointing and, perhaps, dangerous precedent. The design
of a data structure is like the solution to a riddle: the process of developing the
answer is as important as the answer itself. The text may, however, be used as a
reference for using the structure package in other applications by selectively
avoiding the discussions of implementation.
Preface to the Second Edition
Since the first edition of Java Structures support for writing programs in Java2
has grown considerably. At that time the Java Development Toolkit consisted
of 504 classes in 23 packages3 In Java 1.2 (also called Java 2) Sun rolled out
1520 classes in 59 packages. This book is ready for Java 1.4, where the number
of classes and packages continues to grow.
Most computer scientists are convinced of the utility of Java for program-
ming in a well structured and platform independent manner. While there are
still significant arguments about important aspects of the language (for exam-
ple, support for generic types), the academic community is embracing Java, for
example, as the subject of the Computer Science Advanced Placement Exami-
nation.
It might seem somewhat perplexing to think that many aspects of the origi-
nal Java environment have been retracted (or deprecated) or reconsidered. The
developers at Sun have one purpose in mind: to make Java the indispensable
language of the current generation. As a result, documenting their progress on
the development of data structures gives us valuable insight into the process of
designing useful data structures for general purpose programming. Those stu-
dents and faculty considering a move to this second edition of Java Structures
will see first-hand some of the decisions that have been made in the interven-
ing years. During that time, for example, the Collection-based classes were
introduced, and are generally considered an improvement. Another force—
one similar to calcification—has left a trail of backwards compatible features
that are sometimes difficult to understand. For example, the Iterator class
was introduced, but the Enumeration class was not deprecated. One subject of
the first edition—the notion of Comparable classes—has been introduced into
a number of important classes including String and Integer. This is a step
forward and a reconsideration of what we have learned about that material has
lead to important improvements in the text.
Since the main purpose of the text is to demonstrate the design and behavior
of traditional data structures, we have not generally tracked the progress of
Java where it blurs the view. For example, Java 2 introduces a List interface
(we applaud) but the Vector class has been extended to include methods that
are, essentially, motivated by linked lists (we wonder). As this text points out
frequently, the purpose of an interface is often to provide reduced functionality.
If the data structure does not naturally provide the functionality required by the
application, it is probably not an effective tool for solving the problem: search
elsewhere for an effective structure.

2 The Java Programming Language is a trademark of Sun Microsystems, Incorporated.


3 David Flanagan, et al., Java in a Nutshell, O’Reilly & Associates.
xiv Preface to the Second Edition

As of this writing, more than 100, 000 individuals have searched for and
downloaded the structure package. To facilitate using the comprehensive set
of classes with the Java 2 environment, we have provided a number of features
that support the use of the structure package in more concrete applications.
Please see Appendix C.
Also new to this edition are more than 200 new problems, several dozen
exercises, and over a dozen labs we regularly use at Williams.
Acknowledgments. Several students, instructors, and classes have helped to
shape this edition of Java Structures. Parth Doshi and Alex Glenday—diligent
Williams students—pointed out a large number of typos and stretches of logic.
Kim Bruce, Andrea Danyluk, Jay Sachs, and Jim Teresco have taught this course
at Williams over the past few years, and have provided useful feedback. I tip
my hat to Bill Lenhart, a good friend and advisor, who has helped improve this
text in subtle ways. To Sean Sandys I am indebted for showing me new ways to
teach new minds.
The various reviewers have made, collectively, hundreds of pages of com-
ments that have been incorporated (as much as possible) into this edition:
Eleanor Hare and David Jacobs (Clemson University), Ram Athavale (North
Carolina State University), Yannick Daoudi (McGill University), Walter Daugh-
erty (Texas A&M University), Subodh Kumar (Johns Hopkins University), Toshimi
Minoura (Oregon State University), Carolyn Schauble (Colorado State Univer-
sity), Val Tannen (University of Pennsylvania), Frank Tompa (University of Wa-
terloo), Richard Wiener (University of Colorado at Colorado Springs), Cynthia
Brown Zickos (University of Mississippi), and my good friend Robbie Moll (Uni-
versity of Massachusetts). Deborah Trytten (University of Oklahoma) has re-
viewed both editions! Still, until expert authoring systems are engineered, au-
thors will remain human. Any mistakes left behind or introduced are purely
those of the author.
The editors and staff at McGraw-Hill–Kelly Lowery, Melinda Dougharty, John
Wannemacher, and Joyce Berendes–have attempted the impossible: to keep me
within a deadline. David Hash, Phil Meek, and Jodi Banowetz are responsible
for the look and feel of things. I am especially indebted to Lucy Mullins, Judy
Gantenbein, and Patti Evers whose red pens have often shown me a better way.
Betsy Jones, publisher and advocate, has seen it all and yet kept the faith:
thanks.
Be aware, though: long after these pages are found to be useless folly, my
best work will be recognized in my children, Kate, Megan, and Ryan. None
of these projects, of course, would be possible without the support of my best
friend, my north star, and my partner, Mary.

Enjoy!

Duane A. Bailey
Williamstown, May 2002

Preface to the 7 Edition
In your hand is a special edition of Java Structures designed for use with two
semesters of Williams’ course on data structures, Computer Science 136. This
version is only marginally different than the preceding edition, but is positioned
to make use of Java 5 (the trademarked name for version 1.5 of the JDK).
Because Java 5 may not be available (yet) on the platform you use, most of the
code available in this book will run on older JDK’s. The one feature that would
not be available is Java’s new Scanner class from the java.util package; an
alternative is my ReadStream class, which is lightly documented in Section B.3.1
on page 494. It is a feature of the structure package soon to be removed.
In making this book available in this paperbound format, my hope is that
you find it a more inviting place to write notes: additions, subtractions, and
updates that you’re likely to have discussed in class. Sometimes you’ll identify
improvements, and I hope you’ll pass those along to me. In any case, you can
download the software (as hundreds of thousands have done in the past) and
modify it as you desire.
On occasion, I will release new sections you can incorporate into your text,
including a discussion of how the structure package can make use of generic
types.
I have spent a considerable amount of time designing the structure pack-
age. The first structures were available 8 years ago when Java was still in its
infancy. Many of the structures have since been incorporated (directly or indi-
rectly) into Sun’s own JDK. (Yes, we’ve sold a few books in California.) Still, I
feel the merit of my approach is a slimness that, in the end, you will not find
surprising.
Meanwhile, for those of you keeping track, the following table (adapted
from the 121 cubic inch, 3 pound 6 ounce, Fifth edition of David Flanagan’s
essential Java in a Nutshell) demonstrates the growth of Java’s support:

JDK Packages Classes Features


1.0 8 212 First public version
1.1 23 504 Inner classes
1.2 (Java 2) 59 1520 Collection classes
1.3 76 1842 A “maintenance” release.
1.4 135 2991 Improvments, including assert
1.5 (Java 5) 166 3562 Generics, autoboxing, and “varargs.”

Seeing this reminds me of the comment made by Niklaus Wirth, designer of


Pascal and the first two releases of Modula. After the design team briefed him
on the slew of new features to be incorporated into Modula 3, he parried: “But,
what features have you removed?” A timeless question.

xvi Preface to the 7 Edition

Acknowledgments. This book was primarily written for students of Williams


College. The process of publishing and reviewing a text tends to move the focus
off campus and toward the bottom line. The Route 7 edition4 —somewhere
between editions 2 and 3—is an initial attempt to bring that focus back to those
students who made it all possible.
For nearly a decade, students at many institutions have played an important
role in shaping these resources. In this edition, I’m especially indebted to Katie
Creel ’10 (Williams) and Brian Bargh ’07 (Messiah): thanks!
Many colleagues, including Steve Freund ’95 (Stanford, now at Williams),
Jim Teresco ’92 (Union, now at Mount Holyoke), and especially Gene Chase ’65
(M.I.T., now at Messiah) continue to nudge this text in a better direction. Brent
Heeringa ’99 (Morris, now at Williams) showers all around him with youthful
enthusiasm.
And a most special thanks to Bill Mueller for the shot heard around the
world—the game-winning run that showed all things were possible. Called by
Joe Castiglione ’68 (Colgate, now at Fenway):
“Three-and-one to Mueller. One out, nineth inning. 10-9 Yankees,
runner at first. Here’s the pitch...swing and a High Drive Deep to
Right...Back Goes Sheffield to the Bullpen...AND IT IS GONE!...AND
THE RED SOX HAVE WON IT!...ON A WALKOFF TWO RUN HOMER
BY BILL MUELLER OFF MARIANO RIVERA! CAN YOU BELIEVE IT?!”
Have I been a Red Sox fan all my life? Not yet.
Finally, nothing would be possible without my running mate, my Sox buddy,
and my best friend, Mary.

Cheers!

Duane A. Bailey ’82 (Amherst, now at Williams)


Williamstown, September 2007

4 Route 7 is a scenic byway through the Berkshires and Green Mountains that eddies a bit as it
passes through Williamstown and Middlebury.
Chapter 0
Introduction

Concepts: This is an important notice.


. Approaches to this material Please have it translated.
. Principles —The Phone Company

Y OUR MOTHER probably provided you with constructive toys, like blocks or
Tinkertoys1 or Lego bricks. These toys are educational: they teach us to think
spatially and to build increasingly complex structures. You develop modules
that can be stuck together and rules that guide the building process.
If you are reading this book, you probably enjoyed playing with construc-
tive toys. You consider writing programs an artistic process. You have grown
from playing with blocks to writing programs. The same guidelines for building
structures apply to writing programs, save one thing: there is, seemingly, no
limit to the complexity of the programs you can write. I lie.
Well, almost. When writing large programs, the data structures that main-
tain the data in your program govern the space and time consumed by your
running program. In addition, large programs take time to write. Using differ-
ent structures can actually have an impact on how long it takes to write your
program. Choosing the wrong structures can cause your program to run poorly
or be difficult or impossible to implement effectively.
Thus, part of the program-writing process is choosing between different
structures. Ideally you arrive at solutions by analyzing and comparing their
various merits. This book focuses on the creation and analysis of traditional
data structures in a modern programming environment, The Java Programming
Language, or Java for short.

0.1 Read Me
As might be expected, each chapter is dedicated to a specific topic. Many of the
topics are concerned with specific data structures. The structures we will inves-
tigate are abstracted from working implementations in Java that are available
to you if you have access to the Internet.2 Other topics concern the “tools of the

1 All trademarks are recognized.


2 For more information, see http://www.cs.williams.edu/JavaStructures.
2 Introduction

trade.” Some are mathematical and others are philosophical, but all consider
the process of programming well.
The topics we cover are not all-inclusive. Some useful structures have been
left out. Instead, we will opt to learn the principles of programming data struc-
tures, so that, down the road, you can design newer and better structures your-
self.
Perhaps the most important aspect of this book is the set of problems at the
end of each section. All are important for you to consider. For some problems
I have attempted to place a reasonable hint or answer in the back of the book.
Why should you do problems? Practice makes perfect. I could show you how to
Unicycles: the ride a unicycle, but if you never practiced, you would never learn. If you study
ultimate riding and understand these problems, you will find your design and analytical skills
structure. are improved. As for your mother, she’ll be proud of you.
Sometimes we will introduce problems in the middle of the running text—
these problems do not have answers (sometimes they are repeated as formal
problems in the back of the chapter, where they do have answers)—they should
be thought about carefully as you are reading along. You may find it useful to
have a pencil and paper handy to help you “think” about these problems on the
fly.
Exercise 0.1 Call3 your Mom and tell her you’re completing your first exercise. If
you don’t have a phone handy, drop her a postcard. Ask her to verify that she’s
proud of you.
This text is brief and to the point. Most of us are interested in experimenting.
We will save as much time as possible for solving problems, perusing code, and
practicing writing programs. As you read through each of the chapters, you
might find it useful to read through the source code online. As we first consider
the text of files online, the file name will appear in the margin, as you see here.
Structure The top icon refers to files in the structure package, while the bottom icon
refers to files supporting examples.
One more point—this book, like most projects, is an ongoing effort, and
the latest thoughts are unlikely to have made it to the printed page. If you
are in doubt, turn to the website for the latest comments. You will also find
online documentation for each of the structures, generated from the code using
Example javadoc. It is best to read the online version of the documentation for the
most up-to-date details, as well as the documentation of several structures not
formally presented within this text.

0.2 He Can’t Say That, Can He?


Sure! Throughout this book are little political comments. These remarks may
seem trivial at first blush. Skip them! If, however, you are interested in ways

3 Don’t e-mail her. Call her. Computers aren’t everything, and they’re a poor medium for a mother’s
pride.
0.2 He Can’t Say That, Can He? 3

to improve your skills as a programmer and a computer scientist, I invite you


to read on. Sometimes these comments are so important that they appear as
principles: N

NW

NE
W
Principle 1 The principled programmer understands a principle well enough to

E
SW

SE
form an opinion about it. S

Self Check Problems


Solutions to these problems begin on page 441.
0.1 Where are the answers for “self check” problems found?
0.2 What are features of large programs?
0.3 Should you read the entire text?
0.4 Are principles statements of truth?

Problems
Solutions to the odd-numbered problems begin on page 451.
0.1 All odd problems have answers. Where do you find answers to prob-
lems? (Hint: See page 451.)
0.2 You are an experienced programmer. What five serious pieces of advice
would you give a new programmer?
0.3 Surf to the website associated with this text and review the resources
available to you.
0.4 Which of the following structures are described in this text (see Append-
ix D): BinarySearchTree, BinaryTree, BitSet, Map, Hashtable, List?
0.5 Surf to http://www.javasoft.com and review the Java resources avail-
able from Sun, the developers of Java.
0.6 Review documentation for Sun’s java.util package. (See the Core
API Documentation at http://www.javasoft.com.) Which of the following
data structures are available in this package: BinarySearchTree, BinaryTree,
BitSet, Dictionary, Hashtable, List?
0.7 Check your local library or bookstore for Java reference texts.
0.8 If you haven’t done so already, learn how to use your local Java pro-
gramming environment by writing a Java application to write a line of text.
(Hint: Read Appendix B.)
0.9 Find the local documentation for the structure package. If none is to
be found, remember that the same documentation is available over the Internet
from http://www.cs.williams.edu/JavaStructures.
0.10 Find the examples electronically distributed with the structure pack-
age. Many of these examples are discussed later in this text.
Chapter 1

The Object-Oriented Method

Concepts: I will pick up the hook.


. Data structures You will see something new.
Two things. And I call them
. Abstract data types
Thing One and Thing Two.
. Objects
These Things will not bite you.
. Classes They want to have fun.
. Interfaces —Theodor Seuss Geisel

C OMPUTER SCIENCE DOES NOT SUFFER the great history of many other disci-
plines. While other subjects have well-founded paradigms and methods, com-
puter science still struggles with one important question: What is the best method
to write programs? To date, we have no best answer. The focus of language de-
signers is to develop programming languages that are simple to use but provide
the power to accurately and efficiently describe the details of large programs
and applications. The development of Java is one such effort.
Throughout this text we focus on developing data structures using object-
oriented programming. Using this paradigm the programmer spends time devel- OOP:
oping templates for structures called classes. The templates are then used to Object-oriented
construct instances or objects. A majority of the statements in object-oriented programming.
programs involve sending messages to objects to have them report or change
their state. Running a program involves, then, the construction and coordina-
tion of objects. In this way languages like Java are object-oriented.
In all but the smallest programming projects, abstraction is a useful tool
for writing working programs. In programming languages including Pascal,
Scheme, and C, the details of a program’s implementation are hidden away in
its procedures or functions. This approach involves procedural abstraction. In
object-oriented programming the details of the implementation of data struc-
tures are hidden away within its objects. This approach involves data abstrac-
tion. Many modern programming languages use object orientation to support
basic abstractions of data. We review the details of data abstraction and the
design of formal interfaces for objects in this chapter.
6 The Object-Oriented Method

1.1 Data Abstraction and Encapsulation


If you purchase a donut from Morningside Bakery in Pittsfield, Massachusetts,
you can identify it as a donut without knowing its ingredients. Donuts are
circular, breadlike, and sweet. The particular ingredients in a donut are of little
concern to you. Of course, Morningside is free to switch from one sweetener to
another, as long as the taste is preserved.1 The donut’s ingredients list and its
construction are details that probably do not interest you.
Likewise, it is often unimportant to know how data structures are imple-
mented in order to appreciate their use. For example, most of us are familiar
with the workings or semantics of strings or arrays, but, if pressed, we might
find it difficult to describe their mechanics: Do all consecutive locations in the
array appear close together in memory in your computer, or are they far apart?
The answer is: it is unimportant. As long as the array behaves like an array or
the string behaves like a string we are happy. The less one knows about how
arrays or strings are implemented, the less one becomes dependent on a partic-
Macintosh and ular implementation. Another way to think about this abstractly is that the data
UNIX store structure lives up to an implicit “contract”: a string is an ordered list of charac-
strings ters, or elements of an array may be accessed in any order. The implementor of
differently. the data structure is free to construct it in any reasonable way, as long as all the
terms of the contract are met. Since different implementors are in the habit of
making very different implementation decisions, anything that helps to hide the
implementation details—any means of using abstraction—serves to make the
world a better place to program.
When used correctly, object-oriented programming allows the programmer
to separate the details that are important to the user from the details that are
only important to the implementation. Later in this book we shall consider very
general behavior of data structures; for example, in Section 10.1 we will study
structures that allow the user only to remove the most recently added item.
Such behavior is inherent to our most abstract understanding of how the data
structure works. We can appreciate the unique behavior of this structure even
though we haven’t yet discussed how these structures might be implemented.
Those abstract details that are important to the user of the structure—including
abstract semantics of the methods—make up its contract or interface. The in-
terface describes the abstract behavior of the structure. Most of us would agree
that while strings and arrays are very similar structures, they behave differently:
you can shrink or expand a string, while you cannot directly do the same with
an array; you can print a string directly, while printing an array involves explic-
itly printing each of its elements. These distinctions suggest they have distinct
abstract behaviors; there are distinctions in the design of their interfaces.
The unimportant details hidden from the user are part of what makes up
the implementation. We might decide (see Figure 1.1) that a string is to be

1 Apple cider is often used to flavor donuts in New England, but that decision decidedly changes

the flavor of the donut for the better. Some of the best apple cider donuts can be found at Atkin’s
apple farm in Amherst, Massachusetts.
1.2 The Object Model 7

Counted string

Data L I C K E T Y S P L I T !
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 n

Count 13

Terminated string

E
Data L I C K E T Y S P L I T ! O
S
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 n

Figure 1.1 Two methods of implementing a string. A counted string explicitly records
its length. The terminated string’s length is determined by an end-of-string mark.

constructed from a large array of characters with an attendant character count.


Alternatively, we might specify the length implicitly by terminating the string
with a special end-of-string mark that is not used for any other purpose. Both
of these approaches are perfectly satisfactory, but there are trade-offs. The first
implementation (called a counted string) has its length stored explicitly, while
the length of the second implementation (called a terminated string) is implied.
It takes longer to determine the length of a terminated string because we have to
search for the end-of-string mark. On the other hand, the size of a terminated
string is limited only by the amount of available memory, while the longest
counted string is determined by the range of integers that can be stored in its
length field (often this is only several hundred characters). If implementors can
hide these details, users do not have to be distracted from their own important
design work. As applications mature, a fixed interface to underlying objects
allows alternative implementations of the object to be considered.
Data abstraction in languages like Java allows a structure to take responsibil-
ity for its own state. The structure knows how to maintain its own state without
bothering the programmer. For example, if two strings have to be concatenated
into a single string structure, a request might have to be made for a new allot-
ment of memory. Thankfully, because strings know how to perform operations
on themselves, the user doesn’t have to worry about managing memory.

1.2 The Object Model


To facilitate the construction of well-designed objects, it is useful to have a de-
sign method in mind. As alluded to earlier, we will often visualize the data for
our program as being managed by its objects. Each object manages its own data
that determine its state. A point on a screen, for example, has two coordinates.
8 The Object-Oriented Method

A medical record maintains a name, a list of dependents, a medical history, and


a reference to an insurance company. A strand of genetic material has a se-
quence of base pairs. To maintain a consistent state we imagine the program
manipulates the data within its objects only through messages or method calls
to the objects. A string might receive a message “tell me your length,” while
a medical record might receive a “change insurance” message. The string mes-
sage simply accesses information, while the medical record method may involve
changing several pieces of information in this and other objects in a consistent
manner. If we directly modify the reference to the insurance company, we may
forget to modify similar references in each of the dependents. For large applica-
tions with complex data structures, it can be extremely difficult to remember to
coordinate all the operations that are necessary to move a single complex object
from one consistent state to another. We opt, instead, to have the designer of
the data structure provide us a method for carefully moving between states; this
method is activated in response to a high-level message sent to the object.
This text, then, focuses on two important topics: (1) how we implement and
evaluate objects with methods that are logically complex and (2) how we might
use the objects we create. These objects typically represent data structures, our
primary interest. Occasionally we will develop control structures—structures
whose purpose is to control the manipulation of other objects. Control struc-
tures are an important concept and are described in detail in Chapter 8.

1.3 Object-Oriented Terminology


In Java, data abstraction is accomplished through encapsulation of data in an
object—an instance of a class. Like a record in other languages, an object has
fields. Unlike records, objects also contain methods. Fields and methods of an
object may be declared public, which means that they are visible to entities
outside the class, or protected, in which case they may only be accessed by
code within methods of the class.2 A typical class declaration is demonstrated
by the following simple class that keeps track of the ratio of two integer values:

public class Ratio


{
protected int numerator; // numerator of ratio
Ratio protected int denominator; // denominator of ratio

public Ratio(int top, int bottom)


// pre: bottom != 0
// post: constructs a ratio equivalent to top::bottom
{
numerator = top;
denominator = bottom;
reduce();

2 This is not quite the truth. For a discussion of the facts, see Appendix B.8.
1.3 Object-Oriented Terminology 9

public int getNumerator()


// post: return the numerator of the fraction
{
return numerator;
}

public int getDenominator()


// post: return the denominator of the fraction
{
return denominator;
}

public double getValue()


// post: return the double equivalent of the ratio
{
return (double)numerator/(double)denominator;
}

public Ratio add(Ratio other)


// pre: other is nonnull
// post: return new fraction--the sum of this and other
{
return new Ratio(this.numerator*other.denominator+
this.denominator*other.numerator,
this.denominator*other.denominator);
}

protected void reduce()


// post: numerator and denominator are set so that
// the greatest common divisor of the numerator and denominator is 1
{
int divisor = gcd(numerator,denominator);
if (denominator < 0) divisor = -divisor;
numerator /= divisor;
denominator /= divisor;
}

protected static int gcd(int a, int b)


// post: computes the greatest integer value that divides a and b
{
if (a < 0) return gcd(-a,b);
if (a == 0) {
if (b == 0) return 1;
else return b;
}
if (b < a) return gcd(b,a);
return gcd(b%a,a);
}
10 The Object-Oriented Method

public String toString()


// post: returns a string that represents this fraction.
{
return getNumerator()+"/"+getDenominator();
}
}

First, a Ratio object maintains the numerator and denominator as protected


ints that are not directly modifiable by the user. The Ratio method is a con-
structor: a method whose name is the same as that of the class. (The formal
comments at the top of methods are pre- and postconditions; we discuss these
in detail in Chapter 2.) The constructor is called whenever a new Ratio object is
formed. Constructors initialize all the fields of the associated object, placing the
object into a predictable and consistent initial state. We declare the construc-
tors for a class public. To construct a new Ratio object, users will have to call
these methods. The value method returns a double that represents the ratio,
while the getNumerator and getDenominator methods fetch the current values
of the numerator and denominator of the fraction. The add method is useful for
adding one Ratio to another; the result is a newly constructed Ratio object.
Finally, the toString method generates the preferred printable representation
of the object; we have chosen to represent it in fractional form.
Two methods, reduce and gcd, are utility methods. The gcd method com-
putes the greatest common divisor of two values using Euclid’s method, one of
the oldest numerical algorithms used today. It is used by the reduce method to
reduce the numerator and denominator to lowest terms by removing any com-
mon factors. Both are declared protected because computing the reduction is
not a necessary (or obvious) operation to be performed on ratios of integers;
it’s part of the implementation. The gcd method is declared static because
the algorithm can be used at any time—its utility is independent of the number
of Ratio objects that exist in our program. The reduce method, on the other
hand, works only with a Ratio object.

Exercise 1.1 Nearly everything can be improved. Are there improvements that
might be made to the gcd method? Can you write the method iteratively? Is
iteration an improvement?

As with the Ratio class, data fields are usually declared protected. To ma-
nipulate protected fields the user must invoke public methods. The following
example demonstrates the manipulation of the Ratio class:

public static void main(String[] args)


{
Ratio r = new Ratio(1,1); // r == 1.0
r = new Ratio(1,2); // r == 0.5
r.add(new Ratio(1,3)); // sum computed, but r still 0.5
r = r.add(new Ratio(2,8)); // r == 0.75
System.out.println(r.getValue()); // 0.75 printed
1.4 A Special-Purpose Class: A Bank Account 11

System.out.println(r.toString()); // calls toString()


System.out.println(r); // calls toString()
}

To understand the merit of this technique of class design, we might draw an


analogy between a well-designed object and a lightbulb for your back porch.
The protected fields and methods of an object are analogous to the internal de-
sign of the bulb. The observable features, including the voltage and the size of
the socket, are provided without giving any details about the implementation
of the object. If light socket manufacturers depended on a particular imple-
mentation of lightbulbs—for example the socket only supported bright xenon
bulbs—it might ultimately restrict the variety of suppliers of lightbulbs in the
future. Likewise, manufacturers of lightbulbs should be able to have a cer-
tain freedom in their implementation: as long as they only draw current in an
agreed-upon way and as long as their bulb fits the socket, they should be free
to use whatever design they want. Today, most lamps take either incandescent
or fluorescent bulbs.
In the same way that fields are encapsulated by a class, classes may be encap-
sulated by a package. A package is a collection of related classes that implement
some set of structures with a common theme. The classes of this text, for ex-
ample, are members of the structure package. In the same way that there are
users of classes, there are users of packages, and much of the analogy holds. In
particular, classes may be declared public, in which case they may be used by
anyone who imports the package into their program. If a class is not public, it
is automatically considered protected. These protected classes may only be
constructed and used by other classes within the same package.

1.4 A Special-Purpose Class: A Bank Account


We now look at the detailed construction of a simplistic class: a BankAccount.
Many times, it is necessary to provide a tag associated with an instance of a
data structure. You might imagine that your bank balance is kept in a database
at your bank. When you get money for a trip through the Berkshires, you swipe
your card through an automated teller bringing up your account. Your account Automated
number, presumably, is unique to your account. Nothing about you or your teller: a robotic
banking history is actually stored in your account number. Instead, that num- palm reader.
ber is used to find the record linked to your account: the bank searches for a
structure associated with the number you provide. Thus a BankAccount is a sim-
ple, but important, data structure. It has an account (an identifier that never
changes) and a balance (that potentially does change). The public methods of
such a structure are as follows:

public class BankAccount


{
public BankAccount(String acc, double bal)
// pre: account is a string identifying the bank account BankAccount
12 The Object-Oriented Method

// balance is the starting balance


// post: constructs a bank account with desired balance

public boolean equals(Object other)


// pre: other is a valid bank account
// post: returns true if this bank account is the same as other

public String getAccount()


// post: returns the bank account number of this account

public double getBalance()


// post: returns the balance of this bank account

public void deposit(double amount)


// post: deposit money in the bank account

public void withdraw(double amount)


// pre: there are sufficient funds in the account
// post: withdraw money from the bank account
}

The substance of these methods has purposefully been removed because, again,
it is unimportant for us to know exactly how a BankAccount is implemented.
We have ways to construct and compare BankAccounts, as well as ways to read
the account number or balance, or update the balance.
Let’s look at the implementation of these methods, individually. To build a
new bank account, you must use the new operator to call the constructor with
two parameters. The account number provided never changes over the life of
the BankAccount—if it were necessary to change the value of the account num-
ber, a new BankAccount would have to be made, and the balance would have to
be transferred from one to the other. The constructor plays the important role
of performing the one-time initialization of the account number field. Here is
the code for a BankAccount constructor:

protected String account; // the account number


protected double balance; // the balance associated with account

public BankAccount(String acc, double bal)


// pre: account is a string identifying the bank account
// balance is the starting balance
// post: constructs a bank account with desired balance
{
account = acc;
balance = bal;
}

Two fields—account and balance—of the BankAccount object are responsible


for maintaining the object’s state. The account keeps track of the account num-
ber, while the balance field maintains the balance.
1.4 A Special-Purpose Class: A Bank Account 13

Since account numbers are unique to BankAccounts, to check to see if two


accounts are “the same,” we need only compare the account fields. Here’s the
code:

public boolean equals(Object other)


// pre: other is a valid bank account
// post: returns true if this bank account is the same as other
{
BankAccount that = (BankAccount)other;
// two accounts are the same if account numbers are the same
return this.account.equals(that.account);
}

Notice that the BankAccount equals method calls the equals method of the key,
a String. Both BankAccount and String are nonprimitive types, or examples
of Objects. Every object in Java has an equals method. If you don’t explicitly
provide one, the system will write one for you. Generally speaking, one should
assume that the automatically written or default equals method is of little use.
This notion of “equality” of objects is often based on the complexities of our
abstraction; its design must be considered carefully.
One can ask the BankAccount about various aspects of its state by calling its
getAccount or getBalance methods:
public String getAccount()
// post: returns the bank account number of this account
{
return account;
}

public double getBalance()


// post: returns the balance of this bank account
{
return balance;
}

These methods do little more than pass along the information found in the
account and balance fields, respectively. We call such methods accessors. In a
different implementation of the BankAccount, the balance would not have to be
explicitly stored—the value might be, for example, the difference between two
fields, deposits and drafts. Given the interface, it is not much of a concern to
the user which implementation is used.
We provide two more methods, deposit and withdraw, that explicitly mod-
ify the current balance. These are mutator methods:

public void deposit(double amount)


// post: deposit money in the bank account
{
balance = balance + amount;
}
14 The Object-Oriented Method

public void withdraw(double amount)


// pre: there are sufficient funds in the account
// post: withdraw money from the bank account
{
balance = balance - amount;
}

Because we would like to change the balance of the account, it is important to


have a method that allows us to modify it. On the other hand, we purposefully
don’t have a setAccount method because we do not want the account number
to be changed without a considerable amount of work (work that, by the way,
models reality).
Here is a simple application that determines whether it is better to deposit
$100 in an account that bears 5 percent interest for 10 years, or to deposit $100
in an account that bears 2 21 percent interest for 20 years. It makes use of the
BankAccount object just outlined:

public static void main(String[] args)


{
// Question: is it better to invest $100 over 10 years at 5%
// or to invest $100 over 20 years at 2.5% interest?
BankAccount jd = new BankAccount("Jain Dough",100.00);
BankAccount js = new BankAccount("Jon Smythe",100.00);

for (int years = 0; years < 10; years++)


{
jd.deposit(jd.getBalance() * 0.05);
}
for (int years = 0; years < 20; years++)
{
js.deposit(js.getBalance() * 0.025);
}
System.out.println("Jain invests $100 over 10 years at 5%.");
System.out.println("After 10 years " + jd.getAccount() +
" has $" + jd.getBalance());
System.out.println("Jon invests $100 over 20 years at 2.5%.");
System.out.println("After 20 years " + js.getAccount() +
" has $" + js.getBalance());
}

Exercise 1.2 Which method of investment would you pick?

1.5 A General-Purpose Class: An Association


At least Dr. The following small application implements a Pig Latin translator based on a
Seuss started dictionary of nine words. The code makes use of an array of Associations,
with 50 words! each of which establishes a relation between an English word and its Pig Latin
1.5 A General-Purpose Class: An Association 15

translation. For each string passed as the argument to the main method, the
dictionary is searched to determine the appropriate translation.

public class atinLay {


// a pig latin translator for nine words
public static void main(String args[])
{ atinlay
// build and fill out an array of nine translations
Association dict[] = new Association[9];
dict[0] = new Association("a","aay");
dict[1] = new Association("bad","adbay");
dict[2] = new Association("had","adhay");
dict[3] = new Association("dad","adday");
dict[4] = new Association("day","ayday");
dict[5] = new Association("hop","ophay");
dict[6] = new Association("on","onay");
dict[7] = new Association("pop","oppay");
dict[8] = new Association("sad","adsay");

for (int argn = 0; argn < args.length; argn++)


{ // for each argument
for (int dictn = 0; dictn < dict.length; dictn++)
{ // check each dictionary entry
if (dict[dictn].getKey().equals(args[argn]))
System.out.println(dict[dictn].getValue());
}
}
}
}

When this application is run with the arguments hop on pop, the results are

ophay
onay
oppay

While this application may seem rather trivial, it is easy to imagine a large-scale
application with similar needs.3
We now consider the design of the Association. Notice that while the type
of data maintained is different, the purpose of the Association is very similar
to that of the BankAccount class we discussed in Section 1.4. An Association
is a key-value pair such that the key cannot be modified. Here is the interface
for the Association class:

import java.util.Map;

3 Pig Latin has played an important role in undermining court-ordered restrictions placed on music Association
piracy. When Napster—the rebel music trading firm—put in checks to recognize copyrighted music
by title, traders used Pig Latin translators to foil the recognition software!
16 The Object-Oriented Method

public class Association implements Map.Entry


{
public Association(Object key, Object value)
// pre: key is non-null
// post: constructs a key-value pair

public Association(Object key)


// pre: key is non-null
// post: constructs a key-value pair; value is null

public boolean equals(Object other)


// pre: other is non-null Association
// post: returns true iff the keys are equal

public Object getValue()


// post: returns value from association

public Object getKey()


// post: returns key from association

public Object setValue(Object value)


// post: sets association's value to value
}

For the moment, we will ignore the references to Map and Map.entry; these will
be explained later, in Chapter 15. What distinguishes an Association from a
more specialized class, like BankAccount, is that the fields of an Association
are type Object. The use of the word Object in the definition of an Association
makes the definition very general: any value that is of type Object—any non-
primitive data type in Java—can be used for the key and value fields.
Unlike the BankAccount class, this class has two different constructors:
protected Object theKey; // the key of the key-value pair
protected Object theValue; // the value of the key-value pair

public Association(Object key, Object value)


// pre: key is non-null
// post: constructs a key-value pair
{
Assert.pre(key != null, "Key must not be null.");
theKey = key;
theValue = value;
}

public Association(Object key)


// pre: key is non-null
// post: constructs a key-value pair; value is null
{
this(key,null);
}
1.5 A General-Purpose Class: An Association 17

The first constructor—the constructor distinguished by having two parame-


ters—allows the user to construct a new Association by initializing both fields.
On occasion, however, we may wish to have an Association whose key field is
set, but whose value field is left referencing nothing. (An example might be a
medical record: initially the medical history is incomplete, perhaps waiting to
be forwarded from a previous physician.) For this purpose, we provide a sin-
gle parameter constructor that sets the value field to null. Note that we use
this(key,null) as the body. The one-parameter constructor calls this object’s
two-parameter constructor with null as the second parameter. We write the
constructors in this dependent manner so that if the underlying implementation
of the Association had to be changed, only the two-parameter method would
have to be updated. It also reduces the complexity of the code and saves your
fingerprints!
Now, given a particular Association, it is useful to be able to retrieve the
key or value. Since the implementation is hidden, no one outside the class is
able to see it. Users must depend on the accessor methods to observe the data.

public Object getValue()


// post: returns value from association
{
return theValue;
}

public Object getKey()


// post: returns key from association
{
return theKey;
}

When necessary, the method setValue can be used to change the value associ-
ated with the key. Thus, the setValue method simply takes its parameter and
assigns it to the value field:

public Object setValue(Object value)


// post: sets association's value to value
{
Object oldValue = theValue;
theValue = value;
return oldValue;
}

There are other methods that are made available to users of the Association
class, but we will not discuss the details of that code until later. Some of the
methods are required, some are useful, and some are just nice to have around.
While the code may look complicated, we take the time to implement it cor- N
NW

NE

rectly, so that we will not have to reimplement it in the future.


W

E
SW

SE

S
Principle 2 Free the future: reuse code.
18 The Object-Oriented Method

It is difficult to fight the temptation to design data structures from scratch. We


shall see, however, that many of the more complex structures would be very
difficult to construct if we could not base our implementations on the results of
previous work.

1.6 Sketching an Example: A Word List


Suppose we’re interested in building a game of Hangman. The computer selects
random words and we try to guess them. Over several games, the computer
should pick a variety of words and, as each word is used, it should be removed
from the word list. Using an object-oriented approach, we’ll determine the
essential features of a WordList, the Java object that maintains our list of words.
Our approach to designing the data structures has the following five informal
steps:

1. Identify the types of operations you expect to perform on your object.


What operations access your object only by reading its data? What opera-
tions might modify or mutate your objects?

2. Identify, given your operations, those data that support the state of your
object. Information about an object’s state is carried within the object
between operations that modify the state. Since there may be many ways
to encode the state of your object, your description of the state may be
very general.

3. Identify any rules of consistency. In the Ratio class, for example, it would
not be good to have a zero denominator. Also, the numerator and denom-
inator should be in lowest terms.

4. Determine the number and form of the constructors. Constructors are


synthetic: their sole responsibility is to get a new object into a good initial
and consistent state. Don’t forget to consider the best state for an object
constructed using the parameterless default constructor.

5. Identify the types and kinds of information that, though declared pro-
tected, can efficiently provide the information needed by the public
methods. Important choices about the internals of a data structure are
usually made at this time. Sometimes, competing approaches are devel-
oped until a comparative evaluation can be made. That is the subject of
much of this book.

The operations necessary to support a list of words can be sketched out


easily, even if we don’t know the intimate details of constructing the Hangman
game itself. Once we see how the data structure is used, we have a handle on
the design of the interface. Thinking about the overall design of Hangman, we
can identify the following general use of the WordList object:
1.6 Sketching an Example: A Word List 19

WordList list; // declaration


String targetWord;

list = new WordList(10); // construction WordList


list.add("disambiguate"); // is this a word? how about ambiguate?
list.add("inputted"); // really? what verbification!
list.add("subbookkeeper"); // now that's coollooking!
while (!list.isEmpty()) // game loop
{
targetWord = list.selectAny(); // selection
// ...play the game using target word...
list.remove(targetWord); // update
}

Let’s consider these lines. One of the first lines (labeled declaration) de-
clares a reference to a WordList. For a reference to refer to an object, the object
must be constructed. We require, therefore, a constructor for a WordList. The
construction line allocates an initially empty list of words ultimately contain-
ing as many as 10 words. We provide an upper limit on the number of words
that are potentially stored in the list. (We’ll see later that providing such infor-
mation can be useful in designing efficient data structures.) On the next three
lines, three (dubious) words are added to the list.
The while loop accomplishes the task of playing Hangman with the user.
This is possible as long as the list of words is not empty. We use the isEmpty
method to test this fact. At the beginning of each round of Hangman, a random
word is selected (selectAny), setting the targetWord reference. To make things
interesting, we presume that the selectAny method selects a random word each
time. Once the round is finished, we use the remove method to remove the word
from the word list, eliminating it as a choice in future rounds.
There are insights here. First, we have said very little about the Hangman
game other than its interaction with our rather abstract list of words. The details
of the screen’s appearance, for example, do not play much of a role in under-
standing how the WordList structure works. We knew that a list was necessary
for our program, and we considered the program from the point of view of the
object. Second, we don’t really know how the WordList is implemented. The
words may be stored in an array, or in a file on disk, or they may use some tech-
nology that we don’t currently understand. It is only important that we have
faith that the structure can be implemented. We have sketched out the method
headers, or signatures, of the WordList interface, and we have faith that an im-
plementation supporting the interface can be built. Finally we note that what
we have written is not a complete program. Still, from the viewpoint of the
WordList structure, there are few details of the interface that are in question.
A reasoned individual should be able to look at this design and say “this will
work—provided it is implemented correctly.” If a reviewer of the code were to
ask a question about how the structure works, it would lead to a refinement of
our understanding of the interface.
We have, then, the following required interface for the WordList class:
20 The Object-Oriented Method

public class WordList


{
public WordList(int size)
// pre: size >= 0
// post: construct a word list capable of holding "size" words

public boolean isEmpty()


// post: return true iff the word list contains no words

public void add(String s)


// post: add a word to the word list, if it is not already there

public String selectAny()


// pre: the word list is not empty
// post: return a random word from the list

public void remove(String word)


// pre: word is not null
// post: remove the word from the word list
}

We will leave the implementation details of this example until later. You might
consider various ways that the WordList might be implemented. As long as
the methods of the interface can be supported by your data structure, your
implementation is valid.

Exercise 1.3 Finish the sketch of the WordList class to include details about the
state variables.

1.7 Sketching an Example: A Rectangle Class


Suppose we are developing a graphics system that allows the programmer to
draw on a DrawingWindow. This window has, associated with it, a Cartesian
coordinate system that allows us to uniquely address each of the points within
the window. Suppose, also, that we have methods for drawing line segments,
say, using the Line object. How might we implement a rectangle—called a
Rect—to be drawn in the drawing window?
One obvious goal would be to draw a Rect on the DrawingWindow. This
might be accomplished by drawing four line segments. It would be useful to
be able to draw a filled rectangle, or to erase a rectangle (think: draw a filled
rectangle in the background color). We’re not sure how to do this efficiently, but
these latter methods seem plausible and consistent with the notion of drawing.
(We should check to see if it is possible to draw in the background color.) This
leads to the following methods:

Rect public void fillOn(DrawingTarget d)


// pre: d is a valid drawing window
// post: the rectangle is filled on the drawing window d
1.7 Sketching an Example: A Rectangle Class 21

public void clearOn(DrawingTarget d)


// pre: d is a valid drawing window
// post: the rectangle is erased from the drawing window

public void drawOn(DrawingTarget d)


// pre: d is a valid drawing window
// post: the rectangle is drawn on the drawing window

It might be useful to provide some methods to allow us to perform basic calcu-


lations—for example, we might want to find out if the mouse arrow is located
within the Rect. These require accessors for all the obvious data. In the hope
that we might use a Rect multiple times in multiple locations, we also provide
methods for moving and reshaping the Rect.
public boolean contains(Pt p)
// pre: p is a valid point
// post: true iff p is within the rectangle

public int left()


// post: returns left coordinate of the rectangle

public void left(int x)


// post: sets left to x; dimensions remain unchanged

public int width()


// post: returns the width of the rectangle

public void width(int w)


// post: sets width of rectangle, center and height unchanged

public void center(Pt p)


// post: sets center of rect to p; dimensions remain unchanged

public void move(int dx, int dy)


// post: moves rectangle to left by dx and down by dy

public void moveTo(int left, int top)


// post: moves left top of rectangle to (left,top);
// dimensions are unchanged

public void extend(int dx, int dy)


// post: moves sides of rectangle outward by dx and dy

Again, other approaches might be equally valid. No matter how we might rep-
resent a Rect, however, it seems that all rectangular regions with horizontal
and vertical sides can be specified with four integers. We can, then, construct a
Rect by specifying, say, the left and top coordinates and the width and height.
For consistency’s sake, it seems appropriate to allow rectangles to be drawn
anywhere (even off the screen), but the width and height should be non-negative
22 The Object-Oriented Method

values. We should make sure that these constraints appear in the documenta-
tion associated with the appropriate constructors and methods. (See Section 2.2
for more details on how to write these comments.)
Given our thinking, we have some obvious Rect constructors:

public Rect()
// post: constructs a trivial rectangle at origin

public Rect(Pt p1, Pt p2)


// post: constructs a rectangle between p1 and p2

public Rect(int x, int y, int w, int h)


// pre: w >= 0, h >= 0
// post: constructs a rectangle with upper left (x,y),
// width w, height h

We should feel pleased with the progress we have made. We have developed
the signatures for the rectangle interface, even though we have no immediate
application. We also have some emerging answers on approaches to implement-
ing the Rect internally. If we declare our Rect data protected, we can insulate
ourselves from changes suggested by inefficiencies we may yet discover.

Exercise 1.4 Given this sketch of the Rect interface, how would you declare the
private data associated with the Rect object? Given your approach, describe how
you might implement the center(int x, int y) method.

1.8 Interfaces
Sometimes it is useful to describe the interface for a number of different classes,
without committing to an implementation. For example, in later sections of this
text we will implement a number of data structures that are able to be modified
by adding or removing values. We can, for all of these classes, specify a few of
their fundamental methods by using the Java interface declaration:

public interface Structure


{
public int size();
Structure // post: computes number of elements contained in structure

public boolean isEmpty();


// post: return true iff the structure is empty

public void clear();


// post: the structure is empty

public boolean contains(Object value);


// pre: value is non-null
// post: returns true iff value.equals some value in structure
1.8 Interfaces 23

public void add(Object value);


// pre: value is non-null
// post: value has been added to the structure
// replacement policy is not specified

public Object remove(Object value);


// pre: value is non-null
// post: an object equal to value is removed and returned, if found

public java.util.Enumeration elements();


// post: returns an enumeration for traversing structure;
// all structure package implementations return
// an AbstractIterator

public Iterator iterator();


// post: returns an iterator for traversing structure;
// all structure package implementations return
// an AbstractIterator

public Collection values();


// post: returns a Collection that may be used with
// Java's Collection Framework
}

Notice that the body of each method has been replaced by a semicolon. It
is, in fact, illegal to specify any code in a Java interface. Specifying just the
method signatures in an interface is like writing boilerplate for a contract with-
out committing to any implementation. When we decide that we are interested
in constructing a new class, we can choose to have it implement the Structure
interface. For example, our WordList structure of Section 1.6 might have made
use of our Structure interface by beginning its declaration as follows:

public class WordList implements Structure

When the WordList class is compiled by the Java compiler, it checks to see that
each of the methods mentioned in the Structure interface—add, remove, size, WordList
and the others—is actually implemented. In this case, only isEmpty is part of
the WordList specification, so we must either (1) not have WordList implement
the Structure interface or (2) add the methods demanded by Structure.
Interfaces may be extended. Here, we have a possible definition of what it
means to be a Set:

public interface Set extends Structure


{
public void addAll(Structure other);
// pre: other is non-null Set
// post: values from other are added into this set
24 The Object-Oriented Method

public boolean containsAll(Structure other);


// pre: other is non-null
// post: returns true if every value in set is in other

public void removeAll(Structure other);


// pre: other is non-null
// post: values of this set contained in other are removed

public void retainAll(Structure other);


// pre: other is non-null
// post: values not appearing in the other structure are removed
}

A Set requires several set-manipulation methods—addAll (i.e., set union) retain-


All (set intersection), and removeAll (set difference)—as well as the meth-
ods demanded by being a Structure. If we implement these methods for the
WordList class and indicate that WordList implements Set, the WordList class
could be used wherever either a Structure or Set is required. Currently, our
WordList is close to, but not quite, a Structure. Applications that demand
the functionality of a Structure will not be satisfied with a WordList. Having
the class implement an interface increases the flexibility of its use. Still, it may
require considerable work for us to upgrade the WordList class to the level of
a Structure. It may even work against the design of the WordList to provide
the missing methods. The choices we make are part of an ongoing design pro-
cess that attempts to provide the best implementations of structures to meet the
demands of the user.

1.9 Who Is the User?


When implementing data structures using classes and interfaces, it is sometimes
hard to understand why we might be interested in hiding the implementation.
After all, perhaps we know that ultimately we will be the only programmers
making use of these structures. That might be a good point, except that if
you are really a successful programmer, you will implement the data structure
flawlessly this week, use it next week, and not return to look at the code for
a long time. When you do return, your view is effectively that of a user of the
code, with little or no memory of the implementation.
One side effect of this relationship is that we have all been reminded of the
need to write comments. If you do not write comments, you will not be able to
read the code. If, however, you design, document, and implement your interface
carefully, you might not ever have to look at the implementation! That’s good
news because, for most of us, in a couple of months our code is as foreign to
us as if someone else had implemented it. The end result: consider yourself a
user and design and abide by your interface wherever possible. If you know of
some public field that gives a hint of the implementation, do not make use of it.
Instead, access the data through appropriate methods. You will be happy you
1.10 Conclusions 25
N

NW

NE
did later, when you optimize your implementation.

E
SW

SE
S
Principle 3 Design and abide by interfaces as though you were the user.

A quick corollary to this statement is the following:

Principle 4 Declare data fields protected.


N

NW

NE
W

E
If the data are protected, you cannot access them from outside the class, and

SW

SE
S

you are forced to abide by the restricted access of the interface.

1.10 Conclusions
The construction of substantial applications involves the development of com-
plex and interacting structures. In object-oriented languages, we think of these
structures as objects that communicate through the passing of messages or,
more formally, the invocation of methods.
We use object orientation in Java to write the structures found in this book.
It is possible, of course, to design data structures without object orientation, but
any effective data structuring model ultimately depends on the use of some form
of abstraction that allows the programmer to avoid considering the complexities
of particular implementations.
In many languages, including Java, data abstraction is supported by sepa-
rating the interface from the implementation of the data structure. To ensure
that users cannot get past the interface to manipulate the structure in an uncon-
trolled fashion, the system controls access to fields, methods, and classes. The
implementor plays an important role in making sure that the structure is usable,
given the interface. This role is so important that we think of implementation
as supporting the interface—sometimes usefully considered a contract between
the implementor and the user. This analogy is useful because, as in the real
world, if contracts are violated, someone gets upset!
Initial design of the interfaces for data structures arises from considering
how they are used in simple applications. Those method calls that are required
by the application determine the interface for the new structure and constrain,
in various ways, the choices we make in implementing the object.
In our implementation of an Association, we can use the Object class—
that class inherited by all other Java classes—to write very general data struc-
tures. The actual type of value that is stored in the Association is determined
by the values passed to the constructors and mutators of the class. This abil-
ity to pass a subtype to any object that requires a super type is a strength of
object-oriented languages—and helps to reduce the complexity of code.
26 The Object-Oriented Method

Self Check Problems


Solutions to these problems begin on page 441.
1.1 What is meant by abstraction?
1.2 What is procedural abstraction?
1.3 What is data abstraction?
1.4 How does Java support the concept of a message?
1.5 What is the difference between an object and a class?
1.6 What makes up a method’s signature?
1.7 What is the difference between an interface and an implementation?
1.8 What is the difference between an accessor and a mutator?
1.9 A general purpose class, such as an Association, often makes use of
parameters of type Object. Why?
1.10 What is the difference between a reference and an object?
1.11 Who uses a class?

Problems
Solutions to the odd-numbered problems begin on page 451.
1.1 Which of the following are primitive Java types: int, Integer, double,
Double, String, char, Association, BankAccount, boolean, Boolean?
1.2 Which of the following variables are associated with valid constructor
calls?
BankAccount a,b,c,d,e,f;
Association g,h;
a = new BankAccount("Bob",300.0);
b = new BankAccount(300.0,"Bob");
c = new BankAccount(033414,300.0);
d = new BankAccount("Bob",300);
e = new BankAccount("Bob",new Double(300));
f = new BankAccount("Bob",(double)300);
g = new Association("Alice",300.0);
h = new Association("Alice",new Double(300));

1.3 For each pair of classes, indicate which class extends the other:
a. java.lang.Number, java.lang.Double
b. java.lang.Number, java.lang.Integer
c. java.lang.Number, java.lang.Object
d. java.util.Stack, java.util.Vector
1.10 Conclusions 27

e. java.util.Hashtable, java.util.Dictionary

1.4 Rewrite the compound interest program (discussed when considering


BankAccounts in Section 1.4) so that it uses Associations.
1.5 Write a program that attempts to modify one of the private fields of
an Association. When does your environment detect the violation? What
happens?
1.6 Finish the design of a Ratio class that implements a ratio between
two integers. The class should support standard math operations: addition,
subtraction, multiplication, and division. You should also be able to construct
Ratios from either a numerator-denominator pair, or a single integer, or with
no parameter at all (what is a reasonable default value?).
1.7 Amazing fact: If you construct a Ratio from two random integers, 0 <
a, b, the probability that ab is already in reduced terms is π62 . Use this fact to
write a program to compute an approximation to π.
1.8 Design a class to represent a U.S. telephone number. It should sup-
port three types of constructors—one that accepts three numbers, represent-
ing area code, exchange, and extension; another that accepts two integers,
representing a number within your local area code; and a third constructor
that accepts a string of letters and numbers that represent the number (e.g.,
"900-410-TIME"). Provide a method that determines if the number is provided
toll-free (such numbers have area codes of 800, 866, 877, 880, 881, 882, or
888).
1.9 Sometimes it is useful to measure the length of time it takes for a piece
of code to run. (For example, it may help determine where optimizations of
your code would be most effective.) Design a Stopwatch class to support tim-
ing of events. You should consider use of the nanosecond clock in the Java
environment, System.nanoTime(). Like many stopwatches, it should support
starting, temporary stopping, and a reset. The design of the protected section
of the stopwatch should hide the implementation details.
1.10 Design a data structure in Java that represents a musical tone. A tone
can be completely specified as a number of cycles per second (labeled Hz for
hertz), or the number of half steps above a commonly agreed upon tone, such
as A (in modern times, in the United States, considered to be 440 Hz). Higher
tones have higher frequencies. Two tones are an octave (12 semitones) apart
if one
√ has a frequency twice the other. A half step or semitone increase in tone
is 12 2 ≈ 1.06 times higher. Your tone constructors should accept a frequency
(a double) or a number of half steps (an int) above A. Imperfect frequencies
should be tuned to the nearest half step. Once constructed, a tone should be
able to provide its frequency in either cycles per second or half-steps above A.
1.11 Extend Problem 1.10 to allow a second parameter to each constructor
to specify the definition of A upon which the tone’s definition is based. What
modern tone most closely resembles that of modern middle C (9 semitones
below A) if A is defined to be 415 Hz?
28 The Object-Oriented Method

1.12 Design a data structure to represent a combination lock. When the


lock is constructed, it is provided with an arbitrary length array of integers
between 0 and 25 specifying a combination (if no combination is provided,
9 − 0 − 21 − 0 is the default). Initially, it is locked. Two methods—press
and reset—provide a means of entering a combination: press enters the next
integer to be used toward matching the combination, while reset re-readies
the lock for accepting the first integer of the combination. Only when press is
used to match the last integer of the combination does the lock silently unlock.
Mismatched integers require a call to the reset method before the combination
can again be entered. The isLocked method returns true if and only if the lock
is locked. The lock method locks and resets the lock. In the unlocked state only
the isLocked and lock methods have effect. (Aside: Because of the physical
construction of many combination locks, it is often the case that combinations
have patterns. For example, a certain popular lock is constructed with a three-
number combination. The first and last numbers result in the same remainder x
when divided by 4. The middle number has remainder (x + 2)%4 when divided
by 4!)
1.13 Design a data structure to simulate the workings of a car radio. The
state of the radio is on or off, and it may be used to listen to an AM or FM
station. A dozen modifiable push buttons (identified by integers 1 through 12)
allow the listener to store and recall AM or FM frequencies. AM frequencies can
be represented by multiples of 10 in the range 530 to 1610. FM frequencies are
found at multiples of 0.2 in the range 87.9 to 107.9.
1.14 Design a data structure to maintain the position of m coins of radius 1
through m on a board with n ≥ m squares numbered 0 through n − 1. You may
provide whatever interface you find useful to allow your structure to represent
any placement of coins, including stacks of coins in a single cell. A configuration
is valid only if large coins are not stacked on small coins. Your structure should
have an isValid method that returns true if the coins are in a valid position.
(A problem related to this is discussed in Section 10.2.1.)

Top view

Side view
1.11 Laboratory: The Day of the Week
Calculator

Objective. To (re)establish ties with Java: to write a program that reminds us


of the particulars of numeric calculations and array manipulation in Java.
Discussion. In this lab we learn to compute the day of the week for any date
between January 1, 1900, and December 31, 2099.4 During this period of time,
the only calendar adjustment is a leap-year correction every 4 years. (Years
divisible by 100 are normally not leap years, but years divisible by 400 always
are.) Knowing this, the method essentially computes the number of days since
the beginning of the twentieth century in modulo 7 arithmetic. The computed
remainder tells us the day of the week, where 0 is Saturday.
An essential feature of this algorithm involves remembering a short table of
monthly adjustments. Each entry in the table corresponds to a month, where
January is month 1 and December is month 12.

Month 1 2 3 4 5 6 7 8 9 10 11 12
Adjustment 1 4 4 0 2 5 0 3 6 1 4 6

If the year is divisible by 4 (it’s a leap year) and the date is January or February,
you must subtract 1 from the adjustment.
Remembering this table is equivalent to remembering how many days are in
each month. Notice that 144 is 122 , 025 is 52 , 036 is 62 , and 146 is a bit more
than 122 . Given this, the algorithm is fairly simple:

1. Write down the date numerically. The date consists of a month between
1 and 12, a day of the month between 1 and 31, and the number of
years since 1900. Grace Hopper, computer language pioneer, was born
December 9, 1906. That would be represented as year 6. Jana the Giraffe,
of the National Zoo, was born on January 18, 2001. That year would be
represented as year 101.

2. Compute the sum of the following quantities:

• the month adjustment from the given table (e.g., 6 for Admiral Hop-
per)
• the day of the month
• the year

4 This particular technique is due to John Conway, of Princeton University. Professor Conway
answers 10 day of the week problems before gaining access to his computer. His record is at the
time of this writing well under 15 seconds for 10 correctly answered questions. See “Scientist
at Work: John H. Conway; At Home in the Elusive World of Mathematics,” The New York Times,
October 12, 1993.
30 The Object-Oriented Method

• the whole number of times 4 divides the year (e.g., 25 for Jana the
Giraffe)
3. Compute the remainder of the sum of step 2, when divided by 7. The
remainder gives the day of the week, where Saturday is 0, Sunday is 1, etc.
Notice that we can compute the remainders before we compute the sum.
You may also have to compute the remainder after the sum as well, but if
you’re doing this in your head, this considerably simplifies the arithmetic.

What day of the week was Tiger Woods born?


1. Tiger’s birth date is 12-30-75.
2. Remembering that 18 × 4 = 72, we write the sum as follows:

6 + 30 + 75 + 18

which is equivalent to the following sum, modulo 7:

6 + 2 + 5 + 4 = 17 ≡ 3 mod 7

3. He was born on day 3, a Tuesday.


Now you practice: Which of Grace and Jana was born on a Thursday? (The
other was born on a Sunday.)
Procedure. Write a Java program that performs Conway’s day of the week chal-
lenge:
1. Develop an object that can hold a date.
2. Write a method to compute a random date between 1900 and 2099. How
will you limit the range of days potentially generated for any particular
month?
3. Write a method of your date class to compute the day of the week associ-
ated with a date. Be careful: the table given in the discussion has January
as month 1, but Java would prefer it to be month 0! Don’t forget to handle
Jimmy was a the birthday of Jimmy Dorsey (famous jazzman), February 29, 1904.
Monday’s child.
4. Your main method should repeatedly (1) print a random date, (2) read a
predicted day of the week (as an integer/remainder), and (3) check the
correctness of the guess. The program should stop when 10 dates have
been guessed correctly and print the elapsed time. (You may wish to set
this threshold lower while you’re testing the program.)

Helpful Hints. You may find the following Java useful:


1. Random integers may be selected using the java.util.Random class:

Random r = new Random();


int month = (Math.abs(r.nextInt()) % 12) + 1;
1.11 Laboratory: The Day of the Week Calculator 31

You will need to import java.util.Random; at the top of your program


to make use of this class. Be aware that you need to only construct one
random number generator per program run. Also, the random number
generator potentially returns negative numbers. If Math.abs is not used,
these values generate negative remainders.

2. You can find out how many thousandths of seconds have elapsed since
the 1960s, by calling the Java method, System.currentTimeMillis(). It In 2001,
returns a value of type long. We can use this to measure the duration of 1 trillion millis
an experiment, with code similar to the following: since the ’60s.
Dig that!
long start = System.currentTimeMillis();
//
// place experiment to be timed here
//
long duration = System.currentTimeMillis()-start;
System.out.println("time: "+(duration/1000.0)+" seconds.");

The granularity of this timer isn’t any better than a thousandth of a second.
Still, we’re probably not in Conway’s league yet.
After you finish your program, you will find you can quickly learn to answer
10 of these day of the week challenges in less than a minute.
Thought Questions. Consider the following questions as you complete the lab:
1. True or not: In Java is it true that (a % 7) == (a - a/7*7) for a >= 0?
2. It’s rough to start a week on Saturday. What adjustments would be nec-
essary to have a remainder of 0 associated with Sunday? (This might
allow a mnemonic of Nun-day, One-day, Twos-day, Wednesday, Fours-day,
Fives-day, Saturday.)
3. Why do you subtract 1 in a leap year if the date falls before March?
4. It might be useful to compute the portion of any calculation associated
with this year, modulo 7. Remembering that value will allow you to opti- For years
mize your most frequent date calculations. What is the remainder associ- divisible by 28:
ated with this year? think zero!

Notes:
Other documents randomly have
different content
"Do you really think it's good?" Fanny turned about so as to face her
sister. "I'll tell you something, Susan. I just had to write it. I couldn't
help doing it, no matter how hard I tried."

"It's wonderful," continued the admiring Susan.

"But you mustn't tell. You must never tell," besought Fanny. "I'd be
so ashamed of myself, and just think what father might have to say
to me about it!" She swung about to the desk and rested her head in
her hands as though to contemplate the overwhelming things Dr.
Burney might be called upon to say should he discover her offense.
Then impulsively she stretched out her hands and clasped the
manuscript. "Oh, I love it, I love every line I've written there."

Some one else had been climbing the flight of stairs to the third
story, and now came into the room. It was Mrs. Burney, the
stepmother of Fanny and Susan. She went over to the desk and
looked at the pile of written sheets before Fanny could turn them
over or hide them in the drawer. "So this is what you've been about,
is it?" said she, not unkindly, but rather in an amused tone. "I've
wondered where you went when you stole away from the rest of the
family every afternoon. Your father said you wanted to study, but I
told him I didn't approve of young ladies creeping out of sight to
pore over books. So you've been writing a story surreptitiously? Take
my word for it, Fanny, writing books has gone out of fashion."

"I know it," said Fanny, "but I couldn't help it. I'd much rather do
this than practice on the harpsichord."

"But music is a polite accomplishment, my dear, whereas scribbling


is quite the reverse."

"Fanny's isn't scribbling," protested Susan. "It's wonderful. It really


is, mother. It's as good as anything down-stairs in father's library. Let
her read some of it to you."
"No, thank you, Susan. I can understand some parents letting their
children run wild and become novel-writers, but not Dr. Burney. You
must remember you have a position in society to think about, my
dears."

"I know," agreed Fanny guiltily.

"What would the world say," continued Mrs. Burney, "if it should
learn that Dr. Burney's daughter Frances had composed a novel!"

"Father writes books," suggested Susan.

"Yes, but on the subject of music. It's quite another thing to


compose a treatise showing learning. Fanny's writings, if I mistake
not, are merely idle inventions, the stories of events that never
happened to people who never lived."

"Yes, they are," agreed the ashamed Fanny. "I make them up out of
my head as I go along."

"But they're quite as interesting as the things that do happen to real


people," argued the devoted Susan. "More interesting, I think. I
don't know any real person who interests me as much as Caroline in
Fanny's story."

Mrs. Burney smiled. She had no wish to be harsh, but she had very
decided ideas as to what was and what was not proper for young
ladies to do. She was a bustling, sociable person, and she
considered that Fanny was altogether too shy and reserved. She
wanted to make her more like her other sisters, Esther and
Charlotte, both of whom were very popular with the many visitors
who came to see the celebrated Dr. Burney.

"It's for your own good," she said finally. "I shan't tell your father,
but I know he wouldn't approve of your spending your time in this
way."
"I know," said Fanny slowly. "I know what people think of a young
woman who writes. I oughtn't to do it, but the temptation was too
strong for me. I'll give it up, mother, and not steal off here by
myself. I'll try to be more the way you and father want me."

"That's the right spirit, Fanny. You know we're all very proud of you
anyway." Stooping down Mrs. Burney kissed her stepdaughter, and
then left the sisters alone.

For some time there was silence while Fanny stared at the big pile of
closely written sheets which lay in front of her and Susan looked at
her sister. Then with a sigh the older girl rose and gathered the
papers in her arms. "Mother is right. It is wrong of me," said she.
"Would you mind, Susan, coming down into the yard with me?"

"What are you going to do, Fanny?" asked her sister in alarm.

"I've made up my mind what's best to be done, and I'm going to do


it. Come down-stairs, please."

Fanny led the way with the papers, and Susan came after her. They
went down the three flights, through a hall, and out into a paved
court at the rear of the house.

"Will you watch them a minute, please?" said Fanny, as she laid the
papers on the bricks.

She went indoors and soon was back again, with some sticks of
wood, some straw, and a lighted taper in her hand. She laid the
sticks together, stuffed some straw in among them, and then placed
the pile of papers on top.

"Oh, Fanny," cried her sister, "you're not going to burn up all the
story? Oh, poor Caroline! Don't do it, Fanny; think how long it took
to write it and how good it is!"

"I must," said Fanny, very decidedly.


"Oh, please, please don't! It's almost like murder. It's a shame,
Fanny, it is, it's a terrible shame!"

"It hurts me most," said Fanny, "but it's the only way to settle
Caroline once for all." With a very grim face she held the taper to
the straw until it caught fire. In a moment a page of the manuscript
was curling up in flames.

"Oh, Fanny, Fanny!" cried Susan, tears coming to her eyes. She
looked beseechingly at her sister, but the latter's purpose was
inflexible. A few minutes more and the papers were all burning
brightly.

The two girls stood there until the fire had burnt itself out, and then
turned to each other. Tears stood in Fanny's eyes and also in those
of the sympathetic Susan. "Poor Caroline Evelyn," sighed Fanny, "I'm
going to be ever and ever so lonely without her."

Susan slipped her arm about her sister's waist, and they went
indoors to get ready for supper. The young authoress was very quiet
when the family met at table a little later, and had very little
appetite, but the family were quite used to Fanny's reserve, and
none of them thought anything about it except the faithful Susan,
who threw tender reproachful glances across the table at Fanny from
time to time.

The father of these girls, Dr. Charles Burney, was the fashionable
music-master of the day in London. He had made a great success,
and had so many pupils that he had to begin his round of lessons as
early as seven o'clock in the morning, and often was not through
with them until eleven at night. Many a time he dined in a hackney
coach on sandwiches and a glass of sherry and water as he drove
from one house to another. Among his friends were all sorts of
people, musicians, actors, scholars, famous beaux and belles, and as
he was most hospitable his children grew up familiar with many
different types of men and women of the great world of London. The
other girls and the boys were like their father in taking part in all the
entertainments that went on, but Fanny, the second daughter,
although she was admitted to be very bright, was unusually quiet
and retiring. Her teacher called her "the silent, observant Miss
Fanny," and that described her well, because she was always
watching the people about her, and remembering their peculiar tricks
of manner and speech.

But she had a mind of her own and could speak up on occasion.
When she was ten years old her father lived in a house on Poland
Street, next door to a wig-maker, who supplied perukes to the
judges and lawyers of London. The children of the wig-maker and
the Burney children played together in a little garden behind the
former's house, and one day they went into the wig-maker's house,
and each put on one of the fine wigs he had for sale. Then they
began to play in the garden until one of the perukes, which was very
fine and worth over ten guineas, fell into a tub of water and lost all
its curl. The wig-maker came out, fished out the peruke, and
declared it was entirely ruined. With that he spoke very angrily to his
children, when suddenly the quiet Fanny stepped forth, and with the
manner of an old lady said, "What is the use of talking so much
about an accident? The wig is wet, to be sure, and it was a very
good wig, but words will do no good, because, sir, what's done can't
be undone." The wig-maker listened in great surprise, and then
made Fanny a little bow. "Miss Burney speaks with the wisdom of
ages," he said, and without another word went into the house.

Among all their father's friends the Burney children thought there
was no one quite so amusing as the great actor David Garrick. He
would drop in at all hours of the day, and always playing some new
part. Sometimes he would sit still and listen to Dr. Burney talk on the
history of music, and gradually his face and manner would change
until the children could scarcely believe he was the same man who
had entered the room a short time before. He would seem to
become an old crafty man before their very eyes, or a villain from
the slums of London, or a Spanish grandee for the first time in
England. Sometimes he would appear at the house in disguise and
give a new name to the maid and appear in the dining-room as a
stranger to the family. Once he arrived at the door in an old, ill-
fitting wig and shabby clothes and the servant refused to admit him,
taking him for a beggar. "Egad, child," he said to the maid, "you
don't guess whom you have the happiness to see! Do you know that
I am one of the first geniuses of the age? You would faint away
upon the spot if you could only imagine who I am!" The maid, very
much startled, let him pass, and he shambled into the house, again
pretending to be a beggar. The children were always delighted to
have him come, and Fanny in particular, because she had a talent for
mimicking people herself, and she liked to study him. He often sent
them tickets to see him act at Drury Lane Theatre, and there they
saw their friend play the greatest rôles of the English stage as no
actor had ever played them before.

Fanny's particular friend was a Mr. Samuel Crisp, a curious man who
had once been very popular in London, but had retired to a lonely
life in the country at a place called Chesington Hall. He was very
fond of the Burneys and often had them visit him at his country
home. Fanny called him "her dearest daddy," and loved to walk
across the meadows with him, and tell him of the curious people she
had met at her father's house in town. He understood her better
than any one else, and it was to him that she confided the story of
how she had burned the manuscript of her novel. "It was very hard,
Daddy," she said. "I know I oughtn't to want to keep on scribbling,
but somehow I can't help it. I think of so many things, and I want to
make them real, and the only way is to put them down on paper.
People tell me young ladies shouldn't be writing stories, that it's not
genteel, but how can I help myself?"

"You can tell them to me, Fanny, and no one shall ever know you
made them up."
So she unburdened her heart to him, told him of her friend Caroline
Evelyn, the dear child of her brain, of the suitors that young lady
had, and how she treated them, and of her elopement to Gretna
Green, and of the funny people she was continually meeting. Mr.
Crisp listened and smiled, surprised at the girl's powers of
description and humor. Finally he said to her, "It seems to me,
Fanny, that young lady's career is more interesting to you than your
own."

"So it is," she answered. "I think more about her than about any one
else."

"Then," said Mr. Crisp, "in spite of your mother's good advice and
your own judgment I predict that Caroline rises in time from the
flames."

"Do you think so, Daddy? Oh, if she only might! It's well there's no
paper and ink here or I'd begin her over again right on the spot."

Mr. Crisp was right in his prediction. That summer the Burneys went
to the little town of King's Lynn, where Fanny had been born. There
Fanny shut herself up in a summer-house which was called "The
Cabin," and began to rewrite her book. She seized upon every scrap
of white paper that she could find and bore it off with her. She
worked secretly, inventing numberless excuses for the hours she
spent by herself. Gradually the story took shape again, changed in
many ways from its first telling, and with the heroine rechristened
Evelina.

Meantime Dr. Burney had started to prepare his great History of


Music, and asked the help of his daughters to copy it for him. Fanny
wrote the best hand and was the most reliable, so her father made
her his chief secretary, and day after day she worked with him,
having to postpone her own book from week to week. But each time
she came back to it more ardently and each time her pen flew faster
as she sat at her table in the little summer-house. At last she told
Susan about it, and Susan was delighted, and when Fanny read
some of it to her she declared that it was a thousand times better
than the story of Caroline had been.

When her father's History of Music appeared in print it made a great


success, and this stirred the youthful Fanny with the desire to see
what London would think of "Evelina." She was determined,
however, to keep its authorship unknown, and so she carefully
recopied the manuscript in an assumed handwriting in order that no
publisher or printer who had seen her handwriting in any of the
manuscripts she had copied for her father should recognize the
same hand in this. But "Evelina" had grown to be a very long novel,
and by the time she had copied out two volumes of it she grew
tired, and so she wrote a letter, without any signature, to a
publisher, offering to send him the completed part of her novel at
once, and the rest of it during the next year. This publisher replied
that he would not consider the book unless he were told the author's
name. Fanny showed the letter to Susan, and they talked it over, but
decided that she ought not to send her name. She then wrote to
another publisher, making the same offer as she had made to the
first. He said he would like to see the manuscript. Thereupon Fanny
decided to take her brother Charles into the secret and have him
carry the work to the publisher. Charles agreed, and Fanny and
Susan muffled him up in a greatcoat so that he looked much older
than he was, and sent him off. He was not recognized, and when he
called later for an answer he was told that the publisher was pleased
with the book, but could not agree to print it until he should receive
the whole story. That discouraged Fanny, and she let the book lie by
for some time, but finally plucked up courage, and copied out the
third volume.

In the meantime Fanny began to wonder if it would be fair for her to


publish a novel without telling her father, and she decided she ought
to go to him. She caught him just as he was leaving home on a trip,
and said, with many blushes and much confusion, that she had
written a little story and wanted to have it printed without giving her
name. She added that she would not bother him with the manuscript
in any way and begged that he wouldn't ask to see it. The Doctor
was very much amused as well as surprised, and he told her to go
ahead and see what would come of the story.

Better satisfied now that she had her father's consent Fanny sent the
third volume to the publisher, who accepted the book and paid her
twenty pounds for it.

g
Fanny Burney
At length "Evelina" was published. The first Fanny knew of it was
when her stepmother opened a paper one morning at the breakfast
table and read aloud an advertisement announcing the appearance
of a new novel entitled "Evelina; or, A Young Lady's Entrance into
the World." Susan smiled across the table at Fanny, and Charles
winked at her, but she sat very still, her cheeks a fiery red. They did
not give her secret away to the rest of the family, nor mention who
the author was to any of their friends. Shortly afterward Fanny was
ill and went out to Chesington to recuperate. She took the three
volumes of "Evelina" with her, and read them aloud to Mr. Crisp, who
pretended that he had no idea who the author might be and listened
with the most flattering interest to chapter after chapter. "It reminds
me of something," he said one day.

"And what may that be, dear Daddy?" she asked.

"I can't think, but it's prodigiously finer than what I'm trying to
recall," he answered.

By the time she returned home all London was talking about the
new novel and wondering as to the author. Wherever Dr. Burney
went he found people discussing the same subject. The great Dr.
Samuel Johnson declared that it was uncommonly fine, and the
Doctor was the accepted judge of all literary matters. Like all the
others he was sure that the writer was a man, and made many
guesses as to which of the lights of London it might be, but although
one man after another was credited with the honor of having written
it each had to decline the satisfaction. Sir Joshua Reynolds declared
he would give fifty pounds to know the author and meant to find
him, and Sheridan vowed he must get the clever man, whoever he
was, to write him a play.

In the meantime Fanny and Susan were enjoying the mystery


tremendously. It was very delightful to hear all the visitors at their
house talking of "Evelina" without the faintest notion that the author
was sitting there listening to all they had to say. But the time came
when Dr. Burney learned the secret, and his pride in Fanny's
accomplishment could not keep him silent. He told the story to
several of his friends and they, very much amazed, passed it on to
others. Then Mrs. Thrale, a friend of the Burneys, gave a dinner, and
told her guests that they should have the pleasure of meeting the
author of "Evelina" there. When they came they were presented to
the shy, quiet young woman whom they had often seen at Dr.
Burney's house. She was overwhelmed with congratulations, and
when the party came to an end Sir Joshua Reynolds, with a most
courtly bow, bent over her hand, and hoped that he might shortly
have the pleasure of entertaining her at his home in Leicester
Square. When she went home Fanny said to Susan, "The joke of it is
that the people spoke as if they were afraid of me, instead of my
being very much afraid of them."

"Evelina" made Fanny Burney famous. She became a well-known


figure in London life, and wrote other novels, "Cecilia, "Camilla," and
"The Wanderer." She wrote a life of Dr. Burney, and she kept many
diaries, all of which were filled with witty and humorous descriptions
of the people of her age. In time she was appointed a Lady in
Waiting to Queen Charlotte, wife of George III, and took a
prominent part at court. Later she married the French Chevalier
D'Arblay, and went with him to France, where she had many exciting
adventures during the Reign of Terror. She afterward described these
adventures in her diary and it gives a most interesting account of
those thrilling times.

So it was that "the silent, observant Miss Fanny" became one of the
great figures of England at the close of the eighteenth century, and
it was the fact that she could not give up her love of writing and had
to tell the story of her heroine Evelina that first brought her to the
notice of the world and made her famous.

Transcriber's Note:
Minor typographical errors have been corrected without note.

Irregularities and inconsistencies in the text have been retained as printed.


*** END OF THE PROJECT GUTENBERG EBOOK HISTORIC
GIRLHOODS, PART ONE ***

Updated editions will replace the previous one—the old editions will
be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States copyright in
these works, so the Foundation (and you!) can copy and distribute it
in the United States without permission and without paying
copyright royalties. Special rules, set forth in the General Terms of
Use part of this license, apply to copying and distributing Project
Gutenberg™ electronic works to protect the PROJECT GUTENBERG™
concept and trademark. Project Gutenberg is a registered trademark,
and may not be used if you charge for an eBook, except by following
the terms of the trademark license, including paying royalties for use
of the Project Gutenberg trademark. If you do not charge anything
for copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such as
creation of derivative works, reports, performances and research.
Project Gutenberg eBooks may be modified and printed and given
away—you may do practically ANYTHING in the United States with
eBooks not protected by U.S. copyright law. Redistribution is subject
to the trademark license, especially commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the free


distribution of electronic works, by using or distributing this work (or
any other work associated in any way with the phrase “Project
Gutenberg”), you agree to comply with all the terms of the Full
Project Gutenberg™ License available with this file or online at
www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand, agree
to and accept all the terms of this license and intellectual property
(trademark/copyright) agreement. If you do not agree to abide by all
the terms of this agreement, you must cease using and return or
destroy all copies of Project Gutenberg™ electronic works in your
possession. If you paid a fee for obtaining a copy of or access to a
Project Gutenberg™ electronic work and you do not agree to be
bound by the terms of this agreement, you may obtain a refund
from the person or entity to whom you paid the fee as set forth in
paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only be


used on or associated in any way with an electronic work by people
who agree to be bound by the terms of this agreement. There are a
few things that you can do with most Project Gutenberg™ electronic
works even without complying with the full terms of this agreement.
See paragraph 1.C below. There are a lot of things you can do with
Project Gutenberg™ electronic works if you follow the terms of this
agreement and help preserve free future access to Project
Gutenberg™ electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright law
in the United States and you are located in the United States, we do
not claim a right to prevent you from copying, distributing,
performing, displaying or creating derivative works based on the
work as long as all references to Project Gutenberg are removed. Of
course, we hope that you will support the Project Gutenberg™
mission of promoting free access to electronic works by freely
sharing Project Gutenberg™ works in compliance with the terms of
this agreement for keeping the Project Gutenberg™ name associated
with the work. You can easily comply with the terms of this
agreement by keeping this work in the same format with its attached
full Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside the
United States, check the laws of your country in addition to the
terms of this agreement before downloading, copying, displaying,
performing, distributing or creating derivative works based on this
work or any other Project Gutenberg™ work. The Foundation makes
no representations concerning the copyright status of any work in
any country other than the United States.

1.E. Unless you have removed all references to Project Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project Gutenberg™
work (any work on which the phrase “Project Gutenberg” appears,
or with which the phrase “Project Gutenberg” is associated) is
accessed, displayed, performed, viewed, copied or distributed:
This eBook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this eBook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is derived


from texts not protected by U.S. copyright law (does not contain a
notice indicating that it is posted with permission of the copyright
holder), the work can be copied and distributed to anyone in the
United States without paying any fees or charges. If you are
redistributing or providing access to a work with the phrase “Project
Gutenberg” associated with or appearing on the work, you must
comply either with the requirements of paragraphs 1.E.1 through
1.E.7 or obtain permission for the use of the work and the Project
Gutenberg™ trademark as set forth in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is posted


with the permission of the copyright holder, your use and distribution
must comply with both paragraphs 1.E.1 through 1.E.7 and any
additional terms imposed by the copyright holder. Additional terms
will be linked to the Project Gutenberg™ License for all works posted
with the permission of the copyright holder found at the beginning
of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files containing a
part of this work or any other work associated with Project
Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute this


electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the Project
Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if you
provide access to or distribute copies of a Project Gutenberg™ work
in a format other than “Plain Vanilla ASCII” or other format used in
the official version posted on the official Project Gutenberg™ website
(www.gutenberg.org), you must, at no additional cost, fee or
expense to the user, provide a copy, a means of exporting a copy, or
a means of obtaining a copy upon request, of the work in its original
“Plain Vanilla ASCII” or other form. Any alternate format must
include the full Project Gutenberg™ License as specified in
paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™ works
unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or providing


access to or distributing Project Gutenberg™ electronic works
provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project Gutenberg™


electronic work or group of works on different terms than are set
forth in this agreement, you must obtain permission in writing from
the Project Gutenberg Literary Archive Foundation, the manager of
the Project Gutenberg™ trademark. Contact the Foundation as set
forth in Section 3 below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on, transcribe
and proofread works not protected by U.S. copyright law in creating
the Project Gutenberg™ collection. Despite these efforts, Project
Gutenberg™ electronic works, and the medium on which they may
be stored, may contain “Defects,” such as, but not limited to,
incomplete, inaccurate or corrupt data, transcription errors, a
copyright or other intellectual property infringement, a defective or
damaged disk or other medium, a computer virus, or computer
codes that damage or cannot be read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except for


the “Right of Replacement or Refund” described in paragraph 1.F.3,
the Project Gutenberg Literary Archive Foundation, the owner of the
Project Gutenberg™ trademark, and any other party distributing a
Project Gutenberg™ electronic work under this agreement, disclaim
all liability to you for damages, costs and expenses, including legal
fees. YOU AGREE THAT YOU HAVE NO REMEDIES FOR
NEGLIGENCE, STRICT LIABILITY, BREACH OF WARRANTY OR
BREACH OF CONTRACT EXCEPT THOSE PROVIDED IN PARAGRAPH
1.F.3. YOU AGREE THAT THE FOUNDATION, THE TRADEMARK
OWNER, AND ANY DISTRIBUTOR UNDER THIS AGREEMENT WILL
NOT BE LIABLE TO YOU FOR ACTUAL, DIRECT, INDIRECT,
CONSEQUENTIAL, PUNITIVE OR INCIDENTAL DAMAGES EVEN IF
YOU GIVE NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of receiving
it, you can receive a refund of the money (if any) you paid for it by
sending a written explanation to the person you received the work
from. If you received the work on a physical medium, you must
return the medium with your written explanation. The person or
entity that provided you with the defective work may elect to provide
a replacement copy in lieu of a refund. If you received the work
electronically, the person or entity providing it to you may choose to
give you a second opportunity to receive the work electronically in
lieu of a refund. If the second copy is also defective, you may
demand a refund in writing without further opportunities to fix the
problem.

1.F.4. Except for the limited right of replacement or refund set forth
in paragraph 1.F.3, this work is provided to you ‘AS-IS’, WITH NO
OTHER WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of damages.
If any disclaimer or limitation set forth in this agreement violates the
law of the state applicable to this agreement, the agreement shall be
interpreted to make the maximum disclaimer or limitation permitted
by the applicable state law. The invalidity or unenforceability of any
provision of this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the Foundation,


the trademark owner, any agent or employee of the Foundation,
anyone providing copies of Project Gutenberg™ electronic works in
accordance with this agreement, and any volunteers associated with
the production, promotion and distribution of Project Gutenberg™
electronic works, harmless from all liability, costs and expenses,
including legal fees, that arise directly or indirectly from any of the
following which you do or cause to occur: (a) distribution of this or
any Project Gutenberg™ work, (b) alteration, modification, or
additions or deletions to any Project Gutenberg™ work, and (c) any
Defect you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new computers.
It exists because of the efforts of hundreds of volunteers and
donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project Gutenberg™’s
goals and ensuring that the Project Gutenberg™ collection will
remain freely available for generations to come. In 2001, the Project
Gutenberg Literary Archive Foundation was created to provide a
secure and permanent future for Project Gutenberg™ and future
generations. To learn more about the Project Gutenberg Literary
Archive Foundation and how your efforts and donations can help,
see Sections 3 and 4 and the Foundation information page at
www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-profit
501(c)(3) educational corporation organized under the laws of the
state of Mississippi and granted tax exempt status by the Internal
Revenue Service. The Foundation’s EIN or federal tax identification
number is 64-6221541. Contributions to the Project Gutenberg
Literary Archive Foundation are tax deductible to the full extent
permitted by U.S. federal laws and your state’s laws.

The Foundation’s business office is located at 809 North 1500 West,


Salt Lake City, UT 84116, (801) 596-1887. Email contact links and up
to date contact information can be found at the Foundation’s website
and official page at www.gutenberg.org/contact

Section 4. Information about Donations to


the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission of
increasing the number of public domain and licensed works that can
be freely distributed in machine-readable form accessible by the
widest array of equipment including outdated equipment. Many
small donations ($1 to $5,000) are particularly important to
maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws regulating


charities and charitable donations in all 50 states of the United
States. Compliance requirements are not uniform and it takes a
considerable effort, much paperwork and many fees to meet and
keep up with these requirements. We do not solicit donations in
locations where we have not received written confirmation of
compliance. To SEND DONATIONS or determine the status of
compliance for any particular state visit www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states where


we have not met the solicitation requirements, we know of no
prohibition against accepting unsolicited donations from donors in
such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot make


any statements concerning tax treatment of donations received from
outside the United States. U.S. laws alone swamp our small staff.

Please check the Project Gutenberg web pages for current donation
methods and addresses. Donations are accepted in a number of
other ways including checks, online payments and credit card
donations. To donate, please visit: www.gutenberg.org/donate.

Section 5. General Information About


Project Gutenberg™ electronic works
Professor Michael S. Hart was the originator of the Project
Gutenberg™ concept of a library of electronic works that could be
freely shared with anyone. For forty years, he produced and
distributed Project Gutenberg™ eBooks with only a loose network of
volunteer support.
Project Gutenberg™ eBooks are often created from several printed
editions, all of which are confirmed as not protected by copyright in
the U.S. unless a copyright notice is included. Thus, we do not
necessarily keep eBooks in compliance with any particular paper
edition.

Most people start at our website which has the main PG search
facility: www.gutenberg.org.

This website includes information about Project Gutenberg™,


including how to make donations to the Project Gutenberg Literary
Archive Foundation, how to help produce our new eBooks, and how
to subscribe to our email newsletter to hear about new eBooks.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like