100% found this document useful (7 votes)
245 views

[Ebooks PDF] download Data Structures and Algorithms in Java 6th Edition Michael T. Goodrich full chapters

Michael

Uploaded by

ujexlopke
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (7 votes)
245 views

[Ebooks PDF] download Data Structures and Algorithms in Java 6th Edition Michael T. Goodrich full chapters

Michael

Uploaded by

ujexlopke
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 72

Download the full version of the ebook now at ebookultra.

com

Data Structures and Algorithms in Java 6th


Edition Michael T. Goodrich

https://ebookultra.com/download/data-structures-
and-algorithms-in-java-6th-edition-michael-t-
goodrich/

Explore and download more ebook at https://ebookultra.com


Recommended digital products (PDF, EPUB, MOBI) that
you can download immediately if you are interested.

Data Structures and Algorithms in Java 4th Edition Michael


T. Goodrich

https://ebookultra.com/download/data-structures-and-algorithms-in-
java-4th-edition-michael-t-goodrich/

ebookultra.com

AI algorithms data structures and idioms in Prolog Lisp


and Java 6th Edition George F. Luger

https://ebookultra.com/download/ai-algorithms-data-structures-and-
idioms-in-prolog-lisp-and-java-6th-edition-george-f-luger/

ebookultra.com

Java Collections An Introduction to Abstract Data Types


Data Structures and Algorithms 1st Edition David A. Watt

https://ebookultra.com/download/java-collections-an-introduction-to-
abstract-data-types-data-structures-and-algorithms-1st-edition-david-
a-watt/
ebookultra.com

Data Structures Algorithms In Go 1st Edition Hemant Jain

https://ebookultra.com/download/data-structures-algorithms-in-go-1st-
edition-hemant-jain/

ebookultra.com
Growing Algorithms and Data Structures 4th Edition David
Scuse

https://ebookultra.com/download/growing-algorithms-and-data-
structures-4th-edition-david-scuse/

ebookultra.com

Learning JavaScript Data Structures and Algorithms 2nd


Edition Loiane Groner

https://ebookultra.com/download/learning-javascript-data-structures-
and-algorithms-2nd-edition-loiane-groner/

ebookultra.com

Learning F Functional Data Structures and Algorithms 1st


Edition Masood

https://ebookultra.com/download/learning-f-functional-data-structures-
and-algorithms-1st-edition-masood/

ebookultra.com

Concise Notes on Data Structures and Algorithms Ruby


Edition Christopher Fox

https://ebookultra.com/download/concise-notes-on-data-structures-and-
algorithms-ruby-edition-christopher-fox/

ebookultra.com

Data Structures and Algorithms Using Python 1st Edition


Rance D. Necaise

https://ebookultra.com/download/data-structures-and-algorithms-using-
python-1st-edition-rance-d-necaise/

ebookultra.com
Data Structures and Algorithms in Java 6th Edition
Michael T. Goodrich Digital Instant Download
Author(s): Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser
ISBN(s): 9781118771334, 1118771338
Edition: 6
File Details: PDF, 9.40 MB
Year: 2014
Language: english
Data Structures and
Algorithms in Java™
Sixth Edition

Michael T. Goodrich
Department of Computer Science
University of California, Irvine

Roberto Tamassia
Department of Computer Science
Brown University

Michael H. Goldwasser
Department of Mathematics and Computer Science
Saint Louis University
Vice President and Executive Publisher Don Fowley
Executive Editor Beth Lang Golub
Assistant Marketing Manager Debbie Martin
Sponsoring Editor Mary O’Sullivan
Project Editor Ellen Keohane
Associate Production Manager Joyce Poh
Cover Designer Kenji Ngieng

This book was set in LATEX by the authors, and printed and bound by RR Donnelley. The
cover was printed by RR Donnelley.
Trademark Acknowledgments: Java is a trademark of Oracle Corporation. Unix ® is a
registered trademark in the United States and other countries, licensed through X/Open
Company, Ltd. PowerPoint ® is a trademark of Microsoft Corporation. All other product
names mentioned herein are the trademarks of their respective owners.
This book is printed on acid free paper.
Founded in 1807, John Wiley & Sons, Inc. has been a valued source of knowledge and
understanding for more than 200 years, helping people around the world meet their needs
and fulfill their aspirations. Our company is built on a foundation of principles that include
responsibility to the communities we serve and where we live and work. In 2008, we
launched a Corporate Citizenship Initiative, a global effort to address the environmental,
social, economic, and ethical challenges we face in our business. Among the issues we
are addressing are carbon impact, paper specifications and procurement, ethical conduct
within our business and among our vendors, and community and charitable support. For
more information, please visit our website: www.wiley.com/go/citizenship.
Copyright © 2014, 2010 John Wiley & Sons, Inc. All rights reserved. No part of this publi-
cation may be reproduced, stored in a retrieval system or transmitted in any form or by any
means, electronic, mechanical, photocopying, recording, scanning or otherwise, except
as permitted under Sections 107 or 108 of the 1976 United States Copyright Act, with-
out either the prior written permission of the Publisher, or authorization through payment
of the appropriate per-copy fee to the Copyright Clearance Center, Inc. 222 Rosewood
Drive, Danvers, MA 01923, website www.copyright.com. Requests to the Publisher for
permission should be addressed to the Permissions Department, John Wiley & Sons, Inc.,
111 River Street, Hoboken, NJ 07030-5774, (201) 748-6011, fax (201) 748-6008, website
http://www.wiley.com/go/ permissions.
Evaluation copies are provided to qualified academics and professionals for review pur-
poses only, for use in their courses during the next academic year. These copies are licensed
and may not be sold or transferred to a third party. Upon completion of the review period,
please return the evaluation copy to Wiley. Return instructions and a free of charge return
mailing label are available at www.wiley.com/go/returnlabel. If you have chosen to adopt
this textbook for use in your course, please accept this book as your complimentary desk
copy. Outside of the United States, please contact your local sales representative.
ISBN: 978-1-118-77133-4 (paperback)
Printed in the United States of America
10 9 8 7 6 5 4 3 2 1
To Karen, Paul, Anna, and Jack
– Michael T. Goodrich

To Isabel
– Roberto Tamassia

To Susan, Calista, and Maya


– Michael H. Goldwasser
Preface to the Sixth Edition
Data Structures and Algorithms in Java provides an introduction to data structures
and algorithms, including their design, analysis, and implementation. The major
changes in this sixth edition include the following:
• We redesigned the entire code base to increase clarity of presentation and
consistency in style and convention, including reliance on type inference, as
introduced in Java 7, to reduce clutter when instantiating generic types.
• We added 38 new figures, and redesigned 144 existing figures.
• We revised and expanded exercises, bringing the grand total to 794 exercises!
We continue our approach of dividing them into reinforcement, creativity,
and project exercises. However, we have chosen not to reset the number-
ing scheme with each new category, thereby avoiding possible ambiguity
between exercises such as R-7.5, C-7.5, P-7.5.
• The introductory chapters contain additional examples of classes and inheri-
tance, increased discussion of Java’s generics framework, and expanded cov-
erage of cloning and equivalence testing in the context of data structures.
• A new chapter, dedicated to the topic of recursion, provides comprehensive
coverage of material that was previously divided within Chapters 3, 4, and
9 of the fifth edition, while newly introducing the use of recursion when
processing file systems.
• We provide a new empirical study of the efficiency of Java’s StringBuilder
class relative to the repeated concatenation of strings, and then discuss the
theoretical underpinnings of its amortized performance.
• We provide increased discussion of iterators, contrasting between so-called
lazy iterators and snapshot iterators, with examples of both styles of imple-
mentation for several data structures.
• We have increased the use of abstract base classes to reduce redundancy
when providing multiple implementations of a common interface, and the
use of nested classes to provide greater encapsulation for our data structures.
• We have included complete Java implementations for many data structures
and algorithms that were only described with pseudocode in earlier editions.
These new implementations include both array-based and linked-list-based
queue implementations, a heap-based adaptable priority queue, a bottom-up
heap construction, hash tables with either separate chaining or linear probing,
splay trees, dynamic programming for the least-common subsequence prob-
lem, a union-find data structure with path compression, breadth-first search
of a graph, the Floyd-Warshall algorithm for computing a graph’s transitive
closure, topological sorting of a DAG, and both the Prim-Jarnı́k and Kruskal
algorithms for computing a minimum spanning tree.

v
vi Preface

Prerequisites
We assume that the reader is at least vaguely familiar with a high-level program-
ming language, such as C, C++, Python, or Java, and that he or she understands the
main constructs from such a high-level language, including:
• Variables and expressions
• Methods (also known as functions or procedures)
• Decision structures (such as if-statements and switch-statements)
• Iteration structures (for-loops and while-loops)
For readers who are familiar with these concepts, but not with how they are ex-
pressed in Java, we provide a primer on the Java language in Chapter 1. Still, this
book is primarily a data structures book, not a Java book; hence, it does not provide
a comprehensive treatment of Java. Nevertheless, we do not assume that the reader
is necessarily familiar with object-oriented design or with linked structures, such
as linked lists, for these topics are covered in the core chapters of this book.
In terms of mathematical background, we assume the reader is somewhat famil-
iar with topics from high-school mathematics. Even so, in Chapter 4, we discuss
the seven most-important functions for algorithm analysis. In fact, sections that use
something other than one of these seven functions are considered optional, and are
indicated with a star (⋆).

Online Resources
This book is accompanied by an extensive set of online resources, which can be
found at the following website:
www.wiley.com/college/goodrich
Included on this website is a collection of educational aids that augment the topics
of this book, for both students and instructors. For all readers, and especially for
students, we include the following resources:
• All Java source code presented in this book
• An appendix of useful mathematical facts
• PDF handouts of PowerPoint slides (four-per-page)
• A study guide with hints to exercises, indexed by problem number
For instructors using this book, we include the following additional teaching aids:
• Solutions to hundreds of the book’s exercises
• Color versions of all figures and illustrations from the book
• Slides in PowerPoint and PDF (one-per-page) format
The slides are fully editable, so as to allow an instructor using this book full free-
dom in customizing his or her presentations.
Preface vii

Use as a Textbook
The design and analysis of efficient data structures has long been recognized as a
core subject in computing. We feel that the central role of data structure design and
analysis in the curriculum is fully justified, given the importance of efficient data
structures and algorithms in most software systems, including the Web, operating
systems, databases, compilers, and scientific simulation systems.
This book is designed for use in a beginning-level data structures course, or
in an intermediate-level introduction to algorithms course. The chapters for this
book are organized to provide a pedagogical path that starts with the basics of Java
programming and object-oriented design. We then discuss concrete structures in-
cluding arrays and linked lists, and foundational techniques like algorithm analysis
and recursion. In the main portion of the book we present fundamental data struc-
tures and algorithms, concluding with a discussion of memory management. A
detailed table of contents follows this preface, beginning on page x.
To assist instructors in designing a course in the context of the IEEE/ACM
2013 Computing Curriculum, the following table describes curricular knowledge
units that are covered within this book.

Knowledge Unit Relevant Material


AL/Basic Analysis Chapter 4 and Sections 5.2 & 12.1.4
Sections 5.3.3, 12.1.1, 13.2.1, 13.4.2, 13.5,
AL/Algorithmic Strategies
14.6.2 & 14.7
AL/Fundamental Data Structures Sections 3.1.2, 5.1.3, 9.3, 9.4.1, 10.2, 11.1,
and Algorithms 13.2, and Chapters 12 & 14
Sections 7.2.1, 10.4, 11.2–11.6, 12.2.1, 13.3,
AL/Advanced Data Structures
14.5.1 & 15.3
AR/Memory System Organization
Chapter 15
and Architecture
DS/Sets, Relations, and Functions Sections 9.2.2 & 10.5
DS/Proof Techniques Sections 4.4, 5.2, 7.2.3, 9.3.4 & 12.3.1
DS/Basics of Counting Sections 2.2.3, 6.2.2, 8.2.2 & 12.1.4.
DS/Graphs and Trees Chapters 8 and 14
DS/Discrete Probability Sections 3.1.3, 10.2, 10.4.2 & 12.2.1
PL/Object-Oriented Programming Chapter 2 and Sections 7.3, 9.5.1 & 11.2.1
SDF/Algorithms and Design Sections 2.1, 4.3 & 12.1.1
SDF/Fundamental Programming
Chapters 1 & 5
Concepts
SDF/Fundamental Data Structures Chapters 3 & 6, and Sections 1.3, 9.1 & 10.1
SDF/Developmental Methods Sections 1.9 & 2.4
SE/Software Design Section 2.1
Mapping the IEEE/ACM 2013 Computing Curriculum knowledge units to coverage
within this book.
viii Preface

About the Authors


Michael Goodrich received his Ph.D. in Computer Science from Purdue University
in 1987. He is currently a Chancellor’s Professor in the Department of Computer
Science at University of California, Irvine. Previously, he was a professor at Johns
Hopkins University. He is a Fulbright Scholar and a Fellow of the American As-
sociation for the Advancement of Science (AAAS), Association for Computing
Machinery (ACM), and Institute of Electrical and Electronics Engineers (IEEE).
He is a recipient of the IEEE Computer Society Technical Achievement Award,
the ACM Recognition of Service Award, and the Pond Award for Excellence in
Undergraduate Teaching.
Roberto Tamassia received his Ph.D. in Electrical and Computer Engineering
from the University of Illinois at Urbana–Champaign in 1988. He is the Plastech
Professor of Computer Science and the Chair of the Department of Computer Sci-
ence at Brown University. He is also the Director of Brown’s Center for Geometric
Computing. His research interests include information security, cryptography, anal-
ysis, design, and implementation of algorithms, graph drawing, and computational
geometry. He is a Fellow of the American Association for the Advancement of
Science (AAAS), Association for Computing Machinery (ACM) and Institute for
Electrical and Electronic Engineers (IEEE). He is a recipient of the IEEE Computer
Society Technical Achievement Award.
Michael Goldwasser received his Ph.D. in Computer Science from Stanford
University in 1997. He is currently Professor and Director of the Computer Science
program in the Department of Mathematics and Computer Science at Saint Louis
University. He was previously a faculty member in the Department of Computer
Science at Loyola University Chicago. His research interests focus on the design
and implementation of algorithms, having published work involving approximation
algorithms, online computation, computational biology, and computational geom-
etry. He is also active in the computer science education community.

Additional Books by These Authors


• Di Battista, Eades, Tamassia, and Tollis, Graph Drawing, Prentice Hall
• Goodrich, Tamassia, and Goldwasser, Data Structures and Algorithms in Python,
Wiley
• Goodrich, Tamassia, and Mount, Data Structures and Algorithms in C++, Wiley
• Goodrich and Tamassia, Algorithm Design: Foundations, Analysis, and Internet
Examples, Wiley
• Goodrich and Tamassia, Introduction to Computer Security, Addison-Wesley
• Goldwasser and Letscher, Object-Oriented Programming in Python, Prentice
Hall
Preface ix

Acknowledgments
There are so many individuals who have made contributions to the development of
this book over the past decade, it is difficult to name them all. We wish to reit-
erate our thanks to the many research collaborators and teaching assistants whose
feedback shaped the previous versions of this material. The benefits of those con-
tributions carry forward to this book.
For the sixth edition, we are indebted to the outside reviewers and readers for
their copious comments, emails, and constructive criticisms. We therefore thank the
following people for their comments and suggestions: Sameer O. Abufardeh (North
Dakota State University), Mary Boelk (Marquette University), Frederick Crabbe
(United States Naval Academy), Scot Drysdale (Dartmouth College), David Eisner,
Henry A. Etlinger (Rochester Institute of Technology), Chun-Hsi Huang (Univer-
sity of Connecticut), John Lasseter (Hobart and William Smith Colleges), Yupeng
Lin, Suely Oliveira (University of Iowa), Vincent van Oostrom (Utrecht Univer-
sity), Justus Piater (University of Innsbruck), Victor I. Shtern (Boston University),
Tim Soethout, and a number of additional anonymous reviewers.
There have been a number of friends and colleagues whose comments have led
to improvements in the text. We are particularly thankful to Erin Chambers, Karen
Goodrich, David Letscher, David Mount, and Ioannis Tollis for their insightful
comments. In addition, contributions by David Mount to the coverage of recursion
and to several figures are gratefully acknowledged.
We appreciate the wonderful team at Wiley, including our editor, Beth Lang
Golub, for her enthusiastic support of this project from beginning to end, and the
Product Solutions Group editors, Mary O’Sullivan and Ellen Keohane, for carrying
the project to its completion. The quality of this book is greatly enhanced as a result
of the attention to detail demonstrated by our copyeditor, Julie Kennedy. The final
months of the production process were gracefully managed by Joyce Poh.
Finally, we would like to warmly thank Karen Goodrich, Isabel Cruz, Susan
Goldwasser, Giuseppe Di Battista, Franco Preparata, Ioannis Tollis, and our parents
for providing advice, encouragement, and support at various stages of the prepa-
ration of this book, and Calista and Maya Goldwasser for offering their advice
regarding the artistic merits of many illustrations. More importantly, we thank all
of these people for reminding us that there are things in life beyond writing books.

Michael T. Goodrich
Roberto Tamassia
Michael H. Goldwasser
Contents
1 Java Primer 1
1.1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Base Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.1 Creating and Using Objects . . . . . . . . . . . . . . . . . . . . 6
1.2.2 Defining a Class . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 Strings, Wrappers, Arrays, and Enum Types . . . . . . . . . . . . . 17
1.4 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.1 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.2 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4.3 Type Conversions . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.5 Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.5.1 The If and Switch Statements . . . . . . . . . . . . . . . . . . 30
1.5.2 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.5.3 Explicit Control-Flow Statements . . . . . . . . . . . . . . . . . 37
1.6 Simple Input and Output . . . . . . . . . . . . . . . . . . . . . . . . 38
1.7 An Example Program . . . . . . . . . . . . . . . . . . . . . . . . . . 41
1.8 Packages and Imports . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.9 Software Development . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.9.1 Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.9.2 Pseudocode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.9.3 Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.9.4 Documentation and Style . . . . . . . . . . . . . . . . . . . . . 50
1.9.5 Testing and Debugging . . . . . . . . . . . . . . . . . . . . . . 53
1.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

2 Object-Oriented Design 59
2.1 Goals, Principles, and Patterns . . . . . . . . . . . . . . . . . . . . 60
2.1.1 Object-Oriented Design Goals . . . . . . . . . . . . . . . . . . 60
2.1.2 Object-Oriented Design Principles . . . . . . . . . . . . . . . . 61
2.1.3 Design Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . 63
2.2 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
2.2.1 Extending the CreditCard Class . . . . . . . . . . . . . . . . . . 65
2.2.2 Polymorphism and Dynamic Dispatch . . . . . . . . . . . . . . 68
2.2.3 Inheritance Hierarchies . . . . . . . . . . . . . . . . . . . . . . 69
2.3 Interfaces and Abstract Classes . . . . . . . . . . . . . . . . . . . . 76
2.3.1 Interfaces in Java . . . . . . . . . . . . . . . . . . . . . . . . . 76
2.3.2 Multiple Inheritance for Interfaces . . . . . . . . . . . . . . . . 79
2.3.3 Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . 80
2.4 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
2.4.1 Catching Exceptions . . . . . . . . . . . . . . . . . . . . . . . . 82
2.4.2 Throwing Exceptions . . . . . . . . . . . . . . . . . . . . . . . 85
2.4.3 Java’s Exception Hierarchy . . . . . . . . . . . . . . . . . . . . 86
2.5 Casting and Generics . . . . . . . . . . . . . . . . . . . . . . . . . . 88

x
Contents xi
2.5.1 Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
2.5.2 Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
2.6 Nested Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
2.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

3 Fundamental Data Structures 103


3.1 Using Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
3.1.1 Storing Game Entries in an Array . . . . . . . . . . . . . . . . . 104
3.1.2 Sorting an Array . . . . . . . . . . . . . . . . . . . . . . . . . . 110
3.1.3 java.util Methods for Arrays and Random Numbers . . . . . . . 112
3.1.4 Simple Cryptography with Character Arrays . . . . . . . . . . . 115
3.1.5 Two-Dimensional Arrays and Positional Games . . . . . . . . . 118
3.2 Singly Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
3.2.1 Implementing a Singly Linked List Class . . . . . . . . . . . . . 126
3.3 Circularly Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 128
3.3.1 Round-Robin Scheduling . . . . . . . . . . . . . . . . . . . . . 128
3.3.2 Designing and Implementing a Circularly Linked List . . . . . . 129
3.4 Doubly Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
3.4.1 Implementing a Doubly Linked List Class . . . . . . . . . . . . 135
3.5 Equivalence Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
3.5.1 Equivalence Testing with Arrays . . . . . . . . . . . . . . . . . 139
3.5.2 Equivalence Testing with Linked Lists . . . . . . . . . . . . . . 140
3.6 Cloning Data Structures . . . . . . . . . . . . . . . . . . . . . . . . 141
3.6.1 Cloning Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
3.6.2 Cloning Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . 144
3.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

4 Algorithm Analysis 149


4.1 Experimental Studies . . . . . . . . . . . . . . . . . . . . . . . . . . 151
4.1.1 Moving Beyond Experimental Analysis . . . . . . . . . . . . . . 154
4.2 The Seven Functions Used in This Book . . . . . . . . . . . . . . . 156
4.2.1 Comparing Growth Rates . . . . . . . . . . . . . . . . . . . . . 163
4.3 Asymptotic Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
4.3.1 The “Big-Oh” Notation . . . . . . . . . . . . . . . . . . . . . . 164
4.3.2 Comparative Analysis . . . . . . . . . . . . . . . . . . . . . . . 168
4.3.3 Examples of Algorithm Analysis . . . . . . . . . . . . . . . . . 170
4.4 Simple Justification Techniques . . . . . . . . . . . . . . . . . . . . 178
4.4.1 By Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
4.4.2 The “Contra” Attack . . . . . . . . . . . . . . . . . . . . . . . 178
4.4.3 Induction and Loop Invariants . . . . . . . . . . . . . . . . . . 179
4.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182

5 Recursion 189
5.1 Illustrative Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 191
5.1.1 The Factorial Function . . . . . . . . . . . . . . . . . . . . . . 191
5.1.2 Drawing an English Ruler . . . . . . . . . . . . . . . . . . . . . 193
5.1.3 Binary Search . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
xii Contents
5.1.4 File Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
5.2 Analyzing Recursive Algorithms . . . . . . . . . . . . . . . . . . . . 202
5.3 Further Examples of Recursion . . . . . . . . . . . . . . . . . . . . . 206
5.3.1 Linear Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . 206
5.3.2 Binary Recursion . . . . . . . . . . . . . . . . . . . . . . . . . 211
5.3.3 Multiple Recursion . . . . . . . . . . . . . . . . . . . . . . . . 212
5.4 Designing Recursive Algorithms . . . . . . . . . . . . . . . . . . . . 214
5.5 Recursion Run Amok . . . . . . . . . . . . . . . . . . . . . . . . . . 215
5.5.1 Maximum Recursive Depth in Java . . . . . . . . . . . . . . . . 218
5.6 Eliminating Tail Recursion . . . . . . . . . . . . . . . . . . . . . . . 219
5.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

6 Stacks, Queues, and Deques 225


6.1 Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
6.1.1 The Stack Abstract Data Type . . . . . . . . . . . . . . . . . . 227
6.1.2 A Simple Array-Based Stack Implementation . . . . . . . . . . 230
6.1.3 Implementing a Stack with a Singly Linked List . . . . . . . . . 233
6.1.4 Reversing an Array Using a Stack . . . . . . . . . . . . . . . . 234
6.1.5 Matching Parentheses and HTML Tags . . . . . . . . . . . . . 235
6.2 Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
6.2.1 The Queue Abstract Data Type . . . . . . . . . . . . . . . . . 239
6.2.2 Array-Based Queue Implementation . . . . . . . . . . . . . . . 241
6.2.3 Implementing a Queue with a Singly Linked List . . . . . . . . . 245
6.2.4 A Circular Queue . . . . . . . . . . . . . . . . . . . . . . . . . 246
6.3 Double-Ended Queues . . . . . . . . . . . . . . . . . . . . . . . . . . 248
6.3.1 The Deque Abstract Data Type . . . . . . . . . . . . . . . . . 248
6.3.2 Implementing a Deque . . . . . . . . . . . . . . . . . . . . . . 250
6.3.3 Deques in the Java Collections Framework . . . . . . . . . . . . 251
6.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252

7 List and Iterator ADTs 257


7.1 The List ADT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
7.2 Array Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
7.2.1 Dynamic Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 263
7.2.2 Implementing a Dynamic Array . . . . . . . . . . . . . . . . . . 264
7.2.3 Amortized Analysis of Dynamic Arrays . . . . . . . . . . . . . . 265
7.2.4 Java’s StringBuilder class . . . . . . . . . . . . . . . . . . . . . 269
7.3 Positional Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
7.3.1 Positions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
7.3.2 The Positional List Abstract Data Type . . . . . . . . . . . . . 272
7.3.3 Doubly Linked List Implementation . . . . . . . . . . . . . . . . 276
7.4 Iterators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
7.4.1 The Iterable Interface and Java’s For-Each Loop . . . . . . . . 283
7.4.2 Implementing Iterators . . . . . . . . . . . . . . . . . . . . . . 284
7.5 The Java Collections Framework . . . . . . . . . . . . . . . . . . . 288
7.5.1 List Iterators in Java . . . . . . . . . . . . . . . . . . . . . . . 289
7.5.2 Comparison to Our Positional List ADT . . . . . . . . . . . . . 290
Contents xiii
7.5.3 List-Based Algorithms in the Java Collections Framework . . . . 291
7.6 Sorting a Positional List . . . . . . . . . . . . . . . . . . . . . . . . 293
7.7 Case Study: Maintaining Access Frequencies . . . . . . . . . . . . 294
7.7.1 Using a Sorted List . . . . . . . . . . . . . . . . . . . . . . . . 294
7.7.2 Using a List with the Move-to-Front Heuristic . . . . . . . . . . 297
7.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300

8 Trees 307
8.1 General Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
8.1.1 Tree Definitions and Properties . . . . . . . . . . . . . . . . . . 309
8.1.2 The Tree Abstract Data Type . . . . . . . . . . . . . . . . . . 312
8.1.3 Computing Depth and Height . . . . . . . . . . . . . . . . . . . 314
8.2 Binary Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
8.2.1 The Binary Tree Abstract Data Type . . . . . . . . . . . . . . . 319
8.2.2 Properties of Binary Trees . . . . . . . . . . . . . . . . . . . . 321
8.3 Implementing Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
8.3.1 Linked Structure for Binary Trees . . . . . . . . . . . . . . . . . 323
8.3.2 Array-Based Representation of a Binary Tree . . . . . . . . . . 331
8.3.3 Linked Structure for General Trees . . . . . . . . . . . . . . . . 333
8.4 Tree Traversal Algorithms . . . . . . . . . . . . . . . . . . . . . . . 334
8.4.1 Preorder and Postorder Traversals of General Trees . . . . . . . 334
8.4.2 Breadth-First Tree Traversal . . . . . . . . . . . . . . . . . . . 336
8.4.3 Inorder Traversal of a Binary Tree . . . . . . . . . . . . . . . . 337
8.4.4 Implementing Tree Traversals in Java . . . . . . . . . . . . . . 339
8.4.5 Applications of Tree Traversals . . . . . . . . . . . . . . . . . . 343
8.4.6 Euler Tours . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
8.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350

9 Priority Queues 359


9.1 The Priority Queue Abstract Data Type . . . . . . . . . . . . . . . 360
9.1.1 Priorities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
9.1.2 The Priority Queue ADT . . . . . . . . . . . . . . . . . . . . . 361
9.2 Implementing a Priority Queue . . . . . . . . . . . . . . . . . . . . 362
9.2.1 The Entry Composite . . . . . . . . . . . . . . . . . . . . . . . 362
9.2.2 Comparing Keys with Total Orders . . . . . . . . . . . . . . . . 363
9.2.3 The AbstractPriorityQueue Base Class . . . . . . . . . . . . . . 364
9.2.4 Implementing a Priority Queue with an Unsorted List . . . . . . 366
9.2.5 Implementing a Priority Queue with a Sorted List . . . . . . . . 368
9.3 Heaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
9.3.1 The Heap Data Structure . . . . . . . . . . . . . . . . . . . . . 370
9.3.2 Implementing a Priority Queue with a Heap . . . . . . . . . . . 372
9.3.3 Analysis of a Heap-Based Priority Queue . . . . . . . . . . . . . 379
9.3.4 Bottom-Up Heap Construction ⋆ . . . . . . . . . . . . . . . . 380
9.3.5 Using the java.util.PriorityQueue Class . . . . . . . . . . . . . . 384
9.4 Sorting with a Priority Queue . . . . . . . . . . . . . . . . . . . . . 385
9.4.1 Selection-Sort and Insertion-Sort . . . . . . . . . . . . . . . . . 386
9.4.2 Heap-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
xiv Contents
9.5 Adaptable Priority Queues . . . . . . . . . . . . . . . . . . . . . . . 390
9.5.1 Location-Aware Entries . . . . . . . . . . . . . . . . . . . . . . 391
9.5.2 Implementing an Adaptable Priority Queue . . . . . . . . . . . 392
9.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395

10 Maps, Hash Tables, and Skip Lists 401


10.1 Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
10.1.1 The Map ADT . . . . . . . . . . . . . . . . . . . . . . . . . . 403
10.1.2 Application: Counting Word Frequencies . . . . . . . . . . . . . 405
10.1.3 An AbstractMap Base Class . . . . . . . . . . . . . . . . . . . 406
10.1.4 A Simple Unsorted Map Implementation . . . . . . . . . . . . . 408
10.2 Hash Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
10.2.1 Hash Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 411
10.2.2 Collision-Handling Schemes . . . . . . . . . . . . . . . . . . . . 417
10.2.3 Load Factors, Rehashing, and Efficiency . . . . . . . . . . . . . 420
10.2.4 Java Hash Table Implementation . . . . . . . . . . . . . . . . . 422
10.3 Sorted Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
10.3.1 Sorted Search Tables . . . . . . . . . . . . . . . . . . . . . . . 429
10.3.2 Two Applications of Sorted Maps . . . . . . . . . . . . . . . . 433
10.4 Skip Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
10.4.1 Search and Update Operations in a Skip List . . . . . . . . . . 438

10.4.2 Probabilistic Analysis of Skip Lists . . . . . . . . . . . . . . . 442
10.5 Sets, Multisets, and Multimaps . . . . . . . . . . . . . . . . . . . . 445
10.5.1 The Set ADT . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
10.5.2 The Multiset ADT . . . . . . . . . . . . . . . . . . . . . . . . 447
10.5.3 The Multimap ADT . . . . . . . . . . . . . . . . . . . . . . . . 448
10.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451

11 Search Trees 459


11.1 Binary Search Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
11.1.1 Searching Within a Binary Search Tree . . . . . . . . . . . . . . 461
11.1.2 Insertions and Deletions . . . . . . . . . . . . . . . . . . . . . . 463
11.1.3 Java Implementation . . . . . . . . . . . . . . . . . . . . . . . 466
11.1.4 Performance of a Binary Search Tree . . . . . . . . . . . . . . . 470
11.2 Balanced Search Trees . . . . . . . . . . . . . . . . . . . . . . . . . 472
11.2.1 Java Framework for Balancing Search Trees . . . . . . . . . . . 475
11.3 AVL Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
11.3.1 Update Operations . . . . . . . . . . . . . . . . . . . . . . . . 481
11.3.2 Java Implementation . . . . . . . . . . . . . . . . . . . . . . . 486
11.4 Splay Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
11.4.1 Splaying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
11.4.2 When to Splay . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
11.4.3 Java Implementation . . . . . . . . . . . . . . . . . . . . . . . 494
11.4.4 Amortized Analysis of Splaying ⋆ . . . . . . . . . . . . . . . . 495
11.5 (2,4) Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
11.5.1 Multiway Search Trees . . . . . . . . . . . . . . . . . . . . . . 500
11.5.2 (2,4)-Tree Operations . . . . . . . . . . . . . . . . . . . . . . . 503
Contents xv
11.6 Red-Black Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
11.6.1 Red-Black Tree Operations . . . . . . . . . . . . . . . . . . . . 512
11.6.2 Java Implementation . . . . . . . . . . . . . . . . . . . . . . . 522
11.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525

12 Sorting and Selection 531


12.1 Merge-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
12.1.1 Divide-and-Conquer . . . . . . . . . . . . . . . . . . . . . . . . 532
12.1.2 Array-Based Implementation of Merge-Sort . . . . . . . . . . . 537
12.1.3 The Running Time of Merge-Sort . . . . . . . . . . . . . . . . 538
12.1.4 Merge-Sort and Recurrence Equations . . . . . ⋆ . . . . . . . . 540
12.1.5 Alternative Implementations of Merge-Sort . . . . . . . . . . . 541
12.2 Quick-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
12.2.1 Randomized Quick-Sort . . . . . . . . . . . . . . . . . . . . . . 551
12.2.2 Additional Optimizations for Quick-Sort . . . . . . . . . . . . . 553
12.3 Studying Sorting through an Algorithmic Lens . . . . . . . . . . . 556
12.3.1 Lower Bound for Sorting . . . . . . . . . . . . . . . . . . . . . 556
12.3.2 Linear-Time Sorting: Bucket-Sort and Radix-Sort . . . . . . . . 558
12.4 Comparing Sorting Algorithms . . . . . . . . . . . . . . . . . . . . . 561
12.5 Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
12.5.1 Prune-and-Search . . . . . . . . . . . . . . . . . . . . . . . . . 563
12.5.2 Randomized Quick-Select . . . . . . . . . . . . . . . . . . . . . 564
12.5.3 Analyzing Randomized Quick-Select . . . . . . . . . . . . . . . 565
12.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566

13 Text Processing 573


13.1 Abundance of Digitized Text . . . . . . . . . . . . . . . . . . . . . . 574
13.1.1 Notations for Character Strings . . . . . . . . . . . . . . . . . . 575
13.2 Pattern-Matching Algorithms . . . . . . . . . . . . . . . . . . . . . 576
13.2.1 Brute Force . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
13.2.2 The Boyer-Moore Algorithm . . . . . . . . . . . . . . . . . . . 578
13.2.3 The Knuth-Morris-Pratt Algorithm . . . . . . . . . . . . . . . . 582
13.3 Tries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
13.3.1 Standard Tries . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
13.3.2 Compressed Tries . . . . . . . . . . . . . . . . . . . . . . . . . 590
13.3.3 Suffix Tries . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592
13.3.4 Search Engine Indexing . . . . . . . . . . . . . . . . . . . . . . 594
13.4 Text Compression and the Greedy Method . . . . . . . . . . . . . 595
13.4.1 The Huffman Coding Algorithm . . . . . . . . . . . . . . . . . 596
13.4.2 The Greedy Method . . . . . . . . . . . . . . . . . . . . . . . . 597
13.5 Dynamic Programming . . . . . . . . . . . . . . . . . . . . . . . . . 598
13.5.1 Matrix Chain-Product . . . . . . . . . . . . . . . . . . . . . . . 598
13.5.2 DNA and Text Sequence Alignment . . . . . . . . . . . . . . . 601
13.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
xvi Contents
14 Graph Algorithms 611
14.1 Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
14.1.1 The Graph ADT . . . . . . . . . . . . . . . . . . . . . . . . . . 618
14.2 Data Structures for Graphs . . . . . . . . . . . . . . . . . . . . . . . 619
14.2.1 Edge List Structure . . . . . . . . . . . . . . . . . . . . . . . . 620
14.2.2 Adjacency List Structure . . . . . . . . . . . . . . . . . . . . . 622
14.2.3 Adjacency Map Structure . . . . . . . . . . . . . . . . . . . . . 624
14.2.4 Adjacency Matrix Structure . . . . . . . . . . . . . . . . . . . . 625
14.2.5 Java Implementation . . . . . . . . . . . . . . . . . . . . . . . 626
14.3 Graph Traversals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
14.3.1 Depth-First Search . . . . . . . . . . . . . . . . . . . . . . . . 631
14.3.2 DFS Implementation and Extensions . . . . . . . . . . . . . . . 636
14.3.3 Breadth-First Search . . . . . . . . . . . . . . . . . . . . . . . 640
14.4 Transitive Closure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643
14.5 Directed Acyclic Graphs . . . . . . . . . . . . . . . . . . . . . . . . 647
14.5.1 Topological Ordering . . . . . . . . . . . . . . . . . . . . . . . 647
14.6 Shortest Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651
14.6.1 Weighted Graphs . . . . . . . . . . . . . . . . . . . . . . . . . 651
14.6.2 Dijkstra’s Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 653
14.7 Minimum Spanning Trees . . . . . . . . . . . . . . . . . . . . . . . . 662
14.7.1 Prim-Jarnı́k Algorithm . . . . . . . . . . . . . . . . . . . . . . 664
14.7.2 Kruskal’s Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 667
14.7.3 Disjoint Partitions and Union-Find Structures . . . . . . . . . . 672
14.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677

15 Memory Management and B-Trees 687


15.1 Memory Management . . . . . . . . . . . . . . . . . . . . . . . . . . 688
15.1.1 Stacks in the Java Virtual Machine . . . . . . . . . . . . . . . . 688
15.1.2 Allocating Space in the Memory Heap . . . . . . . . . . . . . . 691
15.1.3 Garbage Collection . . . . . . . . . . . . . . . . . . . . . . . . 693
15.2 Memory Hierarchies and Caching . . . . . . . . . . . . . . . . . . . 695
15.2.1 Memory Systems . . . . . . . . . . . . . . . . . . . . . . . . . 695
15.2.2 Caching Strategies . . . . . . . . . . . . . . . . . . . . . . . . 696
15.3 External Searching and B-Trees . . . . . . . . . . . . . . . . . . . . 701
15.3.1 (a, b) Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
15.3.2 B-Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
15.4 External-Memory Sorting . . . . . . . . . . . . . . . . . . . . . . . . 705
15.4.1 Multiway Merging . . . . . . . . . . . . . . . . . . . . . . . . . 706
15.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707

Bibliography 710

Index 714

Useful Mathematical Facts available at www.wiley.com/college/goodrich


Chapter

1 Java Primer

Contents

1.1 Getting Started . . . . . . . . . . . . . . . . . . . . . . . . 2


1.1.1 Base Types . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Classes and Objects . . . . . . . . . . . . . . . . . . . . . . 5
1.2.1 Creating and Using Objects . . . . . . . . . . . . . . . . . 6
1.2.2 Defining a Class . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 Strings, Wrappers, Arrays, and Enum Types . . . . . . . . 17
1.4 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.1 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.2 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4.3 Type Conversions . . . . . . . . . . . . . . . . . . . . . . 28
1.5 Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.5.1 The If and Switch Statements . . . . . . . . . . . . . . . 30
1.5.2 Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.5.3 Explicit Control-Flow Statements . . . . . . . . . . . . . . 37
1.6 Simple Input and Output . . . . . . . . . . . . . . . . . . . 38
1.7 An Example Program . . . . . . . . . . . . . . . . . . . . . 41
1.8 Packages and Imports . . . . . . . . . . . . . . . . . . . . . 44
1.9 Software Development . . . . . . . . . . . . . . . . . . . . 46
1.9.1 Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.9.2 Pseudocode . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.9.3 Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
1.9.4 Documentation and Style . . . . . . . . . . . . . . . . . . 50
1.9.5 Testing and Debugging . . . . . . . . . . . . . . . . . . . 53
1.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
2 Chapter 1. Java Primer

1.1 Getting Started


Building data structures and algorithms requires that we communicate detailed in-
structions to a computer. An excellent way to perform such communication is
using a high-level computer language, such as Java. In this chapter, we provide an
overview of the Java programming language, and we continue this discussion in the
next chapter, focusing on object-oriented design principles. We assume that readers
are somewhat familiar with an existing high-level language, although not necessar-
ily Java. This book does not provide a complete description of the Java language
(there are numerous language references for that purpose), but it does introduce all
aspects of the language that are used in code fragments later in this book.
We begin our Java primer with a program that prints “Hello Universe!” on the
screen, which is shown in a dissected form in Figure 1.1.

Figure 1.1: A “Hello Universe!” program.

In Java, executable statements are placed in functions, known as methods, that


belong to class definitions. The Universe class, in our first example, is extremely
simple; its only method is a static one named main, which is the first method to be
executed when running a Java program. Any set of statements between the braces
“{” and “}” define a program block. Notice that the entire Universe class definition
is delimited by such braces, as is the body of the main method.
The name of a class, method, or variable in Java is called an identifier, which
can be any string of characters as long as it begins with a letter and consists of let-
ters, numbers, and underscore characters (where “letter” and “number” can be from
any written language defined in the Unicode character set). We list the exceptions
to this general rule for Java identifiers in Table 1.1.
1.1. Getting Started 3

Reserved Words
abstract default goto package synchronized
assert do if private this
boolean double implements protected throw
break else import public throws
byte enum instanceof return transient
case extends int short true
catch false interface static try
char final long strictfp void
class finally native super volatile
const float new switch while
continue for null

Table 1.1: A listing of the reserved words in Java. These names cannot be used as
class, method, or variable names.

Comments

In addition to executable statements and declarations, Java allows a programmer


to embed comments, which are annotations provided for human readers that are
not processed by the Java compiler. Java allows two kinds of comments: inline
comments and block comments. Java uses a “//” to begin an inline comment,
ignoring everything subsequently on that line. For example:

// This is an inline comment.

We will intentionally color all comments in blue in this book, so that they are not
confused with executable code.
While inline comments are limited to one line, Java allows multiline comments
in the form of block comments. Java uses a “/*” to begin a block comment and a
“*/” to close it. For example:

/*
* This is a block comment.
*/

Block comments that begin with “/**” (note the second asterisk) have a special
purpose, allowing a program, called Javadoc, to read these comments and automat-
ically generate software documentation. We discuss the syntax and interpretation
of Javadoc comments in Section 1.9.4.
4 Chapter 1. Java Primer

1.1.1 Base Types

For the most commonly used data types, Java provides the following base types
(also called primitive types):

boolean a boolean value: true or false


char 16-bit Unicode character
byte 8-bit signed two’s complement integer
short 16-bit signed two’s complement integer
int 32-bit signed two’s complement integer
long 64-bit signed two’s complement integer
float 32-bit floating-point number (IEEE 754-1985)
double 64-bit floating-point number (IEEE 754-1985)

A variable having one of these types simply stores a value of that type. Integer
constants, like 14 or 195, are of type int, unless followed immediately by an ‘L’
or ‘l’, in which case they are of type long. Floating-point constants, like 3.1416
or 6.022e23, are of type double, unless followed immediately by an ‘F’ or ‘f’, in
which case they are of type float. Code Fragment 1.1 demonstrates the declaration,
and initialization in some cases, of various base-type variables.

1 boolean flag = true;


2 boolean verbose, debug; // two variables declared, but not yet initialized
3 char grade = 'A';
4 byte b = 12;
5 short s = 24;
6 int i, j, k = 257; // three variables declared; only k initialized
7 long l = 890L; // note the use of ”L” here
8 float pi = 3.1416F; // note the use of ”F” here
9 double e = 2.71828, a = 6.022e23; // both variables are initialized
Code Fragment 1.1: Declarations and initializations of several base-type variables.

Note that it is possible to declare (and initialize) multiple variables of the same
type in a single statement, as done on lines 2, 6, and 9 of this example. In this code
fragment, variables verbose, debug, i, and j remain uninitialized. Variables declared
locally within a block of code must be initialized before they are first used.
A nice feature of Java is that when base-type variables are declared as instance
variables of a class (see next section), Java ensures initial default values if not ex-
plicitly initialized. In particular, all numeric types are initialized to zero, a boolean
is initialized to false, and a character is initialized to the null character by default.
1.2. Classes and Objects 5

1.2 Classes and Objects


In more complex Java programs, the primary “actors” are objects. Every object is
an instance of a class, which serves as the type of the object and as a blueprint,
defining the data which the object stores and the methods for accessing and modi-
fying that data. The critical members of a class in Java are the following:
• Instance variables, which are also called fields, represent the data associated
with an object of a class. Instance variables must have a type, which can
either be a base type (such as int, float, or double) or any class type (also
known as a reference type for reasons we soon explain).
• Methods in Java are blocks of code that can be called to perform actions
(similar to functions and procedures in other high-level languages). Methods
can accept parameters as arguments, and their behavior may depend on the
object upon which they are invoked and the values of any parameters that are
passed. A method that returns information to the caller without changing any
instance variables is known as an accessor method, while an update method
is one that may change one or more instance variables when called.
For the purpose of illustration, Code Fragment 1.2 provides a complete def-
inition of a very simple class named Counter, to which we will refer during the
remainder of this section.

1 public class Counter {


2 private int count; // a simple integer instance variable
3 public Counter( ) { } // default constructor (count is 0)
4 public Counter(int initial) { count = initial; } // an alternate constructor
5 public int getCount( ) { return count; } // an accessor method
6 public void increment( ) { count++; } // an update method
7 public void increment(int delta) { count += delta; } // an update method
8 public void reset( ) { count = 0; } // an update method
9 }
Code Fragment 1.2: A Counter class for a simple counter, which can be queried,
incremented, and reset.

This class includes one instance variable, named count, which is declared at
line 2. As noted on the previous page, the count will have a default value of zero,
unless we otherwise initialize it.
The class includes two special methods known as constructors (lines 3 and
4), one accessor method (line 5), and three update methods (lines 6–8). Unlike
the original Universe class from page 2, our Counter class does not have a main
method, and so it cannot be run as a complete program. Instead, the purpose of the
Counter class is to create instances that might be used as part of a larger program.
6 Chapter 1. Java Primer

1.2.1 Creating and Using Objects


Before we explore the intricacies of the syntax for our Counter class definition, we
prefer to describe how Counter instances can be created and used. To this end,
Code Fragment 1.3 presents a new class named CounterDemo.
1 public class CounterDemo {
2 public static void main(String[ ] args) {
3 Counter c; // declares a variable; no counter yet constructed
4 c = new Counter( ); // constructs a counter; assigns its reference to c
5 c.increment( ); // increases its value by one
6 c.increment(3); // increases its value by three more
7 int temp = c.getCount( ); // will be 4
8 c.reset( ); // value becomes 0
9 Counter d = new Counter(5);// declares and constructs a counter having value 5
10 d.increment( ); // value becomes 6
11 Counter e = d; // assigns e to reference the same object as d
12 temp = e.getCount( ); // will be 6 (as e and d reference the same counter)
13 e.increment(2); // value of e (also known as d) becomes 8
14 }
15 }
Code Fragment 1.3: A demonstration of the use of Counter instances.
There is an important distinction in Java between the treatment of base-type
variables and class-type variables. At line 3 of our demonstration, a new variable c
is declared with the syntax:
Counter c;
This establishes the identifier, c, as a variable of type Counter, but it does not create
a Counter instance. Classes are known as reference types in Java, and a variable of
that type (such as c in our example) is known as a reference variable. A reference
variable is capable of storing the location (i.e., memory address) of an object from
the declared class. So we might assign it to reference an existing instance or a
newly constructed instance. A reference variable can also store a special value,
null, that represents the lack of an object.
In Java, a new object is created by using the new operator followed by a call to
a constructor for the desired class; a constructor is a method that always shares the
same name as its class. The new operator returns a reference to the newly created
instance; the returned reference is typically assigned to a variable for further use.
In Code Fragment 1.3, a new Counter is constructed at line 4, with its reference
assigned to the variable c. That relies on a form of the constructor, Counter( ), that
takes no arguments between the parentheses. (Such a zero-parameter constructor
is known as a default constructor.) At line 9 we construct another counter using a
one-parameter form that allows us to specify a nonzero initial value for the counter.
1.2. Classes and Objects 7
Three events occur as part of the creation of a new instance of a class:
• A new object is dynamically allocated in memory, and all instance variables
are initialized to standard default values. The default values are null for
reference variables and 0 for all base types except boolean variables (which
are false by default).
• The constructor for the new object is called with the parameters specified.
The constructor may assign more meaningful values to any of the instance
variables, and perform any additional computations that must be done due to
the creation of this object.
• After the constructor returns, the new operator returns a reference (that is, a
memory address) to the newly created object. If the expression is in the form
of an assignment statement, then this address is stored in the object variable,
so the object variable refers to this newly created object.

The Dot Operator


One of the primary uses of an object reference variable is to access the members of
the class for this object, an instance of its class. That is, an object reference vari-
able is useful for accessing the methods and instance variables associated with an
object. This access is performed with the dot (“.”) operator. We call a method asso-
ciated with an object by using the reference variable name, following that by the dot
operator and then the method name and its parameters. For example, in Code Frag-
ment 1.3, we call c.increment( ) at line 5, c.increment(3) at line 6, c.getCount( )
at line 7, and c.reset( ) at line 8. If the dot operator is used on a reference that is
currently null, the Java runtime environment will throw a NullPointerException.
If there are several methods with this same name defined for a class, then the
Java runtime system uses the one that matches the actual number of parameters
sent as arguments, as well as their respective types. For example, our Counter
class supports two methods named increment: a zero-parameter form and a one-
parameter form. Java determines which version to call when evaluating commands
such as c.increment( ) versus c.increment(3). A method’s name combined with the
number and types of its parameters is called a method’s signature, for it takes all
of these parts to determine the actual method to perform for a certain method call.
Note, however, that the signature of a method in Java does not include the type that
the method returns, so Java does not allow two methods with the same signature to
return different types.
A reference variable v can be viewed as a “pointer” to some object o. It is as if
the variable is a holder for a remote control that can be used to control the newly
created object (the device). That is, the variable has a way of pointing at the object
and asking it to do things or give us access to its data. We illustrate this concept in
Figure 1.2. Using the remote control analogy, a null reference is a remote control
holder that is empty.
8 Chapter 1. Java Primer

Figure 1.2: Illustrating the relationship between objects and object reference vari-
ables. When we assign an object reference (that is, memory address) to a reference
variable, it is as if we are storing that object’s remote control at that variable.

There can, in fact, be many references to the same object, and each reference to
a specific object can be used to call methods on that object. Such a situation would
correspond to our having many remote controls that all work on the same device.
Any of the remotes can be used to make a change to the device (like changing a
channel on a television). Note that if one remote control is used to change the
device, then the (single) object pointed to by all the remotes changes. Likewise, if
one object reference variable is used to change the state of the object, then its state
changes for all the references to it. This behavior comes from the fact that there are
many references, but they all point to the same object.
Returning to our CounterDemo example, the instance constructed at line 9 as
Counter d = new Counter(5);
is a distinct instance from the one identified as c. However, the command at line 11,
Counter e = d;
does not result in the construction of a new Counter instance. This declares a new
reference variable named e, and assigns that variable a reference to the existing
counter instance currently identified as d. At that point, both variables d and e are
aliases for the same object, and so the call to d.getCount( ) behaves just as would
e.getCount( ). Similarly, the call to update method e.increment(2) is affecting the
same object identified by d.
It is worth noting, however, that the aliasing of two reference variables to the
same object is not permanent. At any point in time, we may reassign a reference
variable to a new instance, to a different existing instance, or to null.
1.2. Classes and Objects 9

1.2.2 Defining a Class


Thus far, we have provided definitions for two simple classes: the Universe class
on page 2 and the Counter class on page 5. At its core, a class definition is a block
of code, delimited by braces “{” and “}” , within which is included declarations of
instance variables and methods that are the members of the class. In this section,
we will undertake a deeper examination of class definitions in Java.

Modifiers
Immediately before the definition of a class, instance variable, or method in Java,
keywords known as modifiers can be placed to convey additional stipulations about
that definition.

Access Control Modifiers


The first set of modifiers we discuss are known as access control modifiers, as they
control the level of access (also known as visibility) that the defining class grants
to other classes in the context of a larger Java program. The ability to limit access
among classes supports a key principle of object-orientation known as encapsula-
tion (see Section 2.1). In general, the different access control modifiers and their
meaning are as follows:
• The public class modifier designates that all classes may access the defined
aspect. For example, line 1 of of Code Fragment 1.2 designates
public class Counter {
and therefore all other classes (such as CounterDemo) are allowed to con-
struct new instances of the Counter class, as well as to declare variables and
parameters of type Counter. In Java, each public class must be defined in a
separate file named classname.java, where “classname” is the name of the
class (for example, file Counter.java for the Counter class definition).
The designation of public access for a particular method of a class allows
any other class to make a call to that method. For example, line 5 of Code
Fragment 1.2 designates
public int getCount( ) { return count; }
which is why the CounterDemo class may call c.getCount( ).
If an instance variable is declared as public, dot notation can be used to di-
rectly access the variable by code in any other class that possesses a reference
to an instance of this class. For example, were the count variable of Counter
to be declared as public (which it is not), then the CounterDemo would be
allowed to read or modify that variable using a syntax such as c.count.
10 Chapter 1. Java Primer
• The protected class modifier designates that access to the defined aspect is
only granted to the following groups of other classes:
◦ Classes that are designated as subclasses of the given class through
inheritance. (We will discuss inheritance as the focus of Section 2.2.)
◦ Classes that belong to the same package as the given class. (We will
discuss packages within Section 1.8.)
• The private class modifier designates that access to a defined member of a
class be granted only to code within that class. Neither subclasses nor any
other classes have access to such members.
For example, we defined the count instance variable of the Counter class to
have private access level. We were allowed to read or edit its value from
within methods of that class (such as getCount, increment, and reset), but
other classes such as CounterDemo cannot directly access that field. Of
course, we did provide other public methods to grant outside classes with
behaviors that depended on the current count value.
• Finally, we note that if no explicit access control modifier is given, the de-
fined aspect has what is known as package-private access level. This allows
other classes in the same package (see Section 1.8) to have access, but not
any classes or subclasses from other packages.

The static Modifier


The static modifier in Java can be declared for any variable or method of a class
(or for a nested class, as we will introduce in Section 2.6).
When a variable of a class is declared as static, its value is associated with
the class as a whole, rather than with each individual instance of that class. Static
variables are used to store “global” information about a class. (For example, a static
variable could be used to maintain the total number of instances of that class that
have been created.) Static variables exist even if no instance of their class exists.
When a method of a class is declared as static, it too is associated with the
class itself, and not with a particular instance of the class. That means that the
method is not invoked on a particular instance of the class using the traditional dot
notation. Instead, it is typically invoked using the name of the class as a qualifier.
As an example, in the java.lang package, which is part of the standard Java
distribution, there is a Math class that provides many static methods, including one
named sqrt that computes square roots of numbers. To compute a square root, you
do not need to create an instance of the Math class; that method is called using a
syntax such as Math.sqrt(2), with the class name Math as the qualifier before the
dot operator.
Static methods can be useful for providing utility behaviors related to a class
that need not rely on the state of any particular instance of that class.
1.2. Classes and Objects 11
The abstract Modifier
A method of a class may be declared as abstract, in which case its signature is pro-
vided but without an implementation of the method body. Abstract methods are an
advanced feature of object-oriented programming to be combined with inheritance,
and the focus of Section 2.3.3. In short, any subclass of a class with abstract meth-
ods is expected to provide a concrete implementation for each abstract method.
A class with one or more abstract methods must also be formally declared as
abstract, because it is essentially incomplete. (It is also permissible to declare
a class as abstract even if it does not contain any abstract methods.) As a result,
Java will not allow any instances of an abstract class to be constructed, although
reference variables may be declared with an abstract type.

The final Modifier


A variable that is declared with the final modifier can be initialized as part of that
declaration, but can never again be assigned a new value. If it is a base type, then
it is a constant. If a reference variable is final, then it will always refer to the same
object (even if that object changes its internal state). If a member variable of a class
is declared as final, it will typically be declared as static as well, because it would
be unnecessarily wasteful to have every instance store the identical value when that
value can be shared by the entire class.
Designating a method or an entire class as final has a completely different
consequence, only relevant in the context of inheritance. A final method cannot be
overridden by a subclass, and a final class cannot even be subclassed.

Declaring Instance Variables


When defining a class, we can declare any number of instance variables. An impor-
tant principle of object-orientation is that each instance of a class maintains its own
individual set of instance variables (that is, in fact, why they are called instance
variables). So in the case of the Counter class, each instance will store its own
(independent) value of count.
The general syntax for declaring one or more instance variables of a class is as
follows (with optional portions bracketed):
[modifiers] type identifier1 [=initialValue1 ], identifier2 [=initialValue2 ];
In the case of the Counter class, we declared
private int count;
where private is the modifier, int is the type, and count is the identifier. Because
we did not declare an initial value, it automatically receives the default of zero as a
base-type integer.
12 Chapter 1. Java Primer

Declaring Methods
A method definition has two parts: the signature, which defines the name and
parameters for a method, and the body, which defines what the method does. The
method signature specifies how the method is called, and the method body specifies
what the object will do when it is called. The syntax for defining a method is as
follows:
[modifiers] returnType methodName(type1 param1 , . . . , typen paramn ) {
// method body . . .
}
Each of the pieces of this declaration has an important purpose. We have al-
ready discussed the significance of modifiers such as public, private, and static.
The returnType designation defines the type of value returned by the method. The
methodName can be any valid Java identifier. The list of parameters and their types
declares the local variables that correspond to the values that are to be passed as
arguments to this method. Each type declaration typei can be any Java type name
and each parami can be any distinct Java identifier. This list of parameters and
their types can be empty, which signifies that there are no values to be passed to
this method when it is invoked. These parameter variables, as well as the instance
variables of the class, can be used inside the body of the method. Likewise, other
methods of this class can be called from inside the body of a method.
When a (nonstatic) method of a class is called, it is invoked on a specific in-
stance of that class and can change the state of that object. For example, the follow-
ing method of the Counter class increases the counter’s value by the given amount.
public void increment(int delta) {
count += delta;
}
Notice that the body of this method uses count, which is an instance variable, and
delta, which is a parameter.

Return Types
A method definition must specify the type of value the method will return. If the
method does not return a value (as with the increment method of the Counter class),
then the keyword void must be used. To return a value in Java, the body of the
method must use the return keyword, followed by a value of the appropriate return
type. Here is an example of a method (from the Counter class) with a nonvoid
return type:
public int getCount( ) {
return count;
}
1.2. Classes and Objects 13
Java methods can return only one value. To return multiple values in Java, we
should instead combine all the values we want to return in a compound object,
whose instance variables include all the values we want to return, and then return a
reference to that compound object. In addition, we can change the internal state of
an object that is passed to a method as another way of “returning” multiple results.

Parameters

A method’s parameters are defined in a comma-separated list enclosed in parenthe-


ses after the name of the method. A parameter consists of two parts, the parameter
type and the parameter name. If a method has no parameters, then only an empty
pair of parentheses is used.
All parameters in Java are passed by value, that is, any time we pass a parameter
to a method, a copy of that parameter is made for use within the method body. So
if we pass an int variable to a method, then that variable’s integer value is copied.
The method can change the copy but not the original. If we pass an object reference
as a parameter to a method, then the reference is copied as well. Remember that we
can have many different variables that all refer to the same object. Reassigning the
internal reference variable inside a method will not change the reference that was
passed in.
For the sake of demonstration, we will assume that the following two methods
were added to an arbitrary class (such as CounterDemo).
public static void badReset(Counter c) {
c = new Counter( ); // reassigns local name c to a new counter
}

public static void goodReset(Counter c) {


c.reset( ); // resets the counter sent by the caller
}
Now we will assume that variable strikes refers to an existing Counter instance in
some context, and that it currently has a value of 3.
If we were to call badReset(strikes), this has no effect on the Counter known as
strikes. The body of the badReset method reassigns the (local) parameter variable c
to reference a newly created Counter instance; but this does not change the state of
the existing counter that was sent by the caller (i.e., strikes).
In contrast, if we were to call goodReset(strikes), this does indeed reset the
caller’s counter back to a value of zero. That is because the variables c and strikes
are both reference variables that refer to the same Counter instance. So when
c.reset( ) is called, that is effectively the same as if strikes.reset( ) were called.
14 Chapter 1. Java Primer

Defining Constructors
A constructor is a special kind of method that is used to initialize a newly created
instance of the class so that it will be in a consistent and stable initial state. This
is typically achieved by initializing each instance variable of the object (unless
the default value will suffice), although a constructor can perform more complex
computation. The general syntax for declaring a constructor in Java is as follows:
modifiers name(type0 parameter0 , . . . , typen−1 parametern−1 ) {
// constructor body . . .
}
Constructors are defined in a very similar way as other methods of a class, but there
are a few important distinctions:
1. Constructors cannot be static, abstract, or final, so the only modifiers that
are allowed are those that affect visibility (i.e., public, protected, private,
or the default package-level visibility).
2. The name of the constructor must be identical to the name of the class it
constructs. For example, when defining the Counter class, a constructor must
be named Counter as well.
3. We don’t specify a return type for a constructor (not even void). Nor does
the body of a constructor explicitly return anything. When a user of a class
creates an instance using a syntax such as
Counter d = new Counter(5);
the new operator is responsible for returning a reference to the new instance
to the caller; the responsibility of the constructor method is only to initialize
the state of the new instance.
A class can have many constructors, but each must have a different signature,
that is, each must be distinguished by the type and number of the parameters it
takes. If no constructors are explicitly defined, Java provides an implicit default
constructor for the class, having zero arguments and leaving all instance variables
initialized to their default values. However, if a class defines one or more nondefault
constructors, no default constructor will be provided.
As an example, our Counter class defines the following pair of constructors:
public Counter( ) { }
public Counter(int initial) { count = initial; }
The first of these has a trivial body, { }, as the goal for this default constructor is to
create a counter with value zero, and that is already the default value of the integer
instance variable, count. However, it is still important that we declared such an
explicit constructor, because otherwise none would have been provided, given the
existence of the nondefault constructor. In that scenario, a user would have been
unable to use the syntax, new Counter( ).
1.2. Classes and Objects 15

The Keyword this


Within the body of a (nonstatic) method in Java, the keyword this is automatically
defined as a reference to the instance upon which the method was invoked. That
is, if a caller uses a syntax such as thing.foo(a, b, c), then within the body of
method foo for that call, the keyword this refers to the object known as thing in
the caller’s context. There are three common reasons why this reference is needed
from within a method body:

1. To store the reference in a variable, or send it as a parameter to another


method that expects an instance of that type as an argument.

2. To differentiate between an instance variable and a local variable with the


same name. If a local variable is declared in a method having the same
name as an instance variable for the class, that name will refer to the local
variable within that method body. (We say that the local variable masks the
instance variable.) In this case, the instance variable can still be accessed
by explicitly using the dot notation with this as the qualifier. For example,
some programmers prefer to use the following style for a constructor, with a
parameter having the same name as the underlying variable.
public Counter(int count) {
this.count = count; // set the instance variable equal to parameter
}

3. To allow one constructor body to invoke another constructor body. When one
method of a class invokes another method of that same class on the current
instance, that is typically done by using the (unqualified) name of the other
method. But the syntax for calling a constructor is special. Java allows use of
the keyword this to be used as a method within the body of one constructor,
so as to invoke another constructor with a different signature.
This is often useful because all of the initialization steps of one constructor
can be reused with appropriate parameterization. As a trivial demonstra-
tion of the syntax, we could reimplement the zero-argument version of our
Counter constructor to have it invoke the one-argument version sending 0 as
an explicit parameter. This would be written as follows:
public Counter( ) {
this(0); // invoke one-parameter constructor with value zero
}
We will provide a more meaningful demonstration of this technique in a later
example of a CreditCard class in Section 1.7.
16 Chapter 1. Java Primer

The main Method


Some Java classes, such as our Counter class, are meant to be used by other classes,
but are not intended to serve as a self-standing program. The primary control for an
application in Java must begin in some class with the execution of a special method
named main. This method must be declared as follows:
public static void main(String[ ] args) {
// main method body...
}
The args parameter is an array of String objects, that is, a collection of indexed
strings, with the first string being args[0], the second being args[1], and so on. (We
say more about strings and arrays in Section 1.3.) Those represent what are known
as command-line arguments that are given by a user when the program is executed.
Java programs can be called from the command line using the java command
(in a Windows, Linux, or Unix shell), followed by the name of the Java class whose
main method we want to run, plus any optional arguments. For example, to exe-
cute the main method of a class named Aquarium, we could issue the following
command:
java Aquarium
In this case, the Java runtime system looks for a compiled version of the Aquarium
class, and then invokes the special main method in that class.
If we had defined the Aquarium program to take an optional argument that
specifies the number of fish in the aquarium, then we might invoke the program by
typing the following in a shell window:
java Aquarium 45
to specify that we want an aquarium with 45 fish in it. In this case, args[0] would
refer to the string "45". It would be up to the body of the main method to interpret
that string as the desired number of fish.
Programmers who use an integrated development environment (IDE), such as
Eclipse, can optionally specify command-line arguments when executing the pro-
gram through the IDE.

Unit Testing
When defining a class, such as Counter, that is meant to be used by other classes
rather than as a self-standing program, there is no need to define a main method.
However, a nice feature of Java’s design is that we could provide such a method
as a way to test the functionality of that class in isolation, knowing that it would
not be run unless we specifically invoke the java command on that isolated class.
However, for more robust testing, frameworks such as JUnit are preferred.
1.3. Strings, Wrappers, Arrays, and Enum Types 17

1.3 Strings, Wrappers, Arrays, and Enum Types

The String Class


Java’s char base type stores a value that represents a single text character. In Java,
the set of all possible characters, known as an alphabet, is the Unicode international
character set, a 16-bit character encoding that covers most used written languages.
(Some programming languages use the smaller ASCII character set, which is a
proper subset of the Unicode alphabet based on a 7-bit encoding.) The form for
expressing a character literal in Java is using single quotes, such as 'G'.
Because it is common to work with sequences of text characters in programs
(e.g., for user interactions or data processing), Java provides support in the form
of a String class. A string instance represents a sequence of zero or more charac-
ters. The class provides extensive support for various text-processing tasks, and in
Chapter 13 we will examine several of the underlying algorithms for text process-
ing. For now, we will only highlight the most central aspects of the String class.
Java uses double quotes to designate string literals. Therefore, we might declare
and initialize a String instance as follows:
String title = "Data Structures & Algorithms in Java"

Character Indexing
Each character c within a string s can be referenced by using an index, which is
equal to the number of characters that come before c in s. By this convention, the
first character is at index 0, and the last is at index n − 1, where n is the length of the
string. For example, the string title, defined above, has length 36. The character at
index 2 is 't' (the third character), and the character at index 4 is ' ' (the space
character). Java’s String class supports a method length( ), which returns the length
of a string instance, and a method charAt(k), which returns the character at index k.

Concatenation
The primary operation for combining strings is called concatenation, which takes
a string P and a string Q combines them into a new string, denoted P + Q, which
consists of all the characters of P followed by all the characters of Q. In Java, the
“+” operation performs concatenation when acting on two strings, as follows:
String term = "over" + "load";
This statement defines a variable named term that references a string with value
"overload". (We will discuss assignment statements and expressions such as that
above in more detail later in this chapter.)
18 Chapter 1. Java Primer

The StringBuilder Class


An important trait of Java’s String class is that its instances are immutable; once
an instance is created and initialized, the value of that instance cannot be changed.
This is an intentional design, as it allows for great efficiencies and optimizations
within the Java Virtual Machine.
However, because String is a class in Java, it is a reference type. Therefore,
variables of type String can be reassigned to another string instance (even if the
current string instance cannot be changed), as in the following:
String greeting = "Hello";
greeting = "Ciao"; // we changed our mind
It is also quite common in Java to use string concatenation to build a new string that
is subsequently used to replace one of the operands of concatenation, as in:
greeting = greeting + '!'; // now it is ”Ciao!”
However, it is important to remember that this operation does create a new string
instance, copying all the characters of the existing string in the process. For long
string (such as DNA sequences), this can be very time consuming. (In fact, we will
experiment with the efficiency of string concatenation to begin Chapter 4.)
In order to support more efficient editing of character strings, Java provides
a StringBuilder class, which is effectively a mutable version of a string. This
class combines some of the accessor methods of the String class, while supporting
additional methods including the following (and more):

setCharAt(k, c): Change the character at index k to character c.

insert(k, s): Insert a copy of string s starting at index k of the sequence,


shifting existing characters further back to make room.

append(s): Append string s to the end of the sequence.

reverse(): Reverse the current sequence.


toString(): Return a traditional String instance based on the current
character sequence.

An error condition occurs, for both String and StringBuilder classes, if an index k
is out of the bounds of the indices of the character sequence.
The StringBuilder class can be very useful, and it serves as an interesting case
study for data structures and algorithms. We will further explore the empirical ef-
ficiency of the StringBuilder class in Section 4.1 and the theoretical underpinnings
of its implementation in Section 7.2.4.
1.3. Strings, Wrappers, Arrays, and Enum Types 19

Wrapper Types
There are many data structures and algorithms in Java’s libraries that are specif-
ically designed so that they only work with object types (not primitives). To get
around this obstacle, Java defines a wrapper class for each base type. An instance
of each wrapper type stores a single value of the corresponding base type. In Ta-
ble 1.2, we show the base types and their corresponding wrapper class, along with
examples of how objects are created and accessed.

Base Type Class Name Creation Example Access Example


boolean Boolean obj = new Boolean(true); obj.booleanValue()
char Character obj = new Character(’Z’); obj.charValue()
byte Byte obj = new Byte((byte) 34); obj.byteValue()
short Short obj = new Short((short) 100); obj.shortValue()
int Integer obj = new Integer(1045); obj.intValue()
long Long obj = new Long(10849L); obj.longValue()
float Float obj = new Float(3.934F); obj.floatValue()
double Double obj = new Double(3.934); obj.doubleValue()

Table 1.2: Java’s wrapper classes. Each class is given with its corresponding base
type and example expressions for creating and accessing such objects. For each
row, we assume the variable obj is declared with the corresponding class name.

Automatic Boxing and Unboxing


Java provides additional support for implicitly converting between base types and
their wrapper types through a process known as automatic boxing and unboxing.
In any context for which an Integer is expected (for example, as a parameter),
an int value k can be expressed, in which case Java automatically boxes the int,
with an implicit call to new Integer(k). In reverse, in any context for which an
int is expected, an Integer value v can be given in which case Java automatically
unboxes it with an implicit call to v.intValue( ). Similar conversions are made with
the other base-type wrappers. Finally, all of the wrapper types provide support for
converting back and forth between string literals. Code Fragment 1.4 demonstrates
many such features.

1 int j = 8;
2 Integer a = new Integer(12);
3 int k = a; // implicit call to a.intValue()
4 int m = j + a; // a is automatically unboxed before the addition
5 a = 3 ∗ m; // result is automatically boxed before assignment
6 Integer b = new Integer("-135"); // constructor accepts a String
7 int n = Integer.parseInt("2013"); // using static method of Integer class
Code Fragment 1.4: A demonstration of the use of the Integer wrapper class.
20 Chapter 1. Java Primer

Arrays
A common programming task is to keep track of an ordered sequence of related
values or objects. For example, we may want a video game to keep track of the top
ten scores for that game. Rather than using ten different variables for this task, we
would prefer to use a single name for the group and use index numbers to refer to
the high scores in that group. Similarly, we may want a medical information system
to keep track of the patients currently assigned to beds in a certain hospital. Again,
we would rather not have to introduce 200 variables in our program just because
the hospital has 200 beds.
In such cases, we can save programming effort by using an array, which is a
sequenced collection of variables all of the same type. Each variable, or cell, in an
array has an index, which uniquely refers to the value stored in that cell. The cells
of an array a are numbered 0, 1, 2, and so on. We illustrate an array of high scores
for a video game in Figure 1.3.
High
scores

indices

Figure 1.3: An illustration of an array of ten (int) high scores for a video game.

Array Elements and Capacities


Each value stored in an array is called an element of that array. Since the length of
an array determines the maximum number of things that can be stored in the array,
we will sometimes refer to the length of an array as its capacity. In Java, the length
of an array named a can be accessed using the syntax a.length. Thus, the cells of
an array a are numbered 0, 1, 2, and so on, up through a.length−1, and the cell
with index k can be accessed with syntax a[k].

Out of Bounds Errors


It is a dangerous mistake to attempt to index into an array a using a number outside
the range from 0 to a.length−1. Such a reference is said to be out of bounds.
Out of bounds references have been exploited numerous times by hackers using a
method called the buffer overflow attack to compromise the security of computer
systems written in languages other than Java. As a safety feature, array indices are
always checked in Java to see if they are ever out of bounds. If an array index is
out of bounds, the runtime Java environment signals an error condition. The name
of this condition is the ArrayIndexOutOfBoundsException. This check helps Java
avoid a number of security problems, such as buffer overflow attacks.
1.3. Strings, Wrappers, Arrays, and Enum Types 21
Declaring and Constructing Arrays

Arrays in Java are somewhat unusual, in that they are not technically a base type
nor are they instances of a particular class. With that said, an instance of an array is
treated as an object by Java, and variables of an array type are reference variables.
To declare a variable (or parameter) to have an array type, we use an empty
pair of square brackets just after the type of element that the array will store. For
example, we might declare:
int[ ] primes;
Because arrays are a reference type, this declares the variable primes to be a refer-
ence to an array of integer values, but it does not immediately construct any such
array. There are two ways for creating an array.
The first way to create an array is to use an assignment to a literal form when
initially declaring the array, using a syntax as:
elementType[ ] arrayName = {initialValue0 , initialValue1 , . . . , initialValue N−1 };
The elementType can be any Java base type or class name, and arrayName can be
any valid Java identifier. The initial values must be of the same type as the array.
For example, we could initialize the array of primes to contain the first ten prime
numbers as:
int[ ] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
When using an initializer, an array is created having precisely the capacity needed
to store the indicated values.
The second way to create an array is to use the new operator. However, because
an array is not an instance of a class, we do not use a typical constructor syntax.
Instead we use the syntax:
new elementType[length]
where length is a positive integer denoting the length of the new array. The new
operator returns a reference to the new array, and typically this would be assigned to
an array variable. For example, the following statement declares an array variable
named measurements, and immediately assigns it a new array of 1000 cells.
double[ ] measurements = new double[1000];
When arrays are created using the new operator, all of their elements are au-
tomatically assigned the default value for the element type. That is, if the element
type is numeric, all cells of the array are initialized to zero, if the element type is
boolean, all cells are false, and if the element type is a reference type (such as with
an array of String instances), all cells are initialized to null.
22 Chapter 1. Java Primer

Enum Types
In olden times, programmers would often define a series of constant integer values
to be used for representing a finite set of choices. For example, in representing a
day of the week, they might declare variable today as an int and then set it with
value 0 for Monday, 1 for Tuesday, and so on.
A slightly better programming style is to define static constants (with the final
keyword), to make the associations, such as:
static final int MON = 0;
static final int TUE = 1;
static final int WED = 2;
...
because then it becomes possible to make assignments such as today = TUE,
rather than the more obscure today = 1. Unfortunately, the variable today is still
declared as an int using such a programming style, and it may not be clear that you
intend for it to represent a day of the week when storing it as an instance variable
or sending it as a parameter.
Java supports a more elegant approach to representing choices from a finite
set by defining what is known as an enumerated type, or enum for short. These
are types that are only allowed to take on values that come from a specified set of
names. They are declared as follows:

modifier enum name { valueName0 , valueName1 , . . . , valueNamen−1 };

where the modifier can be blank, public, protected, or private. The name of
this enum, name, can be any legal Java identifier. Each of the value identifiers,
valueNamei , is the name of a possible value that variables of this enum type can
take on. Each of these name values can also be any legal Java identifier, but the
Java convention is that these should usually be capitalized words. For example, an
enumerated type definition for days of the weak might appear as:

public enum Day { MON, TUE, WED, THU, FRI, SAT, SUN };

Once defined, Day becomes an official type and we may declare variables or pa-
rameters with type Day. A variable of that type can be declared as:
Day today;
and an assignment of a value to that variable can appear as:
today = Day.TUE;
1.4. Expressions 23

1.4 Expressions
Variables and constants are used in expressions to define new values and to modify
variables. In this section, we discuss how expressions work in Java in more detail.
Expressions involve the use of literals, variables, and operators. Since we have al-
ready discussed variables, let us briefly focus on literals and then discuss operators
in some detail.

1.4.1 Literals
A literal is any “constant” value that can be used in an assignment or other expres-
sion. Java allows the following kinds of literals:

• The null object reference (this is the only object literal, and it is allowed to
be any reference type).
• Boolean: true and false.
• Integer: The default for an integer like 176, or -52 is that it is of type int,
which is a 32-bit integer. A long integer literal must end with an “L” or “l”,
for example, 176L or -52l, and defines a 64-bit integer.
• Floating Point: The default for floating-point numbers, such as 3.1415 and
135.23, is that they are double. To specify that a literal is a float, it must
end with an “F” or “f”. Floating-point literals in exponential notation are also
allowed, such as 3.14E2 or .19e10; the base is assumed to be 10.
• Character: In Java, character constants are assumed to be taken from the
Unicode alphabet. Typically, a character is defined as an individual symbol
enclosed in single quotes. For example, ’a’ and ’?’ are character constants.
In addition, Java defines the following special character constants:

'\n' (newline) '\t' (tab)


'\b' (backspace) '\r' (return)
'\f' (form feed) '\\' (backslash)
'\'' (single quote) '\"' (double quote).

• String Literal: A string literal is a sequence of characters enclosed in double


quotes, for example, the following is a string literal:

"dogs cannot climb trees"


24 Chapter 1. Java Primer

1.4.2 Operators
Java expressions involve composing literals and variables with operators. We will
survey the operators in Java in this section.

Arithmetic Operators
The following are binary arithmetic operators in Java:
+ addition
− subtraction
∗ multiplication
/ division
% the modulo operator
This last operator, modulo, is also known as the “remainder” operator, because
it is the remainder left after an integer division. We often use “ mod ” to denote the
modulo operator, and we define it formally as

n mod m = r,

such that
n = mq + r,
for an integer q and 0 ≤ r < m.
Java also provides a unary minus (−), which can be placed in front of an arith-
metic expression to invert its sign. Parentheses can be used in any expression to
define the order of evaluation. Java also uses a fairly intuitive operator precedence
rule to determine the order of evaluation when parentheses are not used. Unlike
C++, Java does not allow operator overloading for class types.

String Concatenation
With strings, the (+) operator performs concatenation, so that the code
String rug = "carpet";
String dog = "spot";
String mess = rug + dog;
String answer = mess + " will cost me " + 5 + " hours!";
would have the effect of making answer refer to the string
"carpetspot will cost me 5 hours!"
This example also shows how Java converts nonstring values (such as 5) into strings,
when they are involved in a string concatenation operation.
1.4. Expressions 25
Increment and Decrement Operators
Like C and C++, Java provides increment and decrement operators. Specifically, it
provides the plus-one increment (++) and decrement (−−) operators. If such an
operator is used in front of a variable reference, then 1 is added to (or subtracted
from) the variable and its value is read into the expression. If it is used after a
variable reference, then the value is first read and then the variable is incremented
or decremented by 1. So, for example, the code fragment
int i = 8;
int j = i++; // j becomes 8 and then i becomes 9
int k = ++i; // i becomes 10 and then k becomes 10
int m = i−−; // m becomes 10 and then i becomes 9
int n = 9 + −−i; // i becomes 8 and then n becomes 17
assigns 8 to j, 10 to k, 10 to m, 17 to n, and returns i to value 8, as noted.

Logical Operators
Java supports the standard comparisons operators between numbers:
< less than
<= less than or equal to
== equal to
!= not equal to
>= greater than or equal to
> greater than
The type of the result of any of these comparison is a boolean. Comparisons may
also be performed on char values, with inequalities determined according to the
underlying character codes.
For reference types, it is important to know that the operators == and != are
defined so that expression a == b is true if a and b both refer to the identical
object (or are both null). Most object types support an equals method, such that
a.equals(b) is true if a and b refer to what are deemed as “equivalent” instances for
that class (even if not the same instance); see Section 3.5 for further discussion.
Operators defined for boolean values are the following:
! not (prefix)
&& conditional and
|| conditional or
The boolean operators && and | | will not evaluate the second operand (to the right)
in their expression if it is not needed to determine the value of the expression. This
“short circuiting” feature is useful for constructing boolean expressions where we
first test that a certain condition holds (such as an array index being valid) and then
test a condition that could have otherwise generated an error condition had the prior
test not succeeded.
26 Chapter 1. Java Primer
Bitwise Operators
Java also provides the following bitwise operators for integers and booleans:
∼ bitwise complement (prefix unary operator)
& bitwise and
| bitwise or
ˆ bitwise exclusive-or
<< shift bits left, filling in with zeros
>> shift bits right, filling in with sign bit
>>> shift bits right, filling in with zeros

The Assignment Operator


The standard assignment operator in Java is “=”. It is used to assign a value to an
instance variable or local variable. Its syntax is as follows:

variable = expression

where variable refers to a variable that is allowed to be referenced by the statement


block containing this expression. The value of an assignment operation is the value
of the expression that was assigned. Thus, if j and k are both declared as type int,
it is correct to have an assignment statement like the following:
j = k = 25; // works because ’=’ operators are evaluated right-to-left

Compound Assignment Operators


Besides the standard assignment operator (=), Java also provides a number of other
assignment operators that combine a binary operation with an assignment. These
other kinds of operators are of the following form:

variable op= expression

where op is any binary operator. The above expression is generally equivalent to

variable = variable op expression

so that x ∗= 2 is equivalent to x = x ∗ 2. However, if variable contains an expres-


sion (for example, an array index), the expression is evaluated only once. Thus, the
code fragment
a[5] = 10;
j = 5;
a[j++] += 2; // not the same as a[j++] = a[j++] + 2
leaves a[5] with value 12 and j with value 6.
1.4. Expressions 27
Operator Precedence

Operators in Java are given preferences, or precedence, that determine the order in
which operations are performed when the absence of parentheses brings up eval-
uation ambiguities. For example, we need a way of deciding if the expression,
“5+2*3,” has value 21 or 11 (Java says it is 11). We show the precedence of the
operators in Java (which, incidentally, is the same as in C and C++) in Table 1.3.

Operator Precedence
Type Symbols
1 array index []
method call ()
dot operator .
2 postfix ops exp++ exp−−
prefix ops ++exp −−exp +exp −exp ˜exp !exp
cast (type) exp
3 mult./div. ∗ / %
4 add./subt. + −
5 shift << >> >>>
6 comparison < <= > >= instanceof
7 equality == !=
8 bitwise-and &
9 bitwise-xor ˆ
10 bitwise-or |
11 and &&
12 or ||
13 conditional booleanExpression ? valueIfTrue : valueIfFalse
14 assignment = += −= ∗= /= %= <<= >>= >>>= &= ˆ= |=

Table 1.3: The Java precedence rules. Operators in Java are evaluated according to
the ordering above if parentheses are not used to determine the order of evaluation.
Operators on the same line are evaluated in left-to-right order (except for assign-
ment and prefix operations, which are evaluated in right-to-left order), subject to
the conditional evaluation rule for boolean && and | | operations. The operations
are listed from highest to lowest precedence (we use exp to denote an atomic or
parenthesized expression). Without parenthesization, higher precedence operators
are performed before lower precedence operators.

We have now discussed almost all of the operators listed in Table 1.3. A notable
exception is the conditional operator, which involves evaluating a boolean expres-
sion and then taking on the appropriate value depending on whether this boolean
expression is true or false. (We discuss the use of the instanceof operator in the
next chapter.)
Other documents randomly have
different content
130.
Guide, III., chap. li.

131.
See R. Shem-Tob’s Commentary on the Guide, loc. cit.

132.
Ibid.

133.
Maimonides himself describes the contemporary state of
culture among his people in several places. See, for instance,
the Treatise on Resurrection.

134.
Emunoth v’ Deoth, Preface.

135.
R. Jehudah Halevi, despite his profound knowledge of
contemporary philosophy, says categorically: “He who accepts
this [the Law] completely, without scrutiny or argument, is
better off than he who investigates and analyses” (Cuzri, II.,
xxvi. [Dr. Hirschfeld’s translation]).

136.
Guide, I., chap. lxxi.

137. As to the state of mind of the forced converts at that time see
what Maimonides says in the Treatise of the Sanctification of
the Name and the Iggereth Teman.

138.
See Section II. above. Note especially what Maimonides says
about prophecy in the Introduction to his Commentary on the
Mishnah (written at the time when he lived among the forced
converts). Some of this is quoted in Section II. He writes there
with such incisive force as to make it clear that he has left the
realm of pure speculation and theory, and has a practical
object connected with actual circumstances which had stirred
him deeply at the time.

139.
All this is clearly hinted in Maimonides’ Treatise of the
Sanctification of the Name.

140.
Guide, III., chap. xxvii.

141.
We find all the principles of his system in the Introduction to
his first book (the Commentary on the Mishnah), and again at
the end of his last book (Guide, III., chap. li.).

142.
See Introduction to Commentary on the Mishnah.

143.
“This is not the place to treat of this matter; but it is my
intention, wherever a matter of belief is mentioned, to explain
it briefly. For I love to teach nothing so much as one of the
principles of religion” (end of Berachoth).

144.
Especially important in this connection are the Introductions to
Zera’im, to chapter Chelek (where he brings in all the principles
of religion), and to Aboth (Eight Chapters).

145.
His Preface makes it clear that he regarded his book as a sort
of Mishnah in a new form; and it seems (though he does not
say it in so many words) that he intended to hint at this idea
by the title of the book—Mishneh Torah.
146.
There were many writers who suspected that Maimonides’ idea
was to do away altogether with the study of the Talmud. But
this suspicion could arise only from failure to understand
clearly the real purpose of the book. Even theories are
presented here in dogmatic form; but could it possibly be
imagined that Maimonides wanted to do away with the study
of philosophy by the long method of argument and proof—that
study which he regarded as the purpose of the human race?
The truth is that he had in view the social function of religion,
and for this reason he set forth both theories and practical
commands in brief and in a manner suited to the
comprehension of ordinary men. He left it to the chosen few to
study the principles of both the theoretical and the practical
law, and to obtain from the original sources a knowledge of the
reasons for both.

147. Guide, Introduction.

148.
After the publication of the Guide many people discovered that
its opinions were already contained in the innocent-looking
dicta of the Mishneh Torah, especially in its first part (The Book
of Science), and from that time onward they regarded that
book also as heretical, and waged war on it as well as on the
Guide.

149.
See the letter of R. Jehudah Alfachar to Kimchi: Collected
Responses of Maimonides (ed. Leipsic), Part III., p. 1, et seq.

150.
See Dr. Joel’s monograph, Spinoza’s Theologisch-Politischer
Traktat auf seine Quellen geprüft, Breslau, 1870.
151.
See Kerem Chemed, III., pp. 67-70.

152.
I may remark in passing that Luzzatto (ibid.) accuses
Maimonides of yet another disservice to Judaism. By making
opinions the essential element of perfection Maimonides,
according to him, abolished the difference between the
righteous man and the wicked. “The philosopher,” he says,
“may commit theft, murder, and adultery, and yet attain eternal
life: salvation does not depend on merit.” This charge was
already brought against Maimonides by his medieval
opponents, but it is quite mistaken. Maimonides insists, over
and over again, that until a man has moral perfection it is
impossible for him to reach intellectual perfection to the degree
necessary for the attainment of acquired intellect. See, for
instance, the passage from the introduction to Zera’im quoted
above (p. 174).

153.
Though the conception of “nationalism” in its current sense is
modern, the national sentiment itself has existed in our people
at all times; and its existence and value have been realised in
our literature in every period, from the Bible and the Talmud to
the literature of Chassidism, though it used to be called by
other names (“the love of Israel,” etc.). But the sentiment and
its expression do not appear to the same extent or in the same
form in all ages and in all individuals, and it is therefore
legitimate to ask what was the attitude of any particular age or
any particular thinker to the national sentiment. An interesting
book might be written on the history of the national sentiment
and consciousness in Israel, dealing with their different
manifestations in different ages, their growth and decline, and
their expression in the life of the nation and the thought of its
great men in each period.
154.
Guide, III., chap. xliii. Similarly in chap. xlviii.

155.
End of Mishneh Torah.

156.
See the Iggereth Teman and the Treatise of the Sanctification
of the Name.

157. A German Jewish scholar, Dr. D. Rosin, in his monograph on


the ethics of Maimonides (Die Ethik des Maimonides, Breslau,
1876), finds under the heading of “Nationalism” (p. 148) only
two laws in the whole Mishneh Torah which allude to the duties
of the Jew to his people. But in fact the two laws which he
quotes (Hilchoth T’shubah, chap. iii. 11, and Hilchoth Matnath
’Aniim, chap. x. 2) emphasise rather the unity of the members
of one faith.

158.
Introduction to chapter Chelek.

159.
See Albo, Ikkarim, Part I, chap. 1.

160.
See his Introduction to the Sepher Hammitzvoth.

161.
I remarked on this point years ago in “Past and Future.” [See
Selected Essays by Ahad Ha’am, p. 87.]

162.
Cf. supra, p. 10.

163.
See the Treatise on Resurrection.
164.
Luzzatto (ubi supra) seems to suspect that Maimonides’ whole
treatment of resurrection was insincere, and that he was
deliberately throwing dust in the reader’s eyes, in order to
conceal his heresy. But this suspicion is absurd: Maimonides
was a man who was not afraid openly to reject even the
immortality of the soul, and to recast all the fundamental
beliefs of Judaism. Any unbiassed reader of the treatise must
realise that Maimonides defends resurrection with perfect
sincerity, but that he is unable to find the real grounds of his
own conviction, because he looks for them in his reason and
not in his feelings.

165.
Commentary on the Mishnah, Aboth, chap. i. 17.

166.
See his letters to Joseph ben Gabar, to the community of
Lunel, and to R. Samuel Ibn Tibbon (Collected Responses of
Maimonides (Leipsic), Part II., pp. 16, 27, 44).

167. Jewish Quarterly Review, January, 1897, p. 187.

168.
Notes of this kind are found right through the book (see e.g.
pp. 498-503, 691-3, and many other places); and it is unfair of
some Jewish critics to have passed over this fact in silence,
and to have described the book as though it were throughout
simply an attack on Judaism.

169.
Introduction, pp. xvii. xviii. ci.

170.
[The story is that a heathen made this demand of Hillel, whose
reply was: “What is hateful to thyself do not unto thy
neighbour—that is the whole Torah, and the rest is
commentary: go thou and fulfil it.”]

171.
Das Judentum und seine Geschichte (2nd edition), p. 26.

172.
John Stuart Mill writes: “In justice to the great Hebrew
lawgiver, it should always be remembered that the precept to
love thy neighbour as thyself already existed in the
Pentateuch; and very surprising it is to find it there” (Three
Essays on Religion, 2nd edition, p. 98). Had Mill understood
the precept in its original sense, he would certainly not have
been surprised to find it in the Mosaic Law. But even so logical
a thinker could not free himself from the influences of his
education and his environment, and he did not see that a
meaning had been read into this verse which was opposed to
its literal sense.

173.
The Russian philosopher Vladimir Solovioff was the first, if I am
not mistaken, to attempt to find a moral basis for international
relations in the precept “Thou shalt love thy neighbour as
thyself,” taken in the sense mentioned above. This philosopher
was an untiring student of Judaism, for which he had an
appreciation unusual among Christians—a fact not without its
significance.

174.
Mr. Montefiore, indeed, does not admit this. In his opinion the
morality of Jewish family life is a fact not because of the laws,
but in spite of them. If you ask how such a thing is possible,
he replies somewhat as follows: It has already been remarked
that Judaism does not obey the laws of cause and effect, and
we sometimes see a certain tendency in Jewish life which
ought logically to have certain effects, but has in practice just
the opposite results (p. 335). Truly an easy and comfortable
“philosophy of history”!

175.
Even Matthew, who permits divorce on the ground of
unfaithfulness, makes this exception (as some Christian
commentators have pointed out) only because the sanctity of
the marriage is profaned by the sin, and the divine union is
annulled of itself. The point of view is essentially the same in
both versions.

176.
In England the question has become so acute that the
Government has appointed a Commission to find means of
making divorce easier. Men of knowledge and experience, in
evidence before the Commission, have expressed the opinion
that the restriction of the possibility of divorce has very evil
results.

177. In England the law to-day is still in the spirit of Matthew; the
wife’s unfaithfulness is sufficient ground of divorce for the
husband, but the reverse does not hold good.

178.
[Divine Presence. See p. 97.]
Transcriber’s Notes:
Footnotes have been collected at the end of the text, and are
linked for ease of reference.
*** END OF THE PROJECT GUTENBERG EBOOK TEN ESSAYS ON
ZIONISM AND JUDAISM ***

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 ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

ebookultra.com

You might also like