Search for notes by fellow students, in your own course and all over the country.
Browse our notes for titles which look like what you need, you can preview any of the notes via a sample of the contents. After you're happy these are the notes you're after simply pop them into your shopping cart.
Title: Think Java
Description: Currently used at many colleges, universities, and high schools, this hands-on introduction to computer science is ideal for people with little or no programming experience. The goal of this concise book is not just to teach you Java, but to help you think like a computer scientist. You'll learn how to program - a useful skill by itself—but you'll also discover how to use programming as a means to an end. Authors Allen Downey and Chris Mayfield start with the most basic concepts and gradually move into topics that are more complex, such as recursion and object-oriented programming. Each brief chapter covers the material for one week of a college course and includes exercises to help you practice what you've learned.
Description: Currently used at many colleges, universities, and high schools, this hands-on introduction to computer science is ideal for people with little or no programming experience. The goal of this concise book is not just to teach you Java, but to help you think like a computer scientist. You'll learn how to program - a useful skill by itself—but you'll also discover how to use programming as a means to an end. Authors Allen Downey and Chris Mayfield start with the most basic concepts and gradually move into topics that are more complex, such as recursion and object-oriented programming. Each brief chapter covers the material for one week of a college course and includes exercises to help you practice what you've learned.
Document Preview
Extracts from the notes are below, to see the PDF you'll receive please use the links above
Think
Java
HOW TO THINK LIKE A COMPUTER SCIENTIST
Allen B
...
it-ebooks
...
it-ebooks
...
Downey and Chris Mayfield
Beijing
Boston Farnham Sebastopol
www
...
info
Tokyo
Think Java
by Allen B
...
Downey and Chris Mayfield
...
Printed in the United States of America
...
, 1005 Gravenstein Highway North, Sebastopol, CA 95472
...
Online editions are
also available for most titles (http://safaribooksonline
...
For more information, contact our corporate/
institutional sales department: 800-998-9938 or corporate@oreilly
...
Editor: Brian Foster
Production Editor: Kristen Brown
Copyeditor: Charles Roumeliotis
Proofreader: Christina Edwards
Indexers: Allen B
...
com/catalog/errata
...
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc
...
While the publisher and the authors have used good faith efforts to ensure that the information and
instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility
for errors or omissions, including without limitation responsibility for damages resulting from the use of
or reliance on this work
...
If any code samples or other technology this work contains or describes is subject to open source
licenses or the intellectual property rights of others, it is your responsibility to ensure that your use
thereof complies with such licenses and/or rights
...
0 Unported License
...
com/wp/think-java/
...
it-ebooks
...
ix
1
...
1
What Is Programming?
What Is Computer Science?
Programming Languages
The Hello World Program
Displaying Strings
Escape Sequences
Formatting Code
Debugging Code
Vocabulary
Exercises
1
2
3
4
5
6
7
8
8
10
2
...
13
Declaring Variables
Assignment
State Diagrams
Printing Variables
Arithmetic Operators
Floating-Point Numbers
Rounding Errors
Operators for Strings
Composition
Types of Errors
Vocabulary
Exercises
13
14
15
16
16
17
19
19
21
21
24
25
iii
www
...
info
3
...
29
The System Class
The Scanner Class
Program Structure
Inches to Centimeters
Literals and Constants
Formatting Output
Centimeters to Inches
Modulus Operator
Putting It All Together
The Scanner Bug
Vocabulary
Exercises
29
30
31
32
33
33
35
35
36
37
38
39
4
...
43
Math Methods
Composition Revisited
Adding New Methods
Flow of Execution
Parameters and Arguments
Multiple Parameters
Stack Diagrams
Reading Documentation
Writing Documentation
Vocabulary
Exercises
43
44
45
47
48
49
50
51
53
54
55
5
...
57
Relational Operators
Logical Operators
Conditional Statements
Chaining and Nesting
Flag Variables
The return Statement
Validating Input
Recursive Methods
Recursive Stack Diagrams
Binary Numbers
Vocabulary
Exercises
iv
|
57
58
59
60
61
61
62
62
64
65
66
67
Table of Contents
www
...
info
6
...
71
Return Values
Writing Methods
Method Composition
Overloading
Boolean Methods
Javadoc Tags
More Recursion
Leap of Faith
One More Example
Vocabulary
Exercises
71
73
75
76
77
78
79
81
82
82
83
7
...
89
The while Statement
Generating Tables
Encapsulation and Generalization
More Generalization
The for Statement
The do-while Loop
break and continue
Vocabulary
Exercises
89
90
92
94
96
97
98
99
99
8
...
103
Creating Arrays
Accessing Elements
Displaying Arrays
Copying Arrays
Array Length
Array Traversal
Random Numbers
Traverse and Count
Building a Histogram
The Enhanced for Loop
Vocabulary
Exercises
103
104
105
106
107
107
108
109
110
111
112
113
9
...
117
Characters
Strings Are Immutable
String Traversal
117
118
119
Table of Contents
www
...
info
|
v
Substrings
The indexOf Method
String Comparison
String Formatting
Wrapper Classes
Command-Line Arguments
Vocabulary
Exercises
120
121
121
122
123
123
125
125
10
...
131
Point Objects
Attributes
Objects as Parameters
Objects as Return Types
Mutable Objects
Aliasing
The null Keyword
Garbage Collection
Class Diagrams
Java Library Source
Vocabulary
Exercises
131
132
133
133
134
136
137
137
138
139
140
140
11
...
145
The Time Class
Constructors
More Constructors
Getters and Setters
Displaying Objects
The toString Method
The equals Method
Adding Times
Pure Methods and Modifiers
Vocabulary
Exercises
145
146
148
149
151
151
152
154
155
156
157
12
...
161
Card Objects
Card toString
Class Variables
The compareTo Method
Cards Are Immutable
vi
|
161
163
164
165
166
Table of Contents
www
...
info
Arrays of Cards
Sequential Search
Binary Search
Tracing the Code
Recursive Version
Vocabulary
Exercises
167
169
169
170
171
172
172
13
...
175
The Deck Class
Shuffling Decks
Selection Sort
Merge Sort
Subdecks
Merging Decks
Adding Recursion
Vocabulary
Exercises
175
176
177
178
178
179
180
181
181
14
...
185
Decks and Hands
CardCollection
Inheritance
Dealing Cards
The Player Class
The Eights Class
Class Relationships
Vocabulary
Exercises
186
186
189
190
191
194
197
198
198
A
...
201
B
...
211
C
...
217
Index
...
it-ebooks
...
it-ebooks
...
We start with the most basic concepts and are
careful to define all terms when they are first used
...
Larger topics, like recursion and object-oriented program‐
ming, are divided into smaller examples and introduced over the course of several
chapters
...
Each chapter is 12–14 pages and covers the mate‐
rial for one week of a college course
...
We begin with small problems and basic algorithms and work up to
object-oriented design
...
The Philosophy Behind the Book
Here are the guiding principles that make the book the way it is:
• One concept at a time
...
• Balance of Java and concepts
...
Most chapters start with language
features and end with concepts
...
An important goal of the book is to be small enough so that students
can read and understand the entire text in a one-semester college or AP course
...
We try to introduce the minimum number of terms and
define them carefully when they are first used
...
ix
www
...
info
• Program development
...
We demonstrate multiple program develop‐
ment techniques, allowing readers to choose methods that work best for them
...
To write a program, you have to understand the algo‐
rithm, know the programming language, and be able to debug errors
...
Object-Oriented Programming
Some Java books introduce classes and objects immediately; others begin with proce‐
dural programming and transition to object-oriented more gradually
...
Some of these fea‐
tures are hard to explain when people aren’t familiar with the problems they solve
...
So it takes some
time to get there
...
In some cases we explain a feature briefly when it first appears, and
then explain it more deeply later on
...
(AP is a registered trade‐
mark of the College Board
...
A mapping of Think Java section numbers to the current AP
course description is available on our website: http://thinkjava
...
Appendixes
The chapters of this book are meant to be read in order, because each one builds on
the previous one
...
We avoided putting these
details in the main text, because they can be distracting
...
it-ebooks
...
Appendix B, Java 2D Graphics
Java provides libraries for working with graphics and animation, and these topics
can be engaging for students
...
Appendix C, Debugging
We provide debugging suggestions throughout the book, but we also collect our
debugging advice in an appendix
...
Using the Code Examples
Most of the code examples in this book are available from a Git repository at https://
github
...
Git is a “version control system” that allows
you to keep track of the files that make up a project
...
GitHub is a hosting service that provides storage for Git repositories and a conve‐
nient web interface
...
If
you don’t already have a GitHub account, you’ll need to create one
...
Then you can “clone” the repository, which downloads a copy of the
files to your computer
...
If you choose this
option, you don’t need a GitHub account, but you won’t be able to save your
changes on GitHub
...
com/ThinkJavaCodeZip
...
All examples in this book were developed and tested using Java SE Development Kit
8
...
If you are using an older version, some of them may not
...
it-ebooks
...
Bold
Indicates terms defined in the Vocabulary section at the end of each chapter
...
Constant width bold
Shows commands or other text that should be typed literally by the user
...
safaribooksonline
...
Technology professionals, software developers, web designers, and business and crea‐
tive professionals use Safari Books Online as their primary resource for research,
problem solving, learning, and certification training
...
Members have access to thousands of books, training videos, and prepublication
manuscripts in one fully searchable database from publishers like O’Reilly Media,
Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que,
Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kauf‐
mann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders,
McGraw-Hill, Jones & Bartlett, Course Technology, and hundreds more
...
xii
|
Preface
www
...
info
How to Contact Us
Please address comments and questions concerning this book to the publisher:
O’Reilly Media, Inc
...
You can access this page at http://bit
...
To comment or ask technical questions about this book, send email to bookques‐
tions@oreilly
...
For more information about our books, courses, conferences, and news, see our web‐
site at http://www
...
com
...
com/oreilly
Follow us on Twitter: http://twitter
...
youtube
...
• Tania Passfield pointed out that some glossaries had leftover terms that no longer
appeared in the text
...
She has also worked on a Ruby version of the book
...
• Chi-Yu Li pointed out a typo and an error in one of the code examples
...
• Muhammad Saied translated the book into Arabic, and found several errors in
the process
...
it-ebooks
...
• Leslie Klein discovered another error in the series expansion of exp − x2 , iden‐
tified typos in the card array figures, and gave helpful suggestions to clarify sev‐
eral exercises
...
• James Riely ported the textbook source from LaTeX to Sphinx: http://
fpl
...
depaul
...
• Peter Knaggs ported the book to C#: http://www
...
co
...
• Heidi Gentry-Kolen recorded several video lectures that follow the book: https://
www
...
com/user/digipipeline
...
They found errors, made many great suggestions, and helped
make the book much better
...
If you have additional comments or ideas about the text, please send them to:
feedback@greenteapress
...
xiv
| Preface
www
...
info
CHAPTER 1
The Way of the Program
The goal of this book is to teach you to think like a computer scientist
...
Like mathematicians, computer scientists use formal languages to denote
ideas, specifically computations
...
And like scien‐
tists, they observe the behavior of complex systems, form hypotheses, and test
predictions
...
It
involves the ability to formulate problems, think creatively about solutions, and
express solutions clearly and accurately
...
That’s why this
chapter is called, “The way of the program”
...
But on another
level you will use programming as a means to an end
...
What Is Programming?
A program is a sequence of instructions that specifies how to perform a computation
...
It can also be a symbolic computation, like
searching and replacing text in a document or (strangely enough) compiling a pro‐
gram
...
1
www
...
info
input:
Get data from the keyboard, a file, a sensor, or some other device
...
math:
Perform basic mathematical operations like addition and division
...
repetition:
Perform some action repeatedly, usually with some variation
...
Every program you’ve ever used,
no matter how complicated, is made up of small instructions that look much like
these
...
The process continues until the sub‐
tasks are simple enough to be performed with the basic instructions provided by the
computer
...
For example, there
are numerous ways to sort a list of numbers, and each way has its advantages
...
Computer science is the science of algorithms, including their discovery and analy‐
sis
...
Some
algorithms are faster than others, and some use less space in computer memory
...
Designing algorithms and writing code is difficult and error-prone
...
As you learn to debug your programs, you
will develop new problem solving skills
...
Although it can be frustrating, debugging is an intellectually rich, challenging, and
interesting part of computer programming
...
You are confronted with clues, and you have to infer the processes and events
2
|
Chapter 1: The Way of the Program
www
...
info
that led to the results you see
...
Programming Languages
The programming language you will learn is Java, which is a high-level language
...
Before they can run, programs in high-level languages have to be translated into a
low-level language, also called “machine language”
...
But high-level languages have
two advantages:
• It is much easier to program in a high-level language
...
• High-level languages are portable, meaning they can run on different kinds of
computers with few or no modifications
...
Two kinds of programs translate high-level languages into low-level languages: inter‐
preters and compilers
...
It processes the program a little at a time,
alternately reading lines and performing computations
...
Figure 1-1
...
In contrast, a compiler reads the entire program and translates it completely before
the program starts running
...
Once a program is compiled, you can execute it repeatedly without further transla‐
tion
...
Java is both compiled and interpreted
...
Similar to machine lan‐
guage, byte code is easy and fast to interpret
...
it-ebooks
...
The interpreter that runs byte code is
called a “Java Virtual Machine” (JVM)
...
The process of compiling and running a Java program
...
Although it might seem complicated, these
steps are automated for you in most program development environments
...
On the other hand, it is important to know what steps are happening in the
background, so if something goes wrong you can figure out what it is
...
All it does is display the words “Hello,
World!” on the screen
...
out
...
Java programs are made up of class and method definitions, and methods are made up
of statements
...
In the
hello world program, this line is a print statement that displays a message on the
screen:
System
...
println("Hello, World!");
System
...
println displays results on the screen; the name println stands for
“print line”
...
In this book, we’ll try to say “display” when we mean output to the screen
...
4
|
Chapter 1: The Way of the Program
www
...
info
Java is “case-sensitive”, which means that uppercase and lowercase are not the same
...
A method is a named sequence of statements
...
Later, we will see pro‐
grams that define more than one method
...
This program defines a class named Hello
...
The name of the class has to match the name of the file it is in, so this class has to be
in a file named Hello
...
Java uses squiggly braces ({ and }) to group things together
...
java, the outer‐
most braces contain the class definition, and the inner braces contain the method
definition
...
When the compiler sees //, it ignores everything from there
until the end of the line
...
Displaying Strings
You can put as many statements as you like in main
...
out
...
out
...
Phrases that appear in quotation marks are called strings, because they contain a
sequence of “characters” strung together
...
Displaying Strings
www
...
info
|
5
System
...
println appends a special character, called a newline, that moves to the
beginning of the next line
...
out
...
out
...
Notice that there is a space at the end of the
first string, which appears in the output
...
You just have
to tell Java where to put the line breaks
...
out
...
The backslash allows you to “escape” the string’s literal interpretation
...
If you add a space there, there will be a
space at the beginning of the second line
...
Since double quotes indicate the beginning and end of strings, you need to
escape them with a backslash
...
out
...
");
The result is:
She said "Hello!" to me
...
it-ebooks
...
Common escape sequences
\n newline
\t tab
\" double quote
\\ backslash
Formatting Code
In Java programs, some spaces are required
...
out
...
out
...
For example, this program is legal:
public class Goodbye {
public static void main(String[] args) {
System
...
print("Goodbye, ");
System
...
println("cruel world");
}
}
The newlines are optional, too
...
out
...
out
...
Newlines and
spaces are important for organizing your program visually, making it easier to under‐
stand the program and find errors when they occur
...
For example, in DrJava (see Appendix A) you can indent the code by
selecting all text (Ctrl+A) and pressing the Tab key
...
For example, Google publishes its Java coding standards
for use in open-source projects: http://google
...
io/styleguide/javaguide
...
Formatting Code
www
...
info
|
7
You might not understand these guidelines now, because they refer to language fea‐
tures we haven’t yet seen
...
Debugging Code
It is a good idea to read this book in front of a computer so you can try out the exam‐
ples as you go
...
But if you put the code in a source file, it will be easier to try
out variations
...
For example, in the hello world program, what happens if you leave out one
of the quotation marks? What if you leave out both? What if you spell println
wrong? These kinds of experiments help you remember what you read
...
It is better to
make mistakes now and on purpose than later on and accidentally
...
If your hypothesis was correct, then
you can predict the result of the modification, and you take a step closer to a working
program
...
Programming and debugging should go hand in hand
...
Instead, start with
a program that does something and make small modifications, debugging them as you
go, until the program does what you want
...
A great example of this principle is the Linux operating system, which contains mil‐
lions of lines of code
...
According to Larry Greenfield in The Linux Users’ Guide,
“One of Linus’s earlier projects was a program that would switch between printing
AAAA and BBBB
...
”
Finally, programming sometimes brings out strong emotions
...
Remember
that you are not alone, and most if not all programmers have had similar experiences
...
At the end of
each chapter, we include the new terms and their definitions in order of appearance
...
it-ebooks
...
problem solving:
The process of formulating a problem, finding a solution, and expressing the sol‐
ution
...
programming:
The application of problem solving to creating executable computer programs
...
algorithm:
A procedure or formula for solving a problem, with or without a computer
...
debugging:
The process of finding and removing errors
...
low-level language:
A programming language that is designed to be easy for a computer to run
...
portable:
The ability of a program to run on more than one kind of computer
...
compile:
To translate a program in a high-level language into a low-level language, all at
once, in preparation for later execution
...
Vocabulary
www
...
info
|
9
object code:
The output of the compiler, after translating the program
...
byte code:
A special kind of object code used for Java programs
...
statement:
Part of a program that specifies one step of an algorithm
...
method:
A named sequence of statements
...
(We will see later that there is more to
it
...
string:
A sequence of characters; the primary data type for text
...
Also known as line ending,
end of line (EOL), or line break
...
Exercises
At the end of each chapter, we include exercises you can do with the things you’ve
learned
...
You can’t learn to pro‐
gram only by reading about it; you have to practice
...
There are many good options, but we recommend DrJava, which is
an “integrated development environment” (IDE) well suited for beginners
...
10
|
Chapter 1: The Way of the Program
www
...
info
The code for this chapter is in the ch01 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
Computer scientists have the annoying habit of using common English words to
mean something other than their common English meaning
...
1
...
What does it mean to say that a program is portable?
3
...
What is an executable? Why is that word used as a noun?
The glossary at the end of each chapter is intended to highlight words and phrases
that have special meanings in computer science
...
Before you do anything else, find out how to compile and run a Java program
...
1
...
2
...
Say something witty like, “How are you?” Compile and run the program again
...
Add a comment to the program (anywhere), recompile, and run it again
...
This exercise may seem trivial, but it is the starting place for many of the programs
we will work with
...
In some environments, it is easy to lose track of which program is executing
...
Adding (and changing) print statements is a simple way to be sure that the
program you are looking at is the program you are running
...
it-ebooks
...
It is a good idea to commit as many errors as you can think of, so that you see what
error messages the compiler produces
...
But sometimes the error messages are mis‐
leading
...
Starting with the hello world program, try out each of the following errors
...
1
...
2
...
3
...
4
...
5
...
6
...
7
...
8
...
9
...
Add an extra one
...
it-ebooks
...
We also explain three kinds of programming errors and offer additional debug‐
ging advice
...
A variable is a named location that stores a value
...
To store a value, you
first have to declare a variable
...
Each variable has a type that determines what kind of values it
can store
...
Some types begin with a capital letter and some with lowercase
...
There is no such type as Int or string
...
In general, you should use names
that indicate what the variables mean
...
it-ebooks
...
When a
variable name contains more than one word, like firstName, it is conventional to
capitalize the first letter of each word except the first
...
This example also demonstrates the syntax for declaring multiple variables with the
same type on one line: hour and minute are both integers
...
You can use any name you want for a variable
...
These words
include public, class, static, void, and int, which are used by the compiler to ana‐
lyze the structure of the program
...
oracle
...
html, but you don’t have to memorize them
...
Assignment
Now that we have declared variables, we want to use them to store values
...
message = "Hello!";
hour = 11;
minute = 59;
// give message the value "Hello!"
// assign the value 11 to hour
// set minute to 59
This example shows three assignments, and the comments illustrate different ways
people sometimes talk about assignment statements
...
• When you make an assignment to a variable, you update its value
...
For example, you cannot store a string in minute or an integer in message
...
A common source of confusion is that some strings look like integers, but they are
not
...
But that is not the same thing as the integer 123
...
it-ebooks
...
You
can declare a variable and then assign a value later, as in the previous example
...
It is not!
Equality is commutative, and assignment is not
...
In Java a = 7; is a legal assignment statement, but 7 = a; is not
...
Also, in mathematics, a statement of equality is true for all time
...
In Java, an assignment statement can make two variables equal, but
they don’t have to stay that way
...
Taken together, the variables in a program and their current values make up the pro‐
gram’s state
...
Figure 2-1
...
Diagrams like this one that show the state of the program are called state diagrams
...
As the program runs, the state changes, so you should think
of a state diagram as a snapshot of a particular point in the execution
...
it-ebooks
...
The following state‐
ments declare a variable named firstLine, assign it the value "Hello, again!", and
display that value
...
out
...
To display the name of a variable, you have to put it in quotes
...
out
...
out
...
For example:
int hour = 11;
int minute = 59;
System
...
print("The current time is ");
System
...
print(hour);
System
...
print(":");
System
...
print(minute);
System
...
println("
...
To output multiple values on the same line, it’s common to use several print state‐
ments followed by println at the end
...
If you omit the println, the program might
display the stored output at unexpected times or even terminate without displaying
anything
...
For example, the addi‐
tion operator is +, subtraction is -, multiplication is *, and division is /
...
out
...
out
...
it-ebooks
...
When the program runs, each variable is replaced by its cur‐
rent value, and then the operators are applied
...
The result of the previous example is:
Number of minutes since midnight: 719
Expressions are generally a combination of numbers, variables, and operators
...
For example, the expression 1 + 1 has the value 2
...
In the
expression hour * 60 + minute, both variables get replaced, yielding 11 * 60 + 59
...
Then the addition yields 719
...
For example, the following fragment tries to compute the frac‐
tion of an hour that has elapsed:
System
...
print("Fraction of the hour that has passed: ");
System
...
println(minute / 60);
The output is:
Fraction of the hour that has passed: 0
This result often confuses people
...
98333, not 0
...
By design, integer division always rounds toward zero,
even in cases like this one where the next integer is close
...
out
...
out
...
Floating-Point Numbers
A more general solution is to use floating-point numbers, which can represent frac‐
tions as well as integers
...
You can create double variables and assign values
to them using the same syntax we used for the other types:
Floating-Point Numbers
www
...
info
|
17
double pi;
pi = 3
...
So we can solve the problem we saw in the previous section:
double minute = 59
...
out
...
out
...
0);
The output is:
Fraction of the hour that has passed: 0
...
For
example, Java distinguishes the integer value 1 from the floating-point value 1
...
They belong to different data types, and
strictly speaking, you are not allowed to make assignments between types
...
1;
// compiler error
It is easy to forget this rule because in many cases Java automatically converts from
one type to another:
double y = 1;
// legal, but bad style
The preceding example should be illegal, but Java allows it by converting the int
value 1 to the double value 1
...
This leniency is convenient, but it often
causes problems for beginners
...
333333, which is a legal floatingpoint value
...
0
...
Converted to dou
ble, the value assigned to y is 0
...
One way to solve this problem (once you figure out the bug) is to make the righthand side a floating-point expression
...
333333, as expected:
double y = 1
...
0;
// correct
As a matter of style, you should always assign floating-point values to floating-point
variables
...
18
|
Chapter 2: Variables and Operators
www
...
info
Rounding Errors
Most floating-point numbers are only approximately correct
...
But repeating fractions, like
1/3, and irrational numbers, like π, cannot
...
The difference between the number we want and the floating-point number we get is
called rounding error
...
out
...
1 * 10);
System
...
println(0
...
1 + 0
...
1 + 0
...
1 + 0
...
1 + 0
...
1);
But on many machines, the output is:
1
...
9999999999999999
The problem is that 0
...
So its floating-point representation is only approximate
...
For many applications, like computer graphics, encryption, statistical analysis, and
multimedia rendering, floating-point arithmetic has benefits that outweigh the costs
...
For example, consider a bank
account with a balance of $123
...
45;
// potential rounding error
In this example, balances will become inaccurate over time as the variable is used in
arithmetic operations like deposits and withdrawals
...
You can avoid the problem by representing the balance
as an integer:
int balance = 12345;
// total number of cents
This solution works as long as the number of cents doesn’t exceed the largest integer,
which is about 2 billion
...
The following expressions are illegal:
"Hello" - 1
"World" / 123
"Hello" * "World"
Rounding Errors
www
...
info
|
19
The + operator works with strings, but it might not do what you expect
...
So "Hello,
" + "World!" yields the string "Hello, World!"
...
Since addition is defined for both numbers and strings, Java performs automatic con‐
versions you may not expect:
System
...
println(1 + 2 + "Hello");
// the output is 3Hello
System
...
println("Hello" + 1 + 2);
// the output is Hello12
Java executes these operations from left to right
...
But in the second line, "Hello" + 1 is "Hello1", and "Hello1"
+ 2 is "Hello12"
...
Generally speaking, Java evaluates operators from left to right
(as we saw in the previous section)
...
So 1 + 2 * 3 yields 7, not 9, and 2 + 4 / 2
yields 4, not 3
...
So in the expression minute * 100 / 60, the multiplication happens first; if the
value of minute is 59, we get 5900 / 60, which yields 98
...
• Any time you want to override the order of operations (or you are not sure what
it is) you can use parentheses
...
You can also use parentheses to make an expression easier to
read, as in (minute * 100) / 60, even though it doesn’t change the result
...
If it’s not obvious by looking at the expression, use parentheses to make it clear
...
it-ebooks
...
One of the most useful features of programming languages is their ability to take
small building blocks and compose them
...
We can combine these operations into a
single statement:
System
...
println(17 * 3);
Any arithmetic expression can be used inside a print statement
...
out
...
That’s
because the left side indicates where the result will be stored, and expressions do not
represent storage locations
...
But don’t get too carried away
...
Types of Errors
Three kinds of errors can occur in a program: compile-time errors, run-time errors,
and logic errors
...
Compile-time errors occur when you violate the syntax rules of the Java language
...
So (1 + 2) is
legal, but 8) is not
...
Error messages from the compiler usually indicate where in the program the error
occurred, and sometimes they can tell you exactly what the error is
...
Composition
www
...
info
|
21
public class Hello {
public static void main(String[] args) {
// generate some simple output
System
...
println("Hello, World!");
}
}
If you forget the semicolon at the end of the print statement, you might get an error
message like this:
File: Hello
...
But error messages are not always easy to understand
...
And sometimes the description of the problem is more confusing than
helpful
...
java [line: 7]
Error: reached end of file while parsing
There are two problems here
...
Parsing is the process of reading a program before translat‐
ing; if the compiler gets to the end of the file while still parsing, that means something
was omitted
...
It also doesn’t know where
...
Error messages contain useful information, so you should make an effort to read and
understand them
...
During the first few weeks of your programming career, you will probably spend a lot
of time tracking down compile-time errors
...
The second type of error is a run-time error, so-called because it does not appear
until after the program has started running
...
These errors are also
called “exceptions” because they usually indicate that something exceptional (and
bad) has happened
...
it-ebooks
...
When a run-time error occurs, the
interpreter displays an error message that explains what happened and where
...
lang
...
main(Hello
...
The first line includes the name of
the exception, java
...
ArithmeticException, and a message that indicates more
specifically what happened, / by zero
...
main indicates the method main in the class Hello
...
java, and the line number where
the error occurred, 5
...
So one of the challenges is to figure out where to find the useful parts without being
overwhelmed by extraneous information
...
The third type of error is the logic error
...
Instead, it will do exactly what you told it to do
...
out
...
out
...
The problem is
that the first line uses println, when we probably meant to use print (see the “good‐
bye world” example of “Displaying Strings” on page 5)
...
Usually the compiler and the interpreter can’t help
you, since they don’t know what the right thing is
...
It refers to lan‐
Types of Errors
www
...
info
|
23
guage features we haven’t talked about yet, so you might want to re-read it from time
to time
...
All variables have a type, which is declared
when the variable is created
...
Every value
belongs to a type (for example, int or String)
...
type:
Mathematically speaking, a set of values
...
keyword:
A reserved word used by the compiler to analyze programs
...
assignment:
A statement that gives a value to a variable
...
state:
The variables in a program and their current values
...
operator:
A symbol that represents a computation like addition, multiplication, or string
concatenation
...
Most operators in Java require
two operands
...
Expressions also have types, as determined by their operators and operands
...
it-ebooks
...
In
Java, the default floating-point type is double
...
concatenate:
To join two values, often strings, end-to-end
...
composition:
The ability to combine simple expressions and statements into compound
expressions and statements
...
compile-time error:
An error in the source code that makes it impossible to compile
...
parse:
To analyze the structure of a program; what the compiler does first
...
Also called
an “exception”
...
Exercises
The code for this chapter is in the ch02 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
It describes the DrJava Interactions Pane, which is a useful way to develop and
test short fragments of code without writing a complete class definition
...
it-ebooks
...
If you are using this book in a class, you might enjoy this exercise
...
One player looks away while
the other player adds an error to the program
...
You get two points if you find the error without compiling the program,
one point if you find it using the compiler, and your opponent gets a point if you
don’t find it
...
The point of this exercise is (1) to use string concatenation to display values with dif‐
ferent types (int and String), and (2) to practice developing programs gradually by
adding a few statements at a time
...
Create a new program named Date
...
Copy or type in something like the
hello world program and make sure you can compile and run it
...
Following the example in “Printing Variables” on page 16, write a program that
creates variables named day, date, month, and year
...
What type is each variable? Assign values to those variables that repre‐
sent today’s date
...
Display (print out) the value of each variable on a line by itself
...
Compile
and run your program before moving on
...
Modify the program so that it displays the date in standard American format, for
example: Thursday, July 16, 2015
...
Modify the program so it also displays the date in European format
...
it-ebooks
...
The point of this exercise is to (1) use some of the arithmetic operators, and (2) start
thinking about compound entities (like time of day) that are represented with multi‐
ple values
...
Create a new program called Time
...
From now on, we won’t remind you to
start with a small, working program, but you should
...
Following the example program in “Printing Variables” on page 16, create vari‐
ables named hour, minute, and second
...
Use a 24-hour clock so that at 2pm the value of hour is 14
...
Make the program calculate and display the number of seconds since midnight
...
Calculate and display the number of seconds remaining in the day
...
Calculate and display the percentage of the day that has passed
...
6
...
Then
write code to compute the elapsed time since you started working on this exer‐
cise
...
Variables that are used in a computation but never displayed are sometimes
called “intermediate” or “temporary” variables
...
it-ebooks
...
it-ebooks
...
This chapter will show you how to read input from the key‐
board, use that input to calculate a result, and then format that result for output
...
out
...
System is a class that provides methods related to the
“system” or environment where programs run
...
out, which is
a special value that provides methods for displaying output, including println
...
out
...
out:
System
...
println(System
...
io
...
out is a PrintStream, which is defined in a pack‐
age called java
...
A package is a collection of related classes; java
...
The numbers and letters after the @ sign are the address of System
...
The address of a value is its location in the com‐
puter’s memory, which might be different on different computers
...
As shown in Figure 3-1, System is defined in a file called System
...
java
...
29
www
...
info
Figure 3-1
...
out
...
The Scanner Class
The System class also provides the special value System
...
These methods are not
easy to use; fortunately, Java provides other classes that make it easier to handle com‐
mon input tasks
...
Scanner is provided by java
...
Before you can use Scanner, you have
to import it like this:
import java
...
Scanner;
This import statement tells the compiler that when you say Scanner, you mean the
one defined in java
...
It’s necessary because there might be another class named
Scanner in another package
...
Import statements can’t be inside a class definition
...
Next you have to create a Scanner:
Scanner in = new Scanner(System
...
it-ebooks
...
in
...
The following example reads two lines and repeats them
back to the user:
import java
...
Scanner;
public class Echo {
public static void main(String[] args) {
String line;
Scanner in = new Scanner(System
...
out
...
nextLine();
System
...
println("You said: " + line);
System
...
print("Type something else: ");
line = in
...
out
...
That means the compiler doesn’t know what you
mean by Scanner
...
System
belongs to the java
...
According to the
documentation, java
...
” The String class is also part of the java
...
Program Structure
At this point, we have seen all of the elements that make up Java programs
...
To review, a package is a collection of classes, which define methods
...
Expressions are made up of
tokens, which are the basic elements of a program, including numbers, variable
names, operators, keywords, and punctuation like parentheses, braces and semico‐
lons
...
it-ebooks
...
Elements of the Java language, from largest to smallest
...
You can browse this library at http://
docs
...
com/javase/8/docs/api/
...
Note there is a major difference between the Java language, which defines the syntax
and meaning of the elements in Figure 3-2, and the Java library, which provides the
built-in classes
...
Although most of the world has
adopted the metric system for weights and measures, some countries are stuck with
English units
...
Or they might want to convert height in inches to centimeters
...
We’ll use a Scanner to input a measurement in
inches, convert to centimeters, and then display the results
...
in);
The next step is to prompt the user for the input
...
And we’ll use the Scanner
method nextInt, which reads input from the keyboard and converts it to an integer:
System
...
print("How many inches? ");
inch = in
...
54, since that’s how many centimeters
there are per inch, and display the results:
32
|
Chapter 3: Input and Output
www
...
info
cm = inch * 2
...
out
...
out
...
If another programmer reads
this code, they might wonder where 2
...
For the benefit of others (and
yourself in the future), it would be better to assign this value to a variable with a
meaningful name
...
Literals and Constants
A value that appears in a program, like 2
...
In gen‐
eral, there’s nothing wrong with literals
...
54 appear in an
expression with no explanation, they make code hard to read
...
Values like that are sometimes called magic numbers (with the implication that being
“magic” is not a good thing)
...
54;
cm = inch * cmPerInch;
This version is easier to read and less error-prone, but it still has a problem
...
Once we assign a value
to cmPerInch, it should never change
...
final double CM_PER_INCH = 2
...
If you try, the compiler reports an error
...
By convention, names for constants are all uppercase, with the
underscore character (_) between words
...
out
...
0 / 3
...
3333333333333333
Literals and Constants
www
...
info
|
33
That might be more than you want
...
out provides another method, called
printf, that gives you more control of the format
...
Here’s an example:
System
...
printf("Four thirds = %
...
0 / 3
...
This format string contains ordinary text followed by a format
specifier, which is a special sequence that starts with a percent sign
...
3f indicates that the following value should be displayed as floating-point,
rounded to three decimal places
...
333
The format string can contain any number of format specifiers; here’s an example
with two:
int inch = 100;
double cm = inch * CM_PER_INCH;
System
...
printf("%d in = %f cm\n", inch, cm);
The result is:
100 in = 254
...
So format strings often end with a
newline character
...
The values
are matched up with the format specifiers in order, so inch is displayed using %d, and
cm is displayed using %f
...
There are
many options, and the details can be overwhelming
...
For more details, refer to the documen‐
tation of java
...
Formatter
...
Table 3-1
...
2f rounded to 2 decimal places
34
|
6
...
79
Chapter 3: Input and Output
www
...
info
Centimeters to Inches
Now suppose we have a measurement in centimeters, and we want to round it off to
the nearest inch
...
” The problem is that the value on the right is floating-point, and the
variable on the left is an integer
...
The syntax for
type casting is to put the name of the type in parentheses and use it as an operator
...
14159;
int x = (int) pi;
The (int) operator has the effect of converting what follows into an integer
...
Like integer division, converting to an integer always
rounds toward zero, even if the fraction part is 0
...
999999)
...
Type casting takes precedence over arithmetic operations
...
So the result is 60
...
0
...
14159;
double x = (int) pi * 20
...
out
...
And the result is rounded toward zero; we will see in the next chapter how to
round floating-point numbers to the closest integer
...
The goal is divide by 12 (the number of
inches in a foot) and keep the remainder
...
If the numbers are integers, it performs integer division
...
Centimeters to Inches
www
...
info
|
35
Using division and modulus, we can convert to feet and inches like this:
quotient = 76 / 12;
// division
remainder = 76 % 12; // modulus
The first line yields 6
...
So
76 inches is 6 feet, 4 inches
...
The modulus operator turns out to be surprisingly useful
...
You can use modulus to “extract” digits from a number: x \% 10 yields the
rightmost digit of x, and x \% 100 yields the last two digits
...
Putting It All Together
At this point, you have seen enough Java to write useful programs that solve everyday
problems
...
Now we will put everything together in a complete program:
import java
...
Scanner;
/**
* Converts centimeters to feet and inches
...
54;
final int IN_PER_FOOT = 12;
Scanner in = new Scanner(System
...
out
...
nextDouble();
// convert and output the result
inches = (int) (cm / CM_PER_INCH);
feet = inches / IN_PER_FOOT;
remainder = inches % IN_PER_FOOT;
System
...
printf("%
...
it-ebooks
...
This practice makes it easier to find their types later on, and it helps the reader know
what data is involved in the algorithm
...
It also includes a documentation comment (/**), which we’ll
learn more about in the next chapter
...
In both steps, you divide by the same number (IN_PER_FOOT)
...
The reader should never have to scroll
horizontally
...
The following code fragment asks users for their name
and age:
System
...
print("What is your name? ");
name = in
...
out
...
nextInt();
System
...
printf("Hello %s, age %d\n", name, age);
The output might look something like this:
Hello Grace Hopper, age 45
When you read a String followed by an int, everything works just fine
...
System
...
print("What is your age? ");
age = in
...
out
...
nextLine();
System
...
printf("Hello %s, age %d\n", name, age);
Try running this example code
...
Instead, it gets a “stream of characters” as
shown in Figure 3-3
...
it-ebooks
...
A stream of characters as seen by a Scanner
...
When you call
nextInt, it reads characters until it gets to a non-digit
...
Figure 3-4
...
At this point, nextInt returns 45
...
But since the next character is already a newline, nextLine returns the empty string
""
...
System
...
print("What is your age? ");
age = in
...
nextLine(); // read the newline
System
...
print("What is your name? ");
name = in
...
out
...
First you read the number, and then you read the rest of the line, which is
just a newline character
...
address:
The location of a value in computer memory, often represented as a hexadecimal
integer
...
38
| Chapter 3: Input and Output
www
...
info
import statement:
A statement that allows programs to use classes defined in other packages
...
literal:
A value that appears in source code
...
magic number:
A number that appears without explanation as part of an expression
...
constant:
A variable, declared final, whose value cannot be changed
...
format specifier:
A special code that begins with a percent sign and specifies the data type and for‐
mat of the corresponding value
...
In Java it
appears as a type name in parentheses, like (int)
...
In
Java, it is denoted with a percent sign; for example, 5 \% 2 is 1
...
See “Using the
Code Examples” on page xi for instructions on how to download the repository
...
If you have not already read “Command-Line Interface” on page 203, now might be a
good time
...
Exercises
www
...
info
|
39
Exercise 3-1
...
See what
happens if you try to display a value with type int using %f
...
Write a program that converts a temperature from Celsius to Fahrenheit
...
For example, it should dis‐
play "24
...
2 F"
...
Be careful not to use integer division!
F =C×
9
+ 32
5
Exercise 3-3
...
It should (1) prompt the user for input, (2) read an integer from the keyboard,
(3) calculate the result, and (4) use printf to display the output
...
Hint: Use the modulus operator
...
The goal of this exercise is to program a “Guess My Number” game
...
Can you guess what it is?
Type a number: 45
Your guess is: 45
The number I was thinking of is: 14
You were off by: 31
To choose a random number, you can use the Random class in java
...
Here’s how
it works:
40
|
Chapter 3: Input and Output
www
...
info
import java
...
Random;
public class GuessStarter {
public static void main(String[] args) {
// pick a random number
Random random = new Random();
int number = random
...
out
...
And as we saw with Scanner, we have to use the new operator to create a
Random (number generator)
...
In this example,
the result of nextInt(100) will be between 0 and 99, including both
...
1
...
java, in the
directory called ch03, in the repository for this book
...
Compile and run this program
...
Modify the program to prompt the user, then use a Scanner to read a line of user
input
...
4
...
Again, compile and test
...
Compute and display the difference between the user’s guess and the number that
was generated
...
it-ebooks
...
it-ebooks
...
In this chapter, we’ll show you how to organize longer programs into multiple
methods and classes
...
Math Methods
In mathematics, you have probably seen functions like sin and log, and you have
learned to evaluate expressions like sin π/2 and log 1/x
...
Then you
can evaluate the function itself, maybe by punching it into a calculator
...
First we evaluate the argument of the innermost function, then
evaluate the function itself, and so on
...
Math is in the java
...
You can use,
or invoke, Math methods like this:
double root = Math
...
0);
double angle = 1
...
sin(angle);
The first line sets root to the square root of 17
...
5
(the value of angle)
...
To convert from degrees to radians, you can divide by 180 and multiply by π
...
it-ebooks
...
0 * Math
...
Java does not recognize Pi, pi, or pie
...
The same is true
for the constant Math
...
Converting to and from radians is a common operation, so the Math class provides
methods that do it for you
...
toRadians(180
...
toDegrees(Math
...
A long is like an int, but bigger
...
A long
uses 64 bits, so the largest value is 263 − 1, which is about 9 quintillion
...
round(Math
...
0);
The result is 63 (rounded up from 62
...
Take a minute to read the documentation for these and other methods in the Math
class
...
Composition Revisited
Just as with mathematical functions, Java methods can be composed
...
For example, you can use any expression as
an argument to a method:
double x = Math
...
PI / 2
...
PI by two, adds the result to angle, and computes the
cosine of the sum
...
exp(Math
...
0));
In Java, the log method always uses base e
...
The result gets assigned to x
...
For example, Math
...
This line of code assigns the
value 1024
...
it-ebooks
...
pow(2
...
0);
When using Math methods, it is a common error to forget the Math
...
0, 10
...
java [line: 5]
Error: cannot find symbol
symbol:
method pow(double,double)
location: class Test
The message “cannot find symbol” is confusing, but the last line provides a useful
hint
...
If you don’t specify a class name, the compiler looks in the current class
...
Here’s an example:
public class NewLine {
public static void newLine() {
System
...
println();
}
public static void main(String[] args) {
System
...
println("First line
...
out
...
");
}
}
The name of the class is NewLine
...
NewLine contains two methods, newLine and main
...
Method names should begin with a lowercase letter and use “camel case”, which is a
cute name for jammingWordsTogetherLikeThis
...
newLine and main are public, which means they can be invoked from other classes
...
And they are both
void, which means that they don’t yield a result (unlike the Math methods, for exam‐
ple)
...
main has a single parameter, called args,
which has type String[]
...
Adding New Methods
www
...
info
|
45
Since newLine has no parameters, it requires no arguments, as shown when it is
invoked in main
...
The output of this program is:
First line
...
Notice the extra space between the lines
...
out
...
");
newLine();
newLine();
newLine();
System
...
println("Second line
...
out
...
");
threeLine();
System
...
println("Second line
...
In this example, main invokes threeLine, and threeLine invokes new
Line
...
There are
many reasons, but this example demonstrates a few of them:
• Creating a new method gives you an opportunity to give a name to a group of
statements, which makes code easier to read and understand
...
For example, to display nine consecutive new lines, you could invoke three
Line three times
...
it-ebooks
...
Methods allow you to focus on each sub-problem in isolation, and then compose
them into a complete solution
...
out
...
out
...
");
threeLine();
System
...
println("Second line
...
But that is likely to be confusing, because that is not the
flow of execution of the program
...
Statements are executed one at a time, in order, until you reach a method
invocation, which you can think of as a detour
...
That sounds simple enough, but remember that one method can invoke another one
...
While we are
executing threeLine, we go off to execute newLine
...
Fortunately, Java is good at keeping track of which methods are running
...
Flow of Execution
www
...
info
|
47
In summary, when you read a program, don’t read from top to bottom
...
Parameters and Arguments
Some of the methods we have used require arguments, which are the values you pro‐
vide when you invoke the method
...
To display a mes‐
sage, you have to provide the message, so println takes a String
...
When you write a method, you
name the parameters
...
The
following class shows an example:
public class PrintTwice {
public static void printTwice(String s) {
System
...
println(s);
System
...
println(s);
}
public static void main(String[] args) {
printTwice("Don't make me say this twice!");
}
}
printTwice has a parameter named s with type String
...
Before the method executes, the argument gets assigned to the parameter
...
This process is called parameter passing because the value gets passed from outside
the method to the inside
...
";
printTwice(argument);
The value you provide as an argument must have the same type as the parameter
...
it-ebooks
...
java [line: 10]
Error: method printTwice in class Test cannot be applied
to given types;
required: java
...
String
found: int
reason: actual argument int cannot be converted to
java
...
String by method invocation conversion
Sometimes Java can convert an argument from one type to another automatically
...
sqrt requires a double, but if you invoke Math
...
0
...
Parameters and other variables only exist inside their own methods
...
If you try to use it there, you’ll get a compiler error
...
That variable belongs to
main
...
Multiple Parameters
Here is an example of a method that takes two parameters:
public static void printTime(int hour, int minute) {
System
...
print(hour);
System
...
print(":");
System
...
println(minute);
}
In the parameter list, it may be tempting to write:
public static void printTime(int hour, minute) {
...
In
parameter lists, you need to specify the type of each variable separately
...
it-ebooks
...
You wouldn’t declare the types of the arguments if they were
simply integers:
printTime(int 11, int 59);
// syntax error
Stack Diagrams
Pulling together the code fragments from the previous section, here is a complete
class definition:
public class PrintTime {
public static void printTime(int hour, int minute) {
System
...
print(hour);
System
...
print(":");
System
...
println(minute);
}
public static void main(String[] args) {
int hour = 11;
int minute = 59;
printTime(hour, minute);
}
}
printTime has two parameters, named hour and minute
...
Although they have the same names, these variables are
not the same
...
For example, you could invoke printTime like this:
int hour = 11;
int minute = 59;
printTime(hour + 1, 0);
Before the method is invoked, Java evaluates the arguments; in this example, the
results are 12 and 0
...
Inside printTime,
the value of hour is 12, not 11, and the value of minute is 0, not 59
...
One way to keep track of everything is to draw a stack diagram, which is a state dia‐
gram (see “State Diagrams” on page 15) that shows method invocations
...
The name of the method appears outside the frame; the variables and parame‐
ters appear inside
...
it-ebooks
...
Figure 4-1 is a stack diagram at the beginning of the printTime
method
...
Stack diagram for PrintTime
...
But before you use them, you might have to read the documentation
...
As an example, let’s look at the documentation for Scanner, which we used in “The
Scanner Class” on page 30
...
Figure 4-2 shows a screenshot of the page
...
Screenshot of the documentation for Scanner
...
it-ebooks
...
The first line is the package
that contains the class, such as java
...
The second line is the name of the class
...
The next section of the documentation is a narrative that explains the purpose of the
class and includes examples of how to use it
...
But the examples are often very useful
...
One of the examples shows how you can use a Scanner to read input from a String
instead of System
...
Method summary:
The list of methods that Scanner provides
...
Method detail:
More information about each method
...
The first line is the method’s signature, which specifies the name of the method, its
parameters (none), and what type it returns (int)
...
The “Method detail” explains more:
public int nextInt()
Scans the next token of the input as an int
...
Returns:
the int scanned from the input
52
|
Chapter 4: Void Methods
www
...
info
Throws:
InputMismatchException - if the next token does not match
the Integer regular expression, or is out of range
NoSuchElementException - if input is exhausted
IllegalStateException - if this scanner is closed
The “Returns” section describes the result when the method succeeds
...
Exceptions
are said to be “thrown”, like a referee throwing a flag, or like a toddler throwing a fit
...
But it’s worth the effort
...
And a little bit of documentation can save you
a lot of debugging
...
A nice feature of the Java language is the ability to
embed documentation in your source code
...
If you include documentation in your source code, you can extract it automatically,
and generate well-formatted HTML, using a tool called Javadoc
...
In fact, the online
documentation of the Java libraries is generated by Javadoc
...
They begin with /** (two stars) and end
with */ (one star)
...
Here’s a class definition with two Javadoc comments, one for the class and one for the
main method:
/**
* Example program that demonstrates print vs println
...
*/
public static void main(String[] args) {
System
...
print("Goodbye, "); // note the space
System
...
println("cruel world");
}
}
Writing Documentation
www
...
info
|
53
The class comment explains the purpose of the class
...
Notice that this example also includes an inline comment, beginning with //
...
They are intended for other programmers reading and maintaining the source code
...
They explain
what each method does, but they omit details about how the method works
...
Appropriate comments and documentation are essential for making source code
readable
...
Vocabulary
argument:
A value that you provide when you invoke a method
...
invoke:
To cause a method to execute
...
parameter:
A piece of information that a method requires before it can run
...
flow of execution:
The order in which Java executes methods and statements
...
parameter passing:
The process of assigning an argument value to a parameter variable
...
Local variables cannot be accessed from
outside their method
...
The
method calls are “stacked” from top to bottom, in the flow of execution
...
54
|
Chapter 4: Void Methods
www
...
info
signature:
The first line of a method that defines its name, return type, and parameters
...
documentation:
Comments that describe the technical operation of a class or method
...
See “Using the
Code Examples” on page xi for instructions on how to download the repository
...
If you have not already read “Command-Line Testing” on page 204, now might be a
good time
...
Exercise 4-1
...
1
...
Hint: Start by describing in words what ping and baffle do when they are
invoked
...
Draw a stack diagram that shows the state of the program the first time ping is
invoked
...
What happens if you invoke baffle(); at the end of the ping method? (We will
see why in the next chapter
...
out
...
out
...
out
...
it-ebooks
...
out
...
out
...
");
}
Exercise 4-2
...
1
...
2
...
Exercise 4-3
...
You should start with a working solution to
Exercise 2-2
...
Write a method called printAmerican that takes the day, date, month and year as
parameters and that displays them in American format
...
Test your method by invoking it from main and passing appropriate arguments
...
Once you have debugged printAmerican, write another method called
printEuropean that displays the date in European format
...
it-ebooks
...
For more complex computations, programs usually
react to the inputs, check for certain conditions, and generate appropriate results
...
Relational Operators
Relational operators are used to check conditions like whether two values are equal,
or whether one is greater than the other
...
These
values belong to the data type boolean; in fact, they are the only boolean values
...
A common error is to use a
single = instead of a double ==
...
Also, there is no such thing as the =< or => operators
...
For example, the expres‐
sion 5 < "6" is invalid because 5 is an int and "6" is a String
...
it-ebooks
...
For example, when evaluating the expression 5
< 6
...
0
...
But confusingly, == and != do work
with strings—they just don’t do what you expect
...
Instead, you should use the equals
method:
String fruit1 = "Apple";
String fruit2 = "Orange";
System
...
println(fruit1
...
equals(fruit2) is the boolean value false
...
The results of these operators are similar to their meanings in English
...
The expression evenFlag || n \% 3 == 0 is true if either condition is true, that
is, if evenFlag is true or the number n is divisible by 3
...
So !evenFlag is true if evenFlag is not true
...
For example,
true || anything is always true, so Java does not need to evaluate the expression
anything
...
Ignoring the second operand,
when possible, is called short circuit evaluation, by analogy with an electrical circuit
...
It can also avoid unnecessary errors, if anything might fail
...
The ! operator takes precedence over && and ||, so you don’t have to put
parentheses around the individual terms !A and !B
...
In this case, negating each
term means using the “opposite” relational operator
...
it-ebooks
...
For instance, “If I don’t want x
to be less than 5, and I don’t want y to be 3, then I need x to be greater than or equal
to 5, or I need y to be anything but 3
...
Conditional statements give us this ability
...
out
...
If it is true, the statements in
braces get executed
...
The condition in parentheses can be any boolean expression
...
The possibilities are called branches, and the condition determines which one
gets executed:
if (x % 2 == 0) {
System
...
println("x is even");
} else {
System
...
println("x is odd");
}
If the remainder when x is divided by 2 is zero, we know that x is even, and this frag‐
ment displays a message to that effect
...
Since the condition must be true or false, exactly one of the
branches will run
...
So we could have
written the previous example this way:
if (x % 2 == 0)
System
...
println("x is even");
else
System
...
println("x is odd");
However, it’s better to use braces—even when they are optional—to avoid making the
mistake of adding statements to an if or else block and forgetting to add the braces
...
it-ebooks
...
out
...
out
...
Since there are no braces,
only the first println is part of the if statement
...
out
...
out
...
Even experienced programmers
make this mistake; search the web for Apple’s “goto fail” bug
...
One way to do this is by chaining a series of if and else statements:
if (x > 0) {
System
...
println("x is positive");
} else if (x < 0) {
System
...
println("x is negative");
} else {
System
...
println("x is zero");
}
These chains can be as long as you want, although they can be difficult to read if they
get out of hand
...
If you keep all the statements and braces lined up,
you are less likely to make syntax errors
...
We could have written the previous example as:
if (x == 0) {
System
...
println("x is zero");
} else {
if (x > 0) {
System
...
println("x is positive");
} else {
System
...
println("x is negative");
}
}
The outer conditional has two branches
...
These two branches are also print statements, but they could
have been conditional statements as well
...
it-ebooks
...
Good indentation is essential to make the structure (or intended structure)
apparent to the reader
...
You can create one like
this:
boolean flag;
flag = true;
boolean testResult = false;
The first line is a variable declaration, the second is an assignment, and the third is
both
...
A variable
defined in this way is called a flag, because it signals or “flags” the presence or absence
of a condition
...
out
...
Since evenFlag is a
boolean, it’s already a condition
...
out
...
One reason to use return is if you detect an error condition:
public static void printLogarithm(double x) {
if (x <= 0
...
err
...
");
return;
}
double result = Math
...
out
...
it-ebooks
...
It checks whether x is less than or equal to zero, in which
case it displays an error message and then uses return to exit the method
...
This example uses System
...
Some development environments display output to Sys
tem
...
Validating Input
Here is a method that uses printLogarithm from the previous section:
public static void scanDouble() {
Scanner in = new Scanner(System
...
out
...
nextDouble();
printLogarithm(x);
}
This example uses nextDouble, so the Scanner tries to read a double
...
But if the user
types anything else, the Scanner throws an InputMismatchException
...
in);
System
...
print("Enter a number: ");
if (!in
...
next();
System
...
println(word + " is not a number");
return;
}
double x = in
...
If so, we can call nextDouble with no
chance of throwing an exception
...
Returning from main terminates the program
...
Consider the following example:
62
|
Chapter 5: Conditionals and Logic
www
...
info
public static void countdown(int n) {
if (n == 0) {
System
...
println("Blastoff!");
} else {
System
...
println(n);
countdown(n - 1);
}
}
The name of the method is countdown; it takes a single integer as a parameter
...
Otherwise, it displays the number
and then invokes itself, passing n - 1 as the argument
...
What happens if we invoke countdown(3) from main?
The execution of countdown begins with n == 3, and since n is not zero, it displays the
value 3, and then invokes itself
...
The execution of countdown begins with n == 1, and since n is not
zero, it displays the value 1, and then invokes itself
...
The countdown that got n == 1 returns
...
The countdown that got n == 3 returns
...
So the total output looks like:
3
2
1
Blastoff!
As a second example, we’ll rewrite the methods newLine and threeLine from
“Adding New Methods” on page 45
...
out
...
it-ebooks
...
A better alternative would be:
public static void nLines(int n) {
if (n > 0) {
System
...
println();
nLines(n - 1);
}
}
This method takes an integer, n, as a parameter and displays n newlines
...
As long as n is greater than zero, it displays a newline and
then invokes itself to display n − 1 additional newlines
...
Recursive Stack Diagrams
In the previous chapter, we used a stack diagram to represent the state of a program
during a method invocation
...
Remember that every time a method gets called, Java creates a new frame that con‐
tains the current method’s parameters and variables
...
Figure 5-1
...
By convention, the stack for main is at the top and the stack grows down
...
(It has the parameter
args, but since we’re not using it, we left it out of the diagram
...
it-ebooks
...
The last frame, with n == 0, is called the base case
...
If there is no base case in a recursive method, or if the base case is never reached, the
stack would grow forever, at least in theory
...
For example, here is a recursive method without a base case:
public static void forever(String s) {
System
...
println(s);
forever(s);
}
This method displays the string until the stack overflows, at which point it throws an
exception
...
What do you think happens if you reverse steps
2 and 3, making the recursive call before displaying?
public static void countup(int n) {
if (n == 0) {
System
...
println("Blastoff!");
} else {
countup(n - 1);
System
...
println(n);
}
}
The stack diagram is the same as before, and the method is still called n times
...
out
...
As a
result, it counts up instead of down:
Blastoff!
1
2
3
This behavior comes in handy when it is easier to compute results in reverse order
...
it-ebooks
...
For more back‐
ground about binary numbers, see http://www
...
com/binary-numbersystem
...
Here is a recursive method that displays the binary representation of any positive
integer:
public static void displayBinary(int value) {
if (value > 0) {
displayBinary(value / 2);
System
...
print(value % 2);
}
}
If value is zero, displayBinary does nothing (that’s the base case)
...
When the
recursive call returns, the method displays one digit of the result and returns (again)
...
The right‐
most digit, at the top of the stack, gets displayed last
...
displayBinary(23);
System
...
println();
// output is 10111
Learning to think recursively is an important aspect of learning to think like a com‐
puter scientist
...
Vocabulary
boolean:
A data type with only two values, true and false
...
logical operator:
An operator that combines boolean values and produces a boolean value
...
De Morgan’s laws:
Mathematical rules that show how to negate a logical expression
...
it-ebooks
...
branch:
One of the alternative sets of statements inside a conditional statement
...
nesting:
Putting a conditional statement inside one or both branches of another condi‐
tional statement
...
recursion:
The process of invoking (and restarting) the same method that is currently exe‐
cuting
...
base case:
A condition that causes a recursive method not to make another recursive call
...
Also known as
“base 2”
...
See “Using the
Code Examples” on page xi for instructions on how to download the repository
...
If you have not already read “Tracing with a Debugger” on page 207, now might be a
good time
...
Exercise 5-1
...
For example, can you
rewrite this code using a single if statement?
Exercises
www
...
info
|
67
if (x > 0) {
if (x < 10) {
System
...
println("positive single digit number
...
For the following program:
1
...
2
...
out
...
out
...
out
...
out
...
Draw a stack diagram that shows the state of the program in “Recursive Methods” on
page 62 after main invokes nLines with the parameter n == 4, just before the last
invocation of nLines returns
...
it-ebooks
...
Fermat’s Last Theorem says that there are no integers a, b, and c such that
an + bn = cn, except when n ≤ 2
...
If n is greater than 2 and
an + bn = cn, the program should display “Holy smokes, Fermat was wrong!” Other‐
wise the program should display “No, that doesn’t work
...
pow
...
The purpose of this exercise is to take a problem and break it into smaller problems,
and to solve the smaller problems by writing simple methods
...
Subsequent verses are identical except that the number of bottles gets smaller by one
in each verse, until the last verse:
No bottles of beer on the wall,
no bottles of beer,
ya’ can’t take one down, ya’ can’t pass it around,
’cause there are no more bottles of beer on the wall!
And then the song (finally) ends
...
Your program
should include a recursive method that does the hard part, but you might want to
write additional methods to separate other parts of the program
...
Exercise 5-6
...
Read the following code and answer the questions
...
it-ebooks
...
out
...
out
...
out
...
out
...
Write the number 1 next to the first line of code in this program that will execute
...
Write the number 2 next to the second line of code, and so on until the end of the
program
...
3
...
What is the output of this program?
Exercise 5-7
...
You should already have a program that chooses a random number, prompts the user
to guess it, and displays the difference between the guess and the chosen number
...
The program should continue until the user gets it right
...
70
|
Chapter 5: Conditionals and Logic
www
...
info
CHAPTER 6
Value Methods
Some of the methods we have used, like the Math methods, return values
...
In
this chapter, we’ll write methods that return values, which we call value methods
...
For
example, here is the countup method from “Recursive Methods” on page 62:
public static void countup(int n) {
if (n == 0) {
System
...
println("Blastoff!");
} else {
countup(n - 1);
System
...
println(n);
}
}
And here is how it is invoked:
countup(3);
System
...
println("Have a nice day
...
We usually assign it to a variable or use it as part of an expression,
like this:
double error = Math
...
sin(angle);
71
www
...
info
Compared to void methods, value methods differ in two ways:
• They declare the type of the return value (the return type);
• They use at least one return statement to provide a return value
...
PI * radius * radius;
return result;
}
As usual, this method is public and static
...
The last line is a new form of the return statement that includes a return value
...
” The expression you provide can be arbitrarily com‐
plex, so we could have written this method more concisely:
public static double calculateArea(double radius) {
return Math
...
The type of the expression in the return statement must match the return type of the
method
...
If you try to return with no
expression, or an expression with the wrong type, the compiler will generate an error
...
As soon as either of them executes, the method terminates without executing
any more statements
...
it-ebooks
...
The compiler will give you an
“unreachable statement” error if part of your code is dead
...
out
...
");
}
If you put return statements inside a conditional statement, you have to make sure
that every possible path through the program reaches a return statement
...
For example, the following method is
incomplete:
public static double absoluteValue(double x) {
if (x < 0) {
return -x;
} else if (x > 0) {
return x;
}
// syntax error
}
When x is 0, neither condition is true, so the method ends without hitting a return
statement
...
But hopefully you
will know what it means
...
Then they spend way too much time debugging
...
The key aspects of incremental development are:
• Start with a working program and make small, incremental changes
...
• Use variables to hold intermediate values so you can check them, either with
print statements or by using a debugger
...
Writing Methods
www
...
info
|
73
As an example, suppose you want to find the distance between two points, given by
the coordinates x1, y1 and x2, y2
...
In other
words, what are the inputs (parameters) and what is the output (return value)? In this
case, the two points are the parameters, and it is natural to represent them using four
double values
...
Already we can write an outline for the method, which is sometimes called a stub
...
0;
}
The return statement is a placeholder that is necessary for the program to compile
...
It’s usually a good idea to think about testing before you develop new methods; doing
so can help you figure out how to implement them
...
0, 2
...
0, 6
...
0 and the vertical distance is 4
...
So the
result should be 5
...
When you are testing a
method, it is helpful to know the right answer
...
After
each incremental change, we recompile and run the program
...
The next step is to find the differences x2 − x1 and y2 − y1
...
public static double distance
(double x1, double y1, double x2, double y2) {
double dx = x2 - x1;
double dy = y2 - y1;
System
...
println("dx is " + dx);
System
...
println("dy is " + dy);
return 0
...
it-ebooks
...
They should be 3
...
0
...
Code like that is called scaffolding, because it is helpful for building the pro‐
gram, but it is not part of the final product
...
We could use the Math
...
public static double distance
(double x1, double y1, double x2, double y2) {
double dx = x2 - x1;
double dy = y2 - y1;
double dsquared = dx * dx + dy * dy;
System
...
println("dsquared is " + dsquared);
return 0
...
0
...
sqrt to compute and
return the result
...
sqrt(dsquared);
return result;
}
As you gain more experience programming, you might write and debug more than
one line at a time
...
Method Composition
Once you define a new method, you can use it as part of an expression, or build new
methods using existing methods
...
Let’s say the center point is stored in the variables xc and yc, and the
perimeter point is in xp and yp
...
Fortunately, we have a method that does just that (distance)
...
We have a method for
that computation too (calculateArea)
...
it-ebooks
...
This process
reduces debugging time and yields code that is more likely to be correct and easier to
maintain
...
They both find the area of a circle, but they take different parameters
...
If two methods do the same thing, it is natural to give them the same name
...
So we could rename cir
cleArea to calculateArea:
public static double calculateArea
(double xc, double yc, double xp, double yp) {
return calculateArea(distance(xc, yc, xp, yp));
}
Note that this new calculateArea method is not recursive
...
If you write:
double x = calculateArea(3
...
it-ebooks
...
If you write:
double y = calculateArea(1
...
0, 4
...
0);
Java uses the second version of calculateArea, which interprets the arguments as
two points
...
Many Java methods are overloaded, meaning that there are different versions that
accept different numbers or types of parameters
...
In the Math class,
there is a version of abs that works on doubles, and there is also a version for ints
...
You might
get yourself nicely confused if you are trying to debug one version of a method while
accidentally invoking a different one
...
For example:
public static boolean isSingleDigit(int x) {
if (x > -10 && x < 10) {
return true;
} else {
return false;
}
}
The name of this method is isSingleDigit
...
Since the return type is boolean, the return
statement has to provide a boolean expression
...
Remember
that the expression x > -10 && x < 10 has type boolean, so there is nothing wrong
with returning it directly (without the if statement):
public static boolean isSingleDigit(int x) {
return x > -10 && x < 10;
}
In main, you can invoke the method in the usual ways:
System
...
println(isSingleDigit(2));
boolean bigFlag = !isSingleDigit(17);
The first line displays true because 2 is a single-digit number
...
Boolean Methods
www
...
info
|
77
Conditional statements often invoke boolean methods and use the result as the con‐
dition:
if (isSingleDigit(z)) {
System
...
println("z is small");
} else {
System
...
println("z is big");
}
Examples like this one almost read like English: “If is single digit z, print
...
Javadoc Tags
In “Writing Documentation” on page 53, we discussed how to write documentation
comments using /**
...
To organize the documentation into sections, Javadoc supports optional tags that
begin with the at sign (@)
...
/**
* Tests whether x is a single digit integer
...
Notice the
relationship between the source code and the documentation
...
HTML documentation for isSingleDigit
...
it-ebooks
...
Void methods should have no @return tag, since they do not return a value
...
That means Java can compute anything computable, for any reason‐
able definition of “computable”
...
To give you an idea of what you can do with the tools we have learned, let’s look at
some methods for evaluating recursively-defined mathematical functions
...
Of course, a truly circular definition is not very useful:
recursive:
An adjective used to describe a method that is recursive
...
But if you search
for recursion on Google, it displays “Did you mean: recursion” as an inside joke
...
For example, the factorial of an integer n, which is written n!, is defined
like this:
0! = 1
n! = n · n − 1 !
Don’t confuse the mathematical symbol !, which means factorial, with the Java opera‐
tor !, which means not
...
So factorial(3) is 3 * factorial(2); factorial(2) is 2 * factorial(1);
factorial(1) is 1 * factorial(0); and factorial(0) is 1
...
If you can formulate a recursive definition of something, you can easily write a Java
method to evaluate it
...
Since factorial is defined for integers, the method takes an int as a parameter and
returns an int
...
it-ebooks
...
If the argument happens to be zero, we return 1
...
public static int factorial(int n) {
if (n == 0) {
return 1;
}
int recurse = factorial(n - 1);
int result = n * recurse;
return result;
}
The flow of execution for this program is similar to countdown from “Recursive
Methods” on page 62
...
Since 2 is not zero, we take the second branch and calculate the factorial of
n − 1
...
Since 0 is zero, we take the first branch and return the
value 1 immediately
...
The return value (1) gets multiplied by n, which is 2, and the result is
returned
...
Figure 6-2 shows what the stack diagram looks like for this sequence of method invo‐
cations
...
Notice that
recurse and result do not exist in the last frame, because when n == 0 the code that
declares them does not execute
...
it-ebooks
...
Stack diagram for the factorial method
...
An alternative is the leap of faith: when you come to a
method invocation, instead of following the flow of execution, you assume that the
method works correctly and returns the appropriate value
...
When you invoke Math
...
out
...
You just assume that they work properly
...
For example, in “Boolean
Methods” on page 77 we wrote a method called isSingleDigit that determines
whether a number is between 0 and 9
...
The same is true of recursive methods
...
For example, “Assuming that I can find the factorial of n − 1, can I compute
the factorial of n?” Yes you can, by multiplying by n
...
it-ebooks
...
But if we take a leap of faith and assume that the two recursive invoca‐
tions work correctly, it is clear that their sum is the result
...
value method:
A method that returns a value
...
return value:
The value provided as the result of a method invocation
...
dead code:
Part of a program that can never be executed, often because it appears after a
return statement
...
82
|
Chapter 6: Value Methods
www
...
info
stub:
A placeholder for an incomplete method so that the class will compile
...
functional decomposition:
A process for breaking down a complex computation into simple methods, then
composing the methods to perform the computation
...
tag:
A label that begins with an at sign (@) and is used by Javadoc to organize docu‐
mentation into sections
...
factorial:
The product of all the integers up to and including a given integer
...
Exercises
The code for this chapter is in the ch06 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
It describes JUnit, a tool for efficiently testing value methods
...
If you have a question about whether something is legal, and what happens if it is not,
a good way to find out is to ask the compiler
...
Exercises
www
...
info
|
83
1
...
What happens if you use a void method as part of an expression? For example,
try System
...
println("boo!") + 7;
Exercise 6-2
...
Exercise 6-3
...
For example, if one of the sticks is 12 inches long and the other two are one inch
long, you will not be able to get the short sticks to meet in the middle
...
Write a method named isTriangle that takes three integers as arguments and
returns either true or false, depending on whether you can or cannot form a trian‐
gle from sticks with the given lengths
...
Exercise 6-4
...
Some processors even provide
a hardware implementation of this operation for floating-point numbers
...
Create a new program called Multadd
...
2
...
3
...
0, 2
...
0
...
it-ebooks
...
Also in main, use multadd to compute the following values:
π
π cos 4
+
4
2
log 10 + log 20
sin
5
...
exp
...
Whenever you do that, it is a good idea to test the first method
carefully before working on the second
...
One of the purposes of this exercise is to practice pattern-matching: the ability to rec‐
ognize a specific problem as an instance of a general category of problems
...
What is the output of the following program?
public static void main(String[] args) {
boolean flag1 = isHoopy(202);
boolean flag2 = isFrabjuous(202);
System
...
println(flag1);
System
...
println(flag2);
if (flag1 && flag2) {
System
...
println("ping!");
}
if (flag1 || flag2) {
System
...
println("pong!");
}
}
public static boolean isHoopy(int x) {
boolean hoopyFlag;
if (x % 2 == 0) {
hoopyFlag = true;
} else {
hoopyFlag = false;
}
return hoopyFlag;
}
Exercises
www
...
info
|
85
public static boolean isFrabjuous(int x) {
boolean frabjuousFlag;
if (x > 0) {
frabjuousFlag = true;
} else {
frabjuousFlag = false;
}
return frabjuousFlag;
}
The purpose of this exercise is to make sure you understand logical operators and the
flow of execution through value methods
...
In this exercise, you will use a stack diagram to understand the execution of the fol‐
lowing recursive program
...
out
...
Draw a stack diagram showing the state of the program just before the last invo‐
cation of prod completes
...
What is the output of this program? (Try to answer this question on paper first,
then run the code to check your answer
...
Explain in a few words what prod does (without getting into the details of how it
works)
...
Rewrite prod without the temporary variables recurse and result
...
86
| Chapter 6: Value Methods
www
...
info
Exercise 6-7
...
Start with a base case, and use temporary
variables to debug your solution
...
Exercise 6-8
...
The
Ackermann function is defined for non-negative integers as follows:
A m, n =
n+1
A m − 1, 1
A m − 1, A m, n − 1
if m = 0
if m > 0 and n = 0
if m > 0 and n > 0
Write a method called ack that takes two ints as parameters and that computes and
returns the value of the Ackermann function
...
Note the return value gets very big very quickly
...
Exercise 6-9
...
Hint: A recursive definition of this operation is xn = x · xn − 1
...
Optional challenge: you can make this method more efficient, when n is even, using
2
xn = xn/2
...
it-ebooks
...
it-ebooks
...
Repeating tasks without mak‐
ing errors is something that computers do well and people do poorly
...
We have seen methods, like
countdown and factorial, that use recursion to iterate
...
Java provides language features that make
iteration much easier: the while and for statements
...
out
...
out
...
When you get to zero, print
Blastoff!”
The expression in parentheses is called the condition
...
The flow of execution for a while statement is:
1
...
2
...
3
...
89
www
...
info
This type of flow is called a loop, because the last step loops back around to the first
...
Otherwise the loop will
repeat forever, which is called an infinite loop
...
In the case of countdown, we can prove that the loop terminates when n is positive
...
For example, this
loop continues until n is 1 (which makes the condition false):
public static void sequence(int n) {
while (n != 1) {
System
...
println(n);
if (n % 2 == 0) {
// n is even
n = n / 2;
} else {
// n is odd
n = n * 3 + 1;
}
}
}
Each time through the loop, the program displays the value of n and then checks
whether it is even or odd
...
If it is odd, the
value is replaced by 3n + 1
...
Since n sometimes increases and sometimes decreases, there is no obvious proof that
n will ever reach 1 and that the program will ever terminate
...
For example, if the starting value is a power of two, then
the value of n will be even every time through the loop until we get to 1
...
The hard question is whether this program terminates for all values of n
...
wiki
pedia
...
Generating Tables
Loops are good for generating and displaying tabular data
...
To make that easier, there were books of
tables where you could look up values of various functions
...
90
| Chapter 7: Loops
www
...
info
When computers appeared on the scene, one of the initial reactions was: “This is
great! We can use a computer to generate the tables, so there will be no errors
...
Not much later, computers were so
pervasive that printed tables became obsolete
...
In some
cases, there have been errors in the underlying tables, most famously in the table the
original Intel Pentium used to perform floating-point division (see https://en
...
org/wiki/Pentium_FDIV_bug)
...
The following loop displays a table with a sequence of values in the left col‐
umn and their logarithms in the right column:
int i = 1;
while (i < 10) {
double x = (double) i;
System
...
println(x + "
i = i + 1;
}
" + Math
...
0
2
...
0
4
...
0
6
...
0
8
...
0
0
...
6931471805599453
1
...
3862943611198906
1
...
791759469228055
1
...
0794415416798357
2
...
log computes natural logarithms, that is, logarithms base e
...
To compute them,
we can apply this equation:
log2 x =
log ex
log e2
We can modify the loop as follows:
int i = 1;
while (i < 10) {
double x = (double) i;
System
...
println(x + "
i = i + 1;
}
" + Math
...
log(2));
Generating Tables
www
...
info
|
91
And here are the results:
1
...
0
3
...
0
5
...
0
7
...
0
9
...
0
1
...
5849625007211563
2
...
321928094887362
2
...
807354922057604
3
...
1699250014423126
Each time through the loop, we add one to x, so the result is an arithmetic sequence
...
log(2);
int i = 1;
while (i < 100) {
double x = (double) i;
System
...
println(x + "
" + Math
...
log(2) in a final variable to avoid computing that value
over and over again
...
The result is:
1
...
0
4
...
0
16
...
0
64
...
0
1
...
0
3
...
0
5
...
0
This table shows the powers of two and their logarithms, base 2
...
In this section we present another program development
process called “encapsulation and generalization”
...
Write a few lines of code in main or another method, and test them
...
When they are working, wrap them in a new method, and test again
...
If it’s appropriate, replace literal values with variables and parameters
...
92
|
Chapter 7: Loops
www
...
info
To demonstrate this process, we’ll develop methods that display multiplication tables
...
out
...
out
...
Each time through the loop, we display the value 2 * i padded with spaces so it’s
four characters wide
...
out
...
After the loop, we call println to print a newline and complete the line
...
The output of the code so far is:
2
4
6
8
10
12
The next step is to “encapsulate” this code in a new method
...
out
...
out
...
This step is called “gener‐
alization” because it makes the method more general (less specific)
...
out
...
out
...
With the
argument 3, the output is:
3
6
9
12
15
18
Encapsulation and Generalization
www
...
info
|
93
And with argument 4, the output is:
4
8
12
16
20
24
By now you can probably guess how we are going to display a multiplication table:
we’ll invoke printRow repeatedly with different arguments
...
int i = 1;
while (i <= 6) {
printRow(i);
i = i + 1;
}
And the output looks like this:
1
2
3
4
5
6
2
4
6
8
10
12
3
6
9
12
15
18
4
8
12
16
20
24
5
10
15
20
25
30
6
12
18
24
30
36
The format specifier %4d in printRow causes the output to align vertically, regardless
of whether the numbers are one or two digits
...
The process of encapsulation and generaliza‐
tion allows you to design as you go along
...
We can generalize it by
replacing the literal 6 with a parameter:
public static void printTable(int rows) {
int i = 1;
while (i <= rows) {
printRow(i);
i = i + 1;
}
}
94
|
Chapter 7: Loops
www
...
info
Here is the output with the argument 7:
1
2
3
4
5
6
7
2
4
6
8
10
12
14
3
6
9
12
15
18
21
4
8
12
16
20
24
28
5
10
15
20
25
30
35
6
12
18
24
30
36
42
That’s better, but it still has a problem: it always displays the same number of col‐
umns
...
out
...
out
...
Since we added a parameter to printRow,
we also have to change the line in printTable where it is invoked:
public static void printTable(int rows) {
int i = 1;
while (i <= rows) {
printRow(i, rows);
i = i + 1;
}
}
When this line executes, it evaluates rows and passes the value, which is 7 in this
example, as an argument
...
As a result, the
number of columns equals the number of rows, so we get a square 7x7 table:
1
2
3
4
5
6
7
2
4
6
8
10
12
14
3
6
9
12
15
18
21
4
8
12
16
20
24
28
5
10
15
20
25
30
35
6
12
18
24
30
36
42
7
14
21
28
35
42
49
When you generalize a method appropriately, you often find that it has capabilities
you did not plan
...
You could save ink by
printing half of the table, and you would only have to change one line of printTable:
printRow(i, i);
More Generalization
www
...
info
|
95
In words, the length of each row is the same as its row number
...
1
2
3
4
5
6
7
4
6
8
10
12
14
9
12
15
18
21
16
20
24
28
25
30
35
36
42
49
Generalization makes code more versatile, more likely to be reused, and sometimes
easier to write
...
They start by ini‐
tializing a variable, they have a condition that depends on that variable, and inside the
loop they do something to update that variable
...
For example, we could rewrite printTable like this:
public static void printTable(int rows) {
for (int i = 1; i <= rows; i = i + 1) {
printRow(i, rows);
}
}
for loops have three components in parentheses, separated by semicolons: the initial‐
izer, the condition, and the update
...
The initializer runs once at the very beginning of the loop
...
The condition is checked each time through the loop
...
Otherwise, the body of the loop is executed (again)
...
At the end of each iteration, the update runs, and we go back to step 2
...
There is one difference between for loops and while loops: if you declare a variable
in the initializer, it only exists inside the for loop
...
out
...
out
...
it-ebooks
...
If you need to use a loop variable outside the loop, you have to declare it out‐
side the loop, like this:
public static void printRow(int n, int cols) {
int i;
for (i = 1; i <= cols; i = i + 1) {
System
...
printf("%4d", n * i);
}
System
...
println(i);
}
Assignments like i = i + 1 don’t often appear in for loops, because Java provides a
more concise way to add and subtract by one
...
And -- is the decrement operator; it has the
same effect as i = i - 1
...
For example, i += 2 increments i by 2
...
Java also provides a posttest loop: the do-while statement
...
For example, in “Validating Input” on page 62 we used the return statement to avoid
reading invalid input from the user
...
in);
boolean okay;
do {
System
...
print("Enter a number: ");
if (in
...
next();
System
...
println(word + " is not a number");
}
} while (!okay);
double x = in
...
it-ebooks
...
Display a prompt
...
Check the input; if invalid, display an error and start over
...
Read the input
...
If hasNextDouble() returns false, we consume the invalid input by calling
next()
...
err
...
break and continue
Sometimes neither a pretest nor a posttest loop will provide exactly what you need
...
As a
result, we used a flag variable and a nested if-else statement
...
When a program
reaches a break statement, it exits the current loop
...
in);
while (true) {
System
...
print("Enter a number: ");
if (in
...
next();
System
...
println(word + " is not a number");
}
double x = in
...
”
In addition to the break statement, which exits the loop, Java provides a continue
statement that moves on to the next iteration
...
The continue statement
causes the program to skip over any negative values
...
in);
int x = -1;
int sum = 0;
while (x != 0) {
x = in
...
out
...
it-ebooks
...
Use them sparingly
...
loop:
A statement that executes a sequence of statements repeatedly
...
infinite loop:
A loop whose condition is always true
...
So far we have seen “incremental development”
and “encapsulation and generalization”
...
generalize:
To replace something unnecessarily specific (like a constant value) with some‐
thing appropriately general (like a variable or parameter)
...
increment:
Increase the value of a variable
...
pretest loop:
A loop that tests the condition before each iteration
...
Exercises
The code for this chapter is in the ch07 directory of ThinkJavaCode
...
Vocabulary
www
...
info
|
99
Before you start the exercises, we recommend that you compile and run the
examples
...
It describes Checkstyle, a tool that analyzes many aspects of your source code
...
Consider the following methods:
public static void main(String[] args) {
loop(10);
}
public static void loop(int n) {
int i = n;
while (i > 1) {
System
...
println(i);
if (i % 2 == 0) {
i = i / 2;
} else {
i = i + 1;
}
}
}
1
...
The table should contain one column for each variable and one line for
each iteration
...
What is the output of this program?
3
...
Let’s say you are given a number, a, and you want to find its square root
...
75, which is closer
...
In this case, x2 = 3
...
00091
...
100
| Chapter 7: Loops
www
...
info
Write a method called squareRoot that takes a double and returns an approximation
of the square root of the parameter, using this technique
...
sqrt
...
Your method should iterate until it gets two
consecutive estimates that differ by less than 0
...
You can use Math
...
Exercise 7-3
...
Now write an iterative method to perform the same calcula‐
tion
...
“More Recursion” on page 79 presents a recursive method that computes the factorial
function
...
Exercise 7-5
...
The ith term in the series is xi /i!
...
Write a method called myexp that takes x and n as parameters and estimates ex by
adding the first n terms of this series
...
2
...
Use this observation to eliminate the
use of Math
...
3
...
exp(x)
...
0
2
...
718281828459045
You can use the escape sequence "\t" to put a tab character between columns of
a table
...
it-ebooks
...
Vary the number of terms in the series (the second argument that check sends to
myexp) and see the effect on the accuracy of the result
...
5
...
1, 1
...
0, and 100
...
How does the accuracy of the result vary as x varies? Compare the number of
digits of agreement rather than the difference between the actual and estimated
values
...
Add a loop in main that checks myexp with the values -0
...
0, -10
...
0
...
Exercise 7-6
...
The ith term in this series is − 1 ix2i /i!
...
You should
not use factorial or pow
...
it-ebooks
...
In this chapter, we’ll learn how to store multiple values of the
same type using a single variable
...
Creating Arrays
An array is a sequence of values; the values in the array are called elements
...
To create an array, you have to declare a variable with an array type and then create
the array itself
...
For example, the following lines declare that counts is an “inte‐
ger array” and values is a “double array”:
int[] counts;
double[] values;
To create the array itself, you have to use the new operator, which we first saw in “The
Scanner Class” on page 30:
counts = new int[4];
values = new double[size];
The first assignment makes count refer to an array of four integers
...
103
www
...
info
Of course, you can also declare the variable and create the array in a single line of
code:
int[] counts = new int[4];
double[] values = new double[size];
You can use any integer expression for the size of an array, as long as the value is non‐
negative
...
An array with zero elements is allowed, and there are
special uses for such arrays that we’ll see later on
...
Figure 8-1
shows a state diagram of the counts array so far
...
State diagram of an int array
...
You should
think of the array and the variable that refers to it as two different things
...
The large numbers inside the boxes are the elements of the array
...
Notice that the index of the first element is 0, not 1, as you might have
expected
...
out
...
104
|
Chapter 8: Arrays
www
...
info
Figure 8-2
...
You can use any expression as an index, as long as it has type int
...
For example:
int i = 0;
while (i < 4) {
System
...
println(counts[i]);
i++;
}
This while loop counts from 0 up to 4
...
So the body of the loop is only executed when i is 0, 1, 2, and 3
...
This type of array processing is often written using a for loop
...
out
...
If the index is negative
or greater than 3, the result is an ArrayIndexOutOfBoundsException
...
For example, the following fragment (1) declares an array variable, (2) makes it
refer to an array of four elements, and (3) attempts to display the contents of the array
using println:
int[] a = {1, 2, 3, 4};
System
...
println(a);
Unfortunately, the output is something like:
[I@bf3f7e0
The bracket indicates that the value is an array, I stands for “integer”, and the rest rep‐
resents the address of the array
...
it-ebooks
...
out
...
length; i++) {
System
...
print(", " + a[i]);
}
System
...
println("}");
}
Given the previous array, the output of this method is:
{1, 2, 3, 4}
The Java library provides a utility class java
...
Arrays that provides methods for
working with arrays
...
We can invoke it like this:
System
...
println(Arrays
...
util
...
Notice that the
string format is slightly different: it uses square brackets instead of curly braces
...
Copying Arrays
As explained in “Accessing Elements” on page 104, array variables contain references
to arrays
...
But it doesn’t copy the array itself! For example:
double[] a = new double[3];
double[] b = a;
These statements create an array of three doubles and make two different variables
refer to it, as shown in Figure 8-3
...
State diagram showing two variables that refer to the same array
...
For example, if
we set a[0] = 17
...
0
...
If you actually want to copy the array, not just a reference, you have to create a new
array and copy the elements from the old to the new, like this:
106
|
Chapter 8: Arrays
www
...
info
double[] b = new double[3];
for (int i = 0; i < 3; i++) {
b[i] = a[i];
}
Another option is to use java
...
Arrays, which provides a method named copyOf
that copies an array
...
copyOf(a, 3);
The second parameter is the number of elements you want to copy, so you can also
use copyOf to copy just part of an array
...
It
would be better to generalize the code to work with arrays of any size
...
length:
double[] b = new double[a
...
length; i++) {
b[i] = a[i];
}
All arrays have a built-in constant, length, that stores the number of elements
...
length may look like a method invocation, but there are no parentheses
and no arguments
...
length - 1, which is the index of the last
element
...
length, the condition fails and the body is not exe‐
cuted—which is a good thing, because trying to access a[a
...
You can also use a
...
copyOf:
double[] b = Arrays
...
length);
Array Traversal
Many computations can be implemented by looping through the elements of an array
and performing an operation on each element
...
length; i++) {
a[i] = Math
...
0);
}
Looping through the elements of an array is called a traversal
...
Array Length
www
...
info
|
107
For example, the following method takes an int array and an integer value, and it
returns the index where the value appears:
public static int search(double[] a, double target) {
for (int i = 0; i < a
...
If the loop
exits without finding the target, it returns -1, a special value chosen to indicate a
failed search
...
Examples include the sum or product of the elements, the
minimum, and the maximum
...
0;
for (int i = 0; i < a
...
Each time through the loop, we update
total by adding one element from the array
...
A variable used this way is sometimes called an accumula‐
tor
...
Usually determinism is a good thing, since we expect the same cal‐
culation to yield the same result
...
Games are an obvious example, but there are many others
...
But there are algorithms that generate
unpredictable sequences called pseudorandom numbers
...
108
|
Chapter 8: Arrays
www
...
info
If you did Exercise 3-4, you have already seen java
...
Random, which generates
pseudorandom numbers
...
If you generate a long series of random numbers, every value should appear, at least
approximately, the same number of times
...
The following method creates an int array and fills it with random numbers between
0 and 99
...
public static int[] randomArray(int size) {
Random random = new Random();
int[] a = new int[size];
for (int i = 0; i < a
...
nextInt(100);
}
return a;
}
The following fragment generates an array and displays it using printArray from
“Displaying Arrays” on page 105:
int numValues = 8;
int[] array = randomArray(numValues);
printArray(array);
The output looks like this:
{15, 62, 46, 74, 67, 52, 51, 10}
If you run it, you will probably get different values
...
In statistics, a
histogram is a set of counters that keeps track of the number of times each value
appears
...
To do that, we can traverse the array and count the
number of elements that fall in a given range
...
It returns the
number of elements that fall in the range from low to high
...
it-ebooks
...
length; i++) {
if (a[i] >= low && a[i] < high) {
count++;
}
}
return count;
}
This pattern should look familiar: it is another reduce operation
...
This detail keeps us from count‐
ing any scores twice
...
But suppose we wanted to keep track of the number of times each score
appears
...
int
count0 = inRange(scores, 0, 1);
count1 = inRange(scores, 1, 2);
count2 = inRange(scores, 2, 3);
count99 = inRange(scores, 99, 100);
What we need is a way to store 100 counters, preferably so we can use an index to
access them
...
It loops through the scores and uses inRange to count how many times each score
appears
...
length; i++) {
counts[i] = inRange(scores, i, i + 1);
}
Notice that we are using the loop variable i three times: as an index into the counts
array, and as two arguments for inRange
...
Every time the loop invokes inRange, it traverses the entire array
...
it-ebooks
...
This code tra‐
verses the array of scores only once to generate the histogram:
int[] counts = new int[100];
for (int i = 0; i < scores
...
Because this code only tra‐
verses the array of scores once, it is much more efficient
...
For example, consider a for loop that displays the elements
of an array on separate lines:
for (int i = 0; i < values
...
out
...
out
...
You can read it as, “for each value in
values”
...
Using the enhanced for loop, and removing the temporary variable, we can write the
histogram code from the previous section more concisely:
int[] counts = new int[100];
for (int score : scores) {
counts[score]++;
}
Enhanced for loops often make the code more readable, especially for accumulating
values
...
The Enhanced for Loop
www
...
info
|
111
Vocabulary
array:
A collection of values, where all the values have the same type, and each value is
identified by an index
...
The [] operator selects elements
...
reference:
A value that indicates another value, like an array
...
alias:
A variable that refers to the same object as another variable
...
search:
A traversal pattern used to find a particular element of an array
...
accumulator:
A variable used to accumulate results during a traversal
...
nondeterministic:
A program that always behaves differently, even when run multiple times with
the same input
...
histogram:
An array of integers where each integer counts the number of values that fall into
a certain range
...
112
|
Chapter 8: Arrays
www
...
info
Exercises
The code for this chapter is in the ch08 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
The goal of this exercise is to practice encapsulation with some of the examples in this
chapter
...
Starting with the code in “Array Traversal” on page 107, write a method called
powArray that takes a double array, a, and returns a new array that contains the
elements of a squared
...
2
...
Generalize it to take the number of
counters as an argument
...
The purpose of this exercise is to practice reading code and recognizing the traversal
patterns in this chapter
...
public static int banana(int[] a) {
int kiwi = 1;
int i = 0;
while (i < a
...
length; i++) {
if (a[i] == grape) {
return i;
}
}
return -1;
}
Exercises
www
...
info
|
113
public static int pineapple(int[] a, int apple) {
int pear = 0;
for (int pine: a) {
if (pine == apple) {
pear++;
}
}
return pear;
}
For each method, write one sentence that describes what the method does, without
getting into the details of how it works
...
Exercise 8-3
...
Describe in a few words what mus does
...
length; i++) {
jub[i] *= 2;
}
}
public static int mus(int[] zoo) {
int fus = 0;
for (int i = 0; i < zoo
...
out
...
Write a method called indexOfMax that takes an array of integers and returns the
index of the largest element
...
it-ebooks
...
The Sieve of Eratosthenes is “a simple, ancient algorithm for finding all prime num‐
bers up to any given limit,” which you can read about at https://en
...
org/wiki/
Sieve_of_Eratosthenes
...
Exercise 8-6
...
Exercise 8-7
...
Exercise 8-8
...
It is not common, but it is a useful exercise
...
Write a method called maxInRange that takes an array of integers and two
indexes, lowIndex and highIndex, and finds the maximum value in the array, but
only considering the elements between lowIndex and highIndex, including both
...
If the length of the range is 1, that is, if lowIn
dex == highIndex, we know immediately that the sole element in the range must
be the maximum
...
If there is more than one element in the range, we can break the array into two
pieces, find the maximum in each of the pieces, and then find the maximum of
the maxima
...
Methods like maxInRange can be awkward to use
...
double max = maxInRange(a, 0, a
...
Exercises
www
...
info
|
115
www
...
info
CHAPTER 9
Strings and Things
In Java and other object-oriented languages, an object is a collection of data that pro‐
vides a set of methods
...
System
...
in are also objects
...
They contain characters and provide methods for manipulat‐
ing character data
...
Not everything in Java is an object: int, double, and boolean are so-called primitive
types
...
Characters
Strings provide a method named charAt, which extracts a character
...
String fruit = "banana";
char letter = fruit
...
Like array indexes, string
indexes start at 0, so the character assigned to letter is b
...
You can compare them
using relational operators:
if (letter == 'a') {
System
...
println('?');
}
117
www
...
info
Character literals, like 'a', appear in single quotes
...
Escape
sequences, like '\t', are legal because they represent a single character
...
So this loop displays
the letters of the alphabet:
System
...
print("Roman alphabet: ");
for (char c = 'A'; c <= 'Z'; c++) {
System
...
print(c);
}
System
...
println();
Java uses Unicode to represent characters, so strings can store text in other alphabets
like Cyrillic and Greek, and non-alphabetic languages like Chinese
...
org/
...
The code units for uppercase Greek letters run from 913 to 937, so we can
display the Greek alphabet like this:
System
...
print("Greek alphabet: ");
for (int i = 913; i <= 937; i++) {
System
...
print((char) i);
}
System
...
println();
This example uses a type cast to convert each integer (in the range) to the corre‐
sponding character
...
These methods are often a source of confusion, because it
sounds like they modify strings
...
When you invoke toUpperCase on a string, you get a new string object as a return
value
...
toUpperCase();
After these statements run, upperName refers to the string "ALAN TURING"
...
118
|
Chapter 9: Strings and Things
www
...
info
Another useful method is replace, which finds and replaces instances of one string
within another
...
replace("Computer Science", "CS");
This example demonstrates a common way to work with string methods
...
replace, which returns a reference to a new string, "CS is fun!"
...
This assignment is important; if you don’t save the return value, invoking
text
...
String Traversal
The following loop traverses the characters in fruit and displays them, one on each
line:
for (int i = 0; i < fruit
...
charAt(i);
System
...
println(letter);
}
Strings provide a method called length that returns the number of characters in the
string
...
The condition is i < fruit
...
Unfortunately, the enhanced for loop does not work with strings
...
toCharArray()) {
System
...
println(letter);
}
To find the last letter of a string, you might be tempted to try something like:
int length = fruit
...
charAt(length);
// wrong!
This code compiles and runs, but invoking the charAt method throws a StringIndex
OutOfBoundsException
...
Since we started counting at 0, the 6 letters are indexed from 0 to 5
...
int length = fruit
...
charAt(length - 1);
// correct
Many string traversals involve reading one string and creating another
...
it-ebooks
...
length() - 1; i >= 0; i--) {
r = r + s
...
The loop traverses the letters of
s in reverse order
...
When the loop exits, r contains the letters from s in reverse order
...
Substrings
The substring method returns a new string that copies letters from an existing
string, starting at the given index
...
substring(0) returns "banana"
• fruit
...
substring(6) returns ""
The first example returns a copy of the entire string
...
As the last example shows, substring returns the empty
string if the argument is the length of the string
...
Figure 9-1
...
Like most string methods, substring is overloaded
...
If it’s invoked with two arguments, they
are treated as a start and end index:
• fruit
...
substring(2, 5) returns "nan"
• fruit
...
it-ebooks
...
Defining sub
string this way simplifies some common operations
...
substring(i, i +
len)
...
String fruit = "banana";
int index = fruit
...
But the letter appears three times,
so it’s not obvious what indexOf should do
...
To find subsequent appearances, you can use another version of indexOf, which takes
a second argument that indicates where in the string to start looking
...
indexOf('a', 2);
This code starts at index 2 (the first 'n') and finds the next 'a', which is at index 3
...
So
fruit
...
If the character does not appear in the string, indexOf returns -1
...
You can also use indexOf to search for a substring, not just a single character
...
indexOf("nan") returns 2
...
String name1 = "Alan Turing";
String name2 = "Ada Lovelace";
if (name1 == name2) {
// wrong!
System
...
println("The names are the same
...
But it is
not correct, and sometimes it gets the answer wrong
...
If you give it two different strings that contain the same letters, it yields
false
...
it-ebooks
...
equals(name2)) {
System
...
println("The names are the same
...
The equals
method returns true if the strings contain the same characters; otherwise it returns
false
...
compareTo(name2);
if (diff == 0) {
System
...
println("The names are the same
...
out
...
");
} else if (diff > 0) {
System
...
println("name2 comes before name1
...
If the strings are equal, their difference is zero
...
Otherwise, the difference is positive
...
Both equals and compareTo are case-sensitive
...
String Formatting
In “Formatting Output” on page 33, we learned how to use printf to display format‐
ted output
...
For example, the following method
returns a time string in 12-hour format:
public static String timeString(int hour, int minute) {
String ampm;
if (hour < 12) {
ampm = "AM";
if (hour == 0) {
hour = 12; // midnight
}
} else {
ampm = "PM";
hour = hour - 12;
}
return String
...
it-ebooks
...
format takes the same arguments as System
...
printf: a format specifier
followed by a sequence of values
...
out
...
format creates a new string, but does not dis‐
play anything
...
Wrapper Classes
Primitive values (like ints, doubles, and chars) do not provide methods
...
out
...
equals(5));
// compiler error
But for each primitive type, there is a corresponding class in the Java library, called a
wrapper class
...
Other wrapper classes include Boolean, Long, and Double
...
lang package, so you can use them without importing them
...
For example,
Integer
...
MAX_VALUE is 2147483647
...
Wrapper classes provide methods for converting strings to other types
...
parseInt converts a string to (you guessed it) an integer:
String str = "12345";
int num = Integer
...
The other wrapper classes provide similar methods, like Double
...
parseBoolean
...
toString(num);
The result is the string "12345"
...
If you are unfamiliar with
Wrapper Classes
www
...
info
|
123
the command-line interface, please read or review “Command-Line Interface” on
page 203
...
Rather than read the numbers from System
...
Here is a starting point:
public class Max {
public static void main(String[] args) {
System
...
println(Arrays
...
For example, if you run it like this:
java Max 10 -3 55 0 14
The output is:
[10, -3, 55, 0, 14]
But remember that the elements of args are strings
...
The following fragment uses an enhanced for loop to parse the arguments (using the
Integer wrapper class) and find the largest value:
int max = Integer
...
parseInt(arg);
if (value > max) {
max = value;
}
}
System
...
println("The max is " + max);
The initial value of max is the smallest (most negative) number an int can represent,
so any other value is greater
...
124
|
Chapter 9: Strings and Things
www
...
info
Vocabulary
object:
A collection of related data that comes with a set of methods that operate on it
...
Unicode:
A standard for representing characters in most of the world’s languages
...
Strings are immutable by
design
...
wrapper class:
Classes in java
...
parse:
To read a string and interpret or translate it
...
Exercises
The code for this chapter is in the ch09 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
The point of this exercise is to explore Java types and fill in some of the details that
aren’t covered in the chapter
...
Create a new program named Test
...
For example, what
happens when you “add” a String and a char? Does it perform character addi‐
tion or string concatenation? What is the type of the result? (How can you deter‐
mine the type of the result?)
Vocabulary
www
...
info
|
125
2
...
At the intersection of each
pair of types, you should indicate whether it is legal to use the + operator with
these types, what operation is performed (addition or concatenation), and what
the type of the result is
...
Think about some of the choices the designers of Java made when they filled in
this table
...
Here’s a puzzler: normally, the statement x++ is exactly equivalent to x = x + 1
...
Try it out and see what the error message is, then see if you can
figure out what is going on
...
What happens when you add "" (the empty string) to the other types, for exam‐
ple, "" + 5?
6
...
Exercise 9-2
...
The zeroth element of the histogram should
contain the number of a’s in the string (upper- and lowercase); the 25th element
should contain the number of z’s
...
Exercise 9-3
...
The following code fragment traver‐
ses a string and checks whether it has the same number of open and close parenthe‐
ses:
126
|
Chapter 9: Strings and Things
www
...
info
String s = "((3 + 7) * 2)";
int count = 0;
for (int i = 0; i < s
...
charAt(i);
if (c == '(') {
count++;
} else if (c == ')') {
count--;
}
}
System
...
println(count);
1
...
2
...
Test your method with multiple strings, including some that are balanced and
some that are not
...
Create a program called Recurse
...
*/
public static char first(String s) {
return s
...
*/
public static String rest(String s) {
return s
...
*/
public static String middle(String s) {
return s
...
length() - 1);
}
/**
* Returns the length of the given String
...
length();
}
Exercises
www
...
info
|
127
1
...
Make sure they work,
and you understand what they do
...
Using these methods, and without using any other String methods, write a
method called printString that takes a string as a parameter and that displays
the letters of the string, one on each line
...
3
...
4
...
The new string should contain the
same letters as the parameter, but in reverse order
...
out
...
A palindrome is a word that reads the same both forward and backward, like
“otto” and “palindromeemordnilap”
...
Write a recursive method named isPalindrome that takes a String and returns a
boolean indicating whether the word is a palindrome
...
A word is said to be “abecedarian” if the letters in the word appear in alphabetical
order
...
Your method can be iterative or recur‐
sive
...
it-ebooks
...
A word is said to be a “doubloon” if every letter that appears in the word appears
exactly twice
...
To ignore case, invoke the toLowerCase method before checking
...
Two words are anagrams if they contain the same letters and the same number of
each letter
...
Write a method that takes two strings and checks whether they are anagrams of each
other
...
In Scrabble1 each player has a set of tiles with letters on them
...
The scoring system is complex, but longer words
are usually worth more than shorter words
...
Write a method called canSpell that takes two strings and checks whether the set of
tiles can spell the word
...
1 Scrabble is a registered trademark owned in the USA and Canada by Hasbro Inc
...
W
...
Exercises
www
...
info
|
129
www
...
info
CHAPTER 10
Objects
As we learned in the previous chapter, an object is a collection of data that provides a
set of methods
...
Java is an “object-oriented” language, which means that it uses objects to represent
data and provide methods related to them
...
In this chapter, we introduce two new types of objects: Point and Rectangle
...
We also take a look at the source code for the Java library
...
awt package provides a class named Point intended to represent the coor‐
dinates of a location in a Cartesian plane
...
For example, 0, 0
indicates the origin, and x, y indicates the point x units to the right and y units up
from the origin
...
awt
...
it-ebooks
...
The second line creates the new
Point with the given arguments as coordinates
...
So blank contains a
reference to the new Point object
...
Figure 10-1
...
As usual, the name of the variable blank appears outside the box, and its value
appears inside the box
...
The arrow points to the new object, which contains two variables, x and y
...
To access an attribute of an object, Java uses dot notation
...
x;
The expression blank
...
” In this case, we assign that value to a local variable named x
...
The pur‐
pose of dot notation is to identify which variable you are referring to unambiguously
...
For example:
System
...
println(blank
...
y);
int sum = blank
...
x + blank
...
y;
The first line displays 3, 4; the second line calculates the value 25
...
it-ebooks
...
For example:
public static void printPoint(Point p) {
System
...
println("(" + p
...
y + ")");
}
This method takes a point as an argument and displays its attributes in parentheses
...
But we don’t really need a method like printPoint, because if you invoke Sys
tem
...
println(blank) you get:
java
...
Point[x=3,y=4]
Point objects provide a method called toString that returns a string representation
of a point
...
In this case, it shows the name of the type (java
...
Point) and
the names and values of the attributes
...
public static double distance(Point p1, Point p2) {
int dx = p2
...
x;
int dy = p2
...
y;
return Math
...
Objects as Return Types
The java
...
To use it, you have to
import it:
import java
...
Rectangle;
Rectangle objects are similar to points, but they have four attributes: x, y, width, and
height
...
Objects as Parameters
www
...
info
|
133
Figure 10-2
...
If you run System
...
println(box), you get:
java
...
Rectangle[x=0,y=0,width=100,height=200]
Again, println uses the toString method provided by Rectangle, which knows how
to display Rectangle objects
...
For example, findCenter takes a
Rectangle as an argument and returns a Point with the coordinates of the center of
the rectangle:
public static Point findCenter(Rectangle box) {
int x = box
...
width / 2;
int y = box
...
height / 2;
return new Point(x, y);
}
The return type of this method is Point
...
Mutable Objects
You can change the contents of an object by making an assignment to one of its
attributes
...
x = box
...
y = box
...
134
|
Chapter 10: Objects
www
...
info
Figure 10-3
...
We can encapsulate this code in a method and generalize it to move the rectangle by
any amount:
public static void moveRect(Rectangle box, int dx, int dy) {
box
...
x + dx;
box
...
y + dy;
}
The variables dx and dy indicate how far to move the rectangle in each direction
...
Rectangle box = new Rectangle(0, 0, 100, 200);
moveRect(box, 50, 100);
System
...
println(box);
Modifying objects by passing them as arguments to methods can be useful
...
Java provides a number of methods that operate on Points and Rectangles
...
translate(50, 100);
This line invokes the translate method for the object that box refers to
...
This example is a good illustration of object-oriented programming
...
Mutable Objects
www
...
info
|
135
Aliasing
Remember that when you assign an object to a variable, you are assigning a reference
to an object
...
The
state diagram in Figure 10-4 shows the result
...
State diagram showing two variables that refer to the same object
...
This example adds 50 to all four sides of the rectan‐
gle, so it moves the corner up and to the left by 50, and it increases the height and
width by 100:
System
...
println(box2
...
grow(50, 50);
System
...
println(box2
...
The second line invokes the grow method on box1, which stretches the Rectangle
horizontally and vertically
...
Figure 10-5
...
When we make a change using box1, we see the change using box2
...
136
|
Chapter 10: Objects
www
...
info
The null Keyword
When you create an object variable, remember that you are storing a reference to an
object
...
You can
declare and initialize object variables this way:
Point blank = null;
The value null is represented in state diagrams by a small box with no arrow, as in
Figure 10-6
...
State diagram showing a variable that contains a null reference
...
Point blank = null;
int x = blank
...
translate(50, 50);
// NullPointerException
// NullPointerException
On the other hand, it is legal to pass a null reference as an argument or receive one as
a return value
...
Garbage Collection
In “Aliasing” on page 136, we saw what happens when more than one variable refers
to the same object
...
The second line
changes blank so that instead of referring to the object, it refers to nothing
...
If there are no references to an object, there is no way to access its attributes or invoke
a method on it
...
However it’s still
present in the computer’s memory, taking up space
...
it-ebooks
...
State diagram showing the effect of setting a variable to null
...
This process is called
garbage collection
...
But in high-performance applications, you may notice a
slight delay every now and then when Java reclaims space from discarded objects
...
Attributes are an object’s data, and methods are an
object’s code
...
In practice, it’s more convenient to look at high-level pictures than to examine the
source code
...
As shown in Figure 10-8, a class diagram is divided into two sections
...
UML uses a languageindependent format, so rather than showing int x, the diagram uses x: int
...
UML class diagrams for Point and Rectangle
...
it-ebooks
...
Both Point and Rectangle have additional methods; we are only showing the ones
introduced in this chapter
...
Java Library Source
Throughout the book, you have used classes from the Java library including System,
String, Scanner, Math, Random, and others
...
In fact, you can take a look at the source code to see how
they work
...
That’s more than one person could read and understand fully, so please don’t be
intimidated!
Because it’s so large, the library source code is stored in a file named src
...
Take a
few minutes to locate this file on your machine:
• On Linux, it’s likely under: /usr/lib/jvm/openjdk-8/ (You might need to install
the openjdk-8-source package
...
/
Contents/Home/
• On Windows, it’s likely under: C:\Program Files\Java\jdk
...
For example, open the java folder and then open the awt folder
...
java and Rectangle
...
awt package
...
java in your editor and skim through the file
...
But you can
get a sense of what professional Java software looks like by browsing through the
library
...
java is documentation
...
Javadoc reads these com‐
ments and generates documentation in HTML
...
Java Library Source
www
...
info
|
139
Now take a look at Rectangle’s grow and translate methods
...
To summarize the whole chapter, objects encapsulate data and provide methods to
access and modify the data directly
...
Vocabulary
attribute:
One of the named data items that make up an object
...
) to access an object’s attributes or methods
...
garbage collection:
The process of finding objects that have no references and reclaiming their stor‐
age space
...
class diagram:
An illustration of the attributes and methods for a class
...
See “Using the
Code Examples” on page xi for instructions on how to download the repository
...
140
|
Chapter 10: Objects
www
...
info
Exercise 10-1
...
1
...
Use arrows to show
which objects each variable references
...
What is the output of the program?
3
...
x + p
...
out
...
out
...
out
...
x);
System
...
println(blank
...
The point of this exercise is to make sure you understand the mechanism for return‐
ing new objects from methods
...
Draw a stack diagram showing the state of the program just before distance
returns
...
2
...
x - p1
...
y - p1
...
sqrt(dx * dx + dy * dy);
}
public static Point findCenter(Rectangle box) {
int x = box
...
width / 2;
int y = box
...
height / 2;
return new Point(x, y);
}
Exercises
www
...
info
|
141
public static void main(String[] args) {
Point blank = new Point(5, 8);
Rectangle rect = new Rectangle(0, 2, 4, 4);
Point center = findCenter(rect);
double dist = distance(center, blank);
System
...
println(dist);
}
Exercise 10-3
...
Recall that aliases are two variables that refer to the
same object
...
Draw a diagram that shows the state of the program just before the end of main
...
2
...
At the end of main, are p1 and p2 aliased? Why or why not?
public static void printPoint(Point p) {
System
...
println("(" + p
...
y + ")");
}
public static Point findCenter(Rectangle box) {
int x = box
...
width / 2;
int y = box
...
height / 2;
return new Point(x, y);
}
public static void main(String[] args) {
Rectangle box1 = new Rectangle(2, 4, 7, 9);
Point p1 = findCenter(box1);
printPoint(p1);
box1
...
it-ebooks
...
You might be sick of the factorial method by now, but we’re going to do one more
version
...
Create a new program called Big
...
2
...
At some
point around 15, you will probably see that the answers are not right anymore
...
BigInteger is a Java class that can represent arbitrarily big integers
...
Take a
minute to read the documentation, which you can find by doing a web search for
“Java BigInteger”
...
To use BigIntegers, you have to import java
...
BigInteger at the beginning
of your program
...
There are several ways to create a BigInteger, but the simplest uses valueOf
...
valueOf(x);
6
...
Instead, we have to use methods like add
...
BigInteger small = BigInteger
...
valueOf(1700000000);
BigInteger total = small
...
7
...
You can leave the parameter alone; it will still be
an integer
...
Try displaying the table again with your modified factorial method
...
Are BigInteger objects mutable or immutable? How can you tell?
Exercises
www
...
info
|
143
Exercise 10-5
...
Here is a method that implements an efficient algorithm for integer exponentiation:
public static int pow(int x, int n) {
if (n == 0) return 1;
// find x to the n/2 recursively
int t = pow(x, n / 2);
// if n is even, the result is t squared
// if n is odd, the result is t squared times x
if (n % 2 == 0) {
return t * t;
} else {
return t * t * x;
}
}
The problem with this method is that it only works if the result is small enough to be
represented by an int
...
The parameters
should still be integers, though
...
But don’t use
BigInteger
...
144
|
Chapter 10: Objects
www
...
info
CHAPTER 11
Classes
Whenever you define a new class, you also create a new type with the same name
...
We didn’t declare any variables with type Hello, and
we didn’t use new to create a Hello object
...
We will also
clarify the difference between classes and objects
...
• Every object belongs to some object type; that is, it is an instance of some class
...
• Think of a class like a blueprint for a house: you can use the same blueprint to
build any number of houses
...
The Time Class
One common reason to define a new class is to encapsulate related data in an object
that can be treated as a single unit
...
This design princi‐
ple is called data encapsulation
...
it-ebooks
...
Another example, which we will implement ourselves, is Time, which rep‐
resents a time of day
...
Because every Time object contains these data, we define
attributes to hold them
...
The first step is to decide what type each variable should be
...
Just to keep things interesting, let’s make second a
double
...
By itself, this code fragment is a legal class definition:
public class Time {
private int hour;
private int minute;
private double second;
}
The Time class is public, which means that it can be used in other classes
...
If you try to read or write them from another class, you will get a com‐
piler error
...
It also simplifies what other pro‐
grammers need to understand in order to use your classes
...
Constructors
After declaring the instance variables, the next step is to define a constructor, which
is a special method that initializes the instance variables
...
• Constructors have no return type (and no return value)
...
146
| Chapter 11: Classes
www
...
info
Here is an example constructor for the Time class:
public Time() {
this
...
minute = 0;
this
...
0;
}
This constructor does not take any arguments
...
The name this is a keyword that refers to the object we are creating
...
For example, you can read
and write the instance variables of this, and you can pass this as an argument to
other methods
...
A common error when writing constructors is to put a return statement at the end
...
To create a Time object, you must use the new operator:
Time time = new Time();
When you invoke new, Java creates the object and calls your constructor to initialize
the instance variables
...
In this example, the reference gets assigned to the variable time, which
has type Time
...
Figure 11-1
...
Constructors
www
...
info
|
147
Beginners sometimes make the mistake of invoking new inside the constructor
...
In this example, invoking new Time() in the con‐
structor causes an infinite recursion:
public Time() {
new Time();
// wrong!
this
...
minute = 0;
this
...
0;
}
More Constructors
Like other methods, constructors can be overloaded, which means you can provide
multiple constructors with different parameters
...
It is common to provide a constructor that takes no arguments, like the previous one,
and a “value constructor”, like this one:
public Time(int
this
...
minute
this
...
In this example, the names and types of the parameters are the same as the instance
variables
...
Parameters don’t have to use the same
names, but that’s a common style
...
This example creates a Time object that represents a fraction of a second before
noon:
Time time = new Time(11, 59, 59
...
Once you get the hang of it, writing constructors gets boring
...
In fact, some IDEs can gener‐
ate them for you
...
it-ebooks
...
hour = 0;
this
...
second = 0
...
hour =
this
...
second
}
hour, int minute, double second) {
hour;
= minute;
= second;
}
Getters and Setters
Recall that the instance variables of Time are private
...
For example, here’s a new class called TimeClient, because a class that uses objects
defined in another class is called a client:
public class TimeClient {
public static void main(String[] args) {
Time time = new Time(11, 59, 59
...
out
...
hour);
// compiler error
}
}
If you try to compile this code, you will get a message like hour has private access
in Time
...
• We could provide methods to access the instance variables
...
The first choice is appealing because it’s simple
...
If
anything in B changes later, it is likely that A will have to change, too
...
it-ebooks
...
So if we decide that TimeClient should be able to read the instance variables of Time,
we can provide methods to do it:
public int getHour() {
return this
...
minute;
}
public int getSecond() {
return this
...
By convention, the method that gets a variable named something is called
getSomething
...
hour = hour;
}
public void setMinute(int minute) {
this
...
second = second;
}
These methods are formally called “mutators”, but more commonly known as setters
...
Writing getters and setters can get boring, but many IDEs can generate them for you
based on the instance variables
...
it-ebooks
...
9);
System
...
println(time);
}
The output will look something like:
Time@80cc7c0
When Java displays the value of an object type, it displays the name of the type and
the address of the object (in hexadecimal)
...
To display Time objects in a way that is more meaningful to users, you could write a
method to display the hour, minute, and second
...
out
...
hour);
System
...
print(":");
System
...
println(t
...
out
...
out
...
second);
}
The output of this method, given the time object from the previous section, would be
11:59:59
...
We can use printf to write it more concisely:
public static void printTime(Time t) {
System
...
printf("%02d:%02d:%04
...
hour, t
...
second);
}
As a reminder, you need to use %d with integers and %f with floating-point numbers
...
1
option means “total width 4, one digit after the decimal point, leading zeros if neces‐
sary”
...
When you display an object using print or println, Java invokes the
object’s toString method
...
it-ebooks
...
For example, here is a
toString method for Time:
public String toString() {
return String
...
1f\n",
this
...
minute, this
...
It
is an instance method, so called because when you invoke it, you invoke it on an
instance of the class (Time in this case)
...
The body of the method is similar to printTime in the previous section, with two
changes:
• Inside the method, we use this to refer to the current instance; that is, the object
the method is invoked on
...
format, which returns a formatted String
rather than displaying it
...
9);
String s = time
...
out
...
The output is
11:59:59
...
The equals Method
We have seen two ways to check whether values are equal: the == operator and the
equals method
...
• The == operator checks whether objects are identical; that is, whether they are
the same object
...
The definition of identity is always the same, so the == operator always does the same
thing
...
152
|
Chapter 11: Classes
www
...
info
Consider the following variables:
Time time1 = new Time(9, 30, 0
...
0);
Figure 11-2 is a state diagram that shows these variables and their values
...
State diagram of three Time variables
...
Because they are identical, time1 == time2 is true
...
Because they are not identical, time1
== time3 is false
...
For Time objects, that’s
probably not what we want
...
We can provide an equals method that implements this notion of equivalence:
public boolean equals(Time that) {
return this
...
hour
&& this
...
minute
&& this
...
second;
}
equals is an instance method, so it uses this to refer to the current object and it
doesn’t have the keyword static
...
equals(time3);
Inside the equals method, this refers to the same object as time1, and that refers to
the same object as time3
...
Many objects use a similar notion of equivalence; that is, two objects are equivalent if
their instance variables are equal
...
The equals Method
www
...
info
|
153
Adding Times
Suppose you are going to a movie that starts at 18:50 (or 6:50 PM), and the running
time is 2 hours 16 minutes
...
Here are two ways we could “add” Time objects:
• We could write a static method that takes the two Time objects as parameters
...
To demonstrate the difference, we’ll do both
...
hour = t1
...
hour;
sum
...
minute + t2
...
second = t1
...
second;
return sum;
}
And here’s how we would invoke the static method:
Time startTime = new Time(18, 50, 0
...
0);
Time endTime = Time
...
hour = this
...
hour;
sum
...
minute + t2
...
second = this
...
second;
return sum;
}
The changes are:
• We removed the keyword static
...
• We replaced t1 with this
...
Unlike this, that is not a keyword; it’s
just a slightly clever variable name
...
add(runningTime);
154
|
Chapter 11: Classes
www
...
info
That’s all there is to it
...
There’s only one problem: the addition code itself is not correct
...
If second exceeds 59, we have to “carry” into
the minutes column, and if minute exceeds 59, we have to carry into hour
...
hour = this
...
hour;
sum
...
minute + t2
...
second = this
...
second;
if (sum
...
0) {
sum
...
0;
sum
...
minute >= 60) {
sum
...
hour += 1;
}
return sum;
}
It’s still possible that hour may exceed 23, but there’s no days attribute to carry into
...
hour -= 24 would yield the correct result
...
Instead, it cre‐
ates and returns a new Time object
...
second += seconds;
while (this
...
0) {
this
...
0;
this
...
minute >= 60) {
this
...
hour += 1;
}
}
The increment method modifies an existing Time object
...
In contrast, methods like add are called pure because:
Pure Methods and Modifiers
www
...
info
|
155
• They don’t modify the parameters
...
• The return value only depends on the parameters, not on any other state
...
They are usually void methods, but sometimes they return a reference to the object
they modify
...
But they can
also be error-prone
...
To make a class immutable, like String, you can provide getters but no setters and
pure methods but no modifiers
...
Vocabulary
class:
Previously, we defined a class as a collection of related methods
...
instance:
A member of a class
...
data encapsulation:
A technique for bundling multiple named variables into a single object
...
information hiding:
The practice of making instance variables private to limit dependencies between
classes
...
shadowing:
Defining a local variable or parameter with the same name and type as an
instance variable
...
156
|
Chapter 11: Classes
www
...
info
getter:
A method that returns the value of an instance variable
...
override:
Replacing a default implementation of a method, such as toString
...
identical:
Two values that are the same; in the case of objects, two variables that refer to the
same object
...
pure method:
A static method that depends only on its parameters and no other data
...
Exercises
The code for this chapter is in the ch11 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
During the next few chapters, you should take a detour to read
this appendix and work through the exercises
...
Review the documentation of java
...
Rectangle
...
lang
...
Exercises
www
...
info
|
157
Exercise 11-2
...
Can you
rewrite it so it doesn’t use any loops? Hint: Remember the modulus operator
...
In the board game Scrabble, each tile contains a letter, which is used to spell words in
rows and columns, and a score, which is used to determine the value of words
...
Write a definition for a class named Tile that represents Scrabble tiles
...
2
...
3
...
4
...
5
...
6
...
The point of this exercise is to practice the mechanical part of creating a new class
definition and code that tests it
...
Write a class definition for Date, an object type that contains three integers: year,
month, and day
...
The first should take no
parameters and initialize a default date
...
Write a main method that creates a new Date object named birthday
...
You can use either constructor
...
A rational number is a number that can be represented as the ratio of two integers
...
158
|
Chapter 11: Classes
www
...
info
1
...
A Rational object should have two integer
instance variables that store the numerator and denominator
...
Write a constructor that takes no arguments and that sets the numerator to 0 and
denominator to 1
...
Write an instance method called printRational that displays a Rational in
some reasonable format
...
Write a main method that creates a new object with type Rational, sets its
instance variables to some values, and displays the object
...
At this stage, you have a minimal testable program
...
6
...
7
...
8
...
This method should be a modifier, so it should be void
...
9
...
It should be a modifier
...
10
...
This method is a pure
method; it does not modify the object
...
11
...
This method should be a pure method;
it should not modify the instance variables of the object on which it is invoked
...
Search the web for “Eucli‐
dean algorithm”
...
Write an instance method called add that takes a Rational number as an argu‐
ment, adds it to this, and returns a new Rational object
...
You can use any one you want, but you
should make sure that the result of the operation is reduced so that the numera‐
tor and denominator have no common divisor (other than 1)
...
Exercises
www
...
info
|
159
www
...
info
CHAPTER 12
Arrays of Objects
In the remaining chapters, we will develop programs that work with playing cards
and decks of cards
...
• In “The Deck Class” on page 175, we create a Deck class that encapsulates an
array of cards, and we write methods that operate on decks
...
We then use all these classes to implement the card game
Crazy Eights
...
java, which is in the directory ch12 in the repos‐
itory for this book
...
Card Objects
If you are unfamiliar with traditional playing cards, now would be a good time to get
a deck or read through https://en
...
org/wiki/Standard_52-card_deck
...
Each card belongs to one of four suits and one
of 13 ranks
...
The ranks are Ace, 2,
3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, and King
...
It is not as obvious what types they
should be
...
it-ebooks
...
A problem with this design is that it would not be easy to compare
cards to see which had a higher rank or suit
...
By “encode” we don’t
mean to encrypt or translate into a secret code
...
”
Here is a mapping for suits:
↦
Diamonds ↦
Hearts
↦
Spades
↦
Clubs
0
1
2
3
We use the mathematical symbol ↦ to make it clear that these mappings are not part
of the program
...
Each of the numerical ranks (2 through 10) maps to the corresponding integer, and
for face cards:
↦
↦
Queen ↦
King ↦
Ace
1
Jack
11
12
13
So far, the class definition for the Card type looks like this:
public class Card {
private int rank;
private int suit;
public Card(int rank, int suit) {
this
...
suit = suit;
}
}
The instance variables are private: we can access them from inside this class, but not
from other classes
...
To create a Card object,
we use the new operator:
Card threeOfClubs = new Card(3, 0);
The result is a reference to a Card that represents the 3 of Clubs
...
it-ebooks
...
A good next step is to write toString, which is useful for debug‐
ging and incremental development
...
A natural way to do that is with an array of Strings
...
Each element of the array is a ref‐
erence to a String
...
State diagram of an array of strings
...
We
set it to null to indicate an unused element
...
String s = ranks[card
...
suit];
The expression suits[card
...
”
Card toString
www
...
info
|
163
Now we can wrap all that in a toString method
...
rank] + " of " + suits[this
...
out
...
Class Variables
So far we have seen local variables, which are declared inside a method, and instance
variables, which are declared in a class definition, usually before the method defini‐
tions
...
Instance variables are created when you construct an object
and reclaimed when the object is garbage-collected
...
Like instance variables, class variables are
defined in a class definition, before the method definitions
...
They are created when the program begins (or when the class is
used for the first time) and survive until the program ends
...
public class Card {
public static final String[] RANKS = {
null, "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"};
public static final String[] SUITS = {
"Clubs", "Diamonds", "Hearts", "Spades"};
// instance variables and constructors go here
public String toString() {
return RANKS[this
...
suit];
}
}
164
|
Chapter 12: Arrays of Objects
www
...
info
Class variables are often used to store constant values that are needed in several
places
...
Note that whether a variable
is static or final involves two separate considerations: static means the variable is
shared, and final means the variable is constant
...
Inside toString we can refer to
SUITS and RANKS as if they were local variables, but we can tell that they are class vari‐
ables
...
They may also be
needed in other methods and classes, so it’s helpful to make them available every‐
where
...
The compareTo Method
As we saw in “The equals Method” on page 152, it’s helpful to create an equals
method to test whether two objects are equivalent
...
rank == that
...
suit == that
...
For primitive types, we can use the comparison opera‐
tors—<, >, etc
...
But these operators don’t work for object types
...
Like the equals method, we can write our own version of compareTo for
the classes that we define
...
Integers and strings are totally ordered
...
In Java, the boolean type is unordered; if you try
to compare true < false, you get a compiler error
...
For example, we know that the 3 of Clubs is
higher than the 2 of Clubs, and the 3 of Diamonds is higher than the 3 of Clubs
...
The compareTo Method
www
...
info
|
165
To make cards comparable, we have to decide which is more important: rank or suit
...
But when you
buy a new deck of cards, it comes sorted with all the Clubs together, followed by all
the Diamonds, and so on
...
With that decided, we can write compareTo as follows:
public int compareTo(Card that) {
if (this
...
suit) {
return -1;
}
if (this
...
suit) {
return 1;
}
if (this
...
rank) {
return -1;
}
if (this
...
rank) {
return 1;
}
return 0;
}
compareTo returns 1 if this wins, -1 if that wins, and 0 if they are equivalent
...
If the suits are the same, it compares ranks
...
Cards Are Immutable
The instance variables of Card are private, so they can’t be accessed from other
classes
...
rank;
}
public int getSuit() {
return this
...
If we did, cards would be
mutable, so you could transform one card into another
...
So it might be better
to make cards immutable
...
166
|
Chapter 12: Arrays of Objects
www
...
info
That’s easy enough, but it is not foolproof, because some fool might come along later
and add a modifier
...
}
You can still assign values to these variables inside a constructor
...
Arrays of Cards
Just as you can create an array of String objects, you can create an array of Card
objects
...
Figure 12-2
...
Although we call it an “array of cards”, the array contains references to objects; it does
not contain the Card objects themselves
...
You can
access the elements of the array in the usual way:
if (cards[0] == null) {
System
...
println("No card yet!");
}
But if you try to access the instance variables of the non-existent Cards, you will get a
NullPointerException
...
rank
// NullPointerException
That code won’t work until we put cards in the array
...
it-ebooks
...
For each suit, the inner loop iterates ranks
from 1 to 13
...
We use a separate variable index to keep track of where in the array the next card
should go
...
Figure 12-3
...
When you work with arrays, it is convenient to have a method that displays the con‐
tents
...
length; i++) {
System
...
println(cards[i]);
}
}
Since cards has type Card[], an element of cards has type Card
...
This method is similar to invoking
System
...
println(Arrays
...
168
|
Chapter 12: Arrays of Objects
www
...
info
Sequential Search
The next method we’ll write is search, which takes an array of cards and a Card
object as parameters
...
This version of search uses the algorithm we saw in “Array Traversal” on
page 107, which is called sequential search:
public static int search(Card[] cards, Card target) {
for (int i = 0; i < cards
...
equals(target)) {
return i;
}
}
return -1;
}
The method returns as soon as it discovers the card, which means we don’t have to
traverse the entire array if we find the target
...
Notice that this algorithm depends on the equals method
...
We have to look at every card, because otherwise we can’t be certain the
card we want is not there
...
We will learn in the next chapter how to sort arrays
...
Especially for large arrays, sequential
search is rather inefficient
...
Since the words are in alphabetical order, you probably use a binary
search algorithm:
1
...
2
...
If you find it, stop
...
If the word on the page comes before the word you are looking for, flip to some‐
where later in the dictionary and go to step 2
...
If the word on the page comes after the word you are looking for, flip to some‐
where earlier in the dictionary and go to step 2
...
Getting back to the array of cards, we can write a faster version of search if we know
the cards are in order:
Sequential Search
www
...
info
|
169
public static int binarySearch(Card[] cards, Card target) {
int low = 0;
int high = cards
...
compareTo(target);
if (comp == 0) {
return mid;
} else if (comp < 0) {
low = mid + 1;
} else {
high = mid - 1;
}
// step 2
// step 3
// step 4
}
return -1;
}
First, we declare low and high variables to represent the range we are searching
...
Inside the while loop, we repeat the four steps of binary search:
1
...
2
...
3
...
4
...
If low exceeds high, there are no cards in the range, so we break out of the loop and
return -1
...
Tracing the Code
To see how binary search works, it’s helpful to add the following print statement at
the beginning of the loop:
System
...
println(low + ", " + high);
If we invoke binarySearch like this:
Card card = new Card(11, 0);
System
...
println(binarySearch(cards, card));
We expect to find this card at position 10
...
it-ebooks
...
After k
iterations, the number of remaining cards is 52/2k
...
The result is log2 52, which is
about 5
...
So we might have to look at 5 or 6 cards, as opposed to all 52 if we did a
sequential search
...
For large values of n, binary search can be
much faster
...
The trick is to write
a method that takes low and high as parameters, and turn steps 3 and 4 into recursive
invocations
...
compareTo(target);
if (comp == 0) {
return mid;
} else if (comp < 0) {
return binarySearch(cards, target, mid + 1,
} else {
return binarySearch(cards, target, low, mid
}
// step 2
// step 3
high);
// step 4
- 1);
}
Recursive Version
www
...
info
|
171
Instead of a while loop, we have an if statement to terminate the recursion
...
Two common errors in recursive programs are (1) forgetting to include a base case,
and (2) writing the recursive call so that the base case is never reached
...
Vocabulary
encode:
To represent one set of values using another set of values, by constructing a map‐
ping between them
...
There is only one copy of a class
variable, no matter how many objects there are
...
binary search:
An algorithm that searches a sorted array by starting in the middle, comparing
and element to the target, and eliminating half of the remaining elements
...
See “Using the
Code Examples” on page xi for instructions on how to download the repository
...
Exercise 12-1
...
Exercise 12-2
...
Modify the compareTo
method to implement this ordering
...
it-ebooks
...
In Poker a “flush” is a hand that contains five or more cards of the same suit
...
1
...
Your solution should only tra‐
verse the array once
...
Write a method called hasFlush that takes an array of cards as a parameter and
returns true if the hand contains a flush (and false otherwise)
...
Working with cards is more interesting if you can display them on the screen
...
In the code directory for this chapter, ch12, you will find:
• cardset-oxymoron: A directory containing images of playing cards
...
java: A sample program that demonstrates how to read and display
images
...
The
declaration looks like this:
private Image[][] images;
The variable images refers to a 2D array of Image objects, which are defined in the
java
...
Here’s the code that creates the array itself:
images = new Image[14][4];
The array has 14 rows (one for each rank plus an unused row for rank 0) and 4 col‐
umns (one for each suit)
...
charAt(suit);
for (int rank = 1; rank <= 13; rank++) {
String s = String
...
gif",
cardset, rank, c);
images[rank][suit] = new ImageIcon(s)
...
it-ebooks
...
suits is a string that contains the single-letter abbreviations for the suits
...
For exam‐
ple, when rank=1 and suit=2, the value of s is "cardset-oxymoron/01h
...
The last line of the loop reads the image file, extracts an Image object, and assigns it
to a location in the array, as specified by the indexes rank and suit
...
If you compile and run CardTable
...
You can use this class as a starting place to implement your
own card games
...
it-ebooks
...
In this chapter, we take another step toward object-oriented programming by defin‐
ing a class to represent a deck of cards
...
The code for this chapter is in Card
...
java, which are in the directory
ch13 in the repository for this book
...
The Deck Class
The main idea of this chapter is to create a Deck class that encapsulates an array of
Cards
...
cards = new Card[n];
}
}
The constructor initializes the instance variable with an array of n cards, but it doesn’t
create any card objects
...
175
www
...
info
Figure 13-1
...
We’ll add a second constructor that makes a standard 52-card deck and populates it
with Card objects:
public Deck() {
this
...
cards[index] = new Card(rank, suit);
index++;
}
}
}
This method is similar to the example in “Arrays of Cards” on page 167; we just
turned it into a constructor
...
Looking at the methods we have written so far, one obvious candidate is print
Deck from “Arrays of Cards” on page 167
...
cards
...
out
...
cards[i]);
}
}
When you transform a static method into an instance method, it usually gets shorter
...
print() to invoke the instance method
...
In “Random Numbers” on page 108 we saw how to generate random
numbers, but it is not obvious how to use them to shuffle a deck
...
Since humans usu‐
ally don’t shuffle perfectly, after about seven iterations the order of the deck is pretty
well randomized
...
it-ebooks
...
In fact, after eight perfect shuffles, you would
find the deck back in the order you started in! (For more information, see https://
en
...
org/wiki/Faro_shuffle
...
Here is an outline of how this algorithm
works
...
This technique is sometimes called pseudocode
...
In this case, we need a method that chooses a random integer between
low and high, and a method that takes two indexes and swaps the cards at those posi‐
tions
...
And this process—writing pseudocode first and then writing methods to make it
work—is called top-down development (see https://en
...
org/wiki/Topdown_and_bottom-up_design)
...
Selection Sort
Now that we have messed up the deck, we need a way to put it back in order
...
It’s
called selection sort, because it works by traversing the array repeatedly and selecting
the lowest (or highest) remaining card each time
...
During the ith iteration, we find the lowest card to the right of i and swap it
with the ith card
...
it-ebooks
...
In this algorithm
we can use swapCards again, so we only need a method to find the lowest card; we’ll
call it indexLowest
...
Merge Sort
Selection sort is a simple algorithm, but it is not very efficient
...
Each traversal takes an amount of time proportional
to n
...
In the next two sections, we’ll develop a more efficient algorithm called merge sort
...
That may not seem
impressive, but as n gets big, the difference between n2 and n log2 n can be enormous
...
So if you had to sort a million num‐
bers, selection sort would require one trillion steps; merge sort would require only 20
million
...
Try
this out with a deck of cards:
1
...
Place both decks face up in front of you
...
Compare the top card from each deck and choose the lower one
...
3
...
Then take the remaining cards and
add them to the merged deck
...
In the next few sections, we’ll explain how
to implement this algorithm in Java
...
So we might want a method, subdeck, that takes a deck and a range of
indexes
...
it-ebooks
...
cards
...
cards[i] = this
...
Inside the for loop, the subdeck gets
populated with copies of references from the deck
...
This sort of computation can be confusing, and forgetting the + 1
often leads to “off-by-one” errors
...
Figure 13-2 is a state diagram of a subdeck with low = 0 and high = 4
...
Figure 13-2
...
Aliasing might not be a good idea, because changes to shared cards would be reflec‐
ted in multiple decks
...
Merging Decks
The next helper method we need is merge, which takes two sorted subdecks and
returns a new deck containing all cards from both decks, in order
...
it-ebooks
...
cards
...
Adding Recursion
Once your merge method is working correctly, you can try out a simple version of
merge sort:
public
//
//
//
}
Deck almostMergeSort() {
divide the deck into two subdecks
sort the subdecks using selectionSort
merge the two halves and return the result
An exercise at the end of the chapter asks you to implement this algorithm
...
At the point where you sort the subdecks, why should you invoke the slower algo‐
rithm, selectionSort? Why not invoke the spiffy new mergeSort you are in the pro‐
cess of writing? Not only is that a good idea, it is necessary to achieve the log2
performance advantage
...
A simple base case is a subdeck with 0 or 1 cards
...
The recursive version of mergeSort should look something like this:
180
|
Chapter 13: Objects of Arrays
www
...
info
public
//
//
//
//
}
Deck mergeSort() {
if the deck is 0 or 1 cards, return it
divide the deck into two subdecks
sort the subdecks using mergeSort
merge the two halves and return the result
As usual, there are two ways to think about recursive programs: you can think
through the entire flow of execution, or you can make the “leap of faith” (see “Leap of
Faith” on page 81)
...
When you used selectionSort to sort the subdecks, you didn’t feel compelled to fol‐
low the flow of execution
...
And all you did to make mergeSort recursive was replace one sorting
algorithm with another
...
Well, almost
...
But other than that, writing the recursive
version should be no problem
...
helper method:
Often a small method that does not do anything enormously useful by itself, but
which helps another, more complex method
...
selection sort:
A simple sorting algorithm that searches for the smallest or largest element n
times
...
Exercises
The code for this chapter is in the ch13 directory of ThinkJavaCode
...
Vocabulary
www
...
info
|
181
Before you start the exercises, we recommend that you compile and run the
examples
...
You can learn more about the sorting algorithms in this chapter, and others, at http://
www
...
com/
...
Exercise 13-2
...
1
...
java that con‐
tains the code in this chapter
...
2
...
You can use the
nextInt provided by java
...
Random, which we saw in “Random Numbers”
on page 108
...
3
...
4
...
Exercise 13-3
...
Use
the Deck
...
1
...
2
...
3
...
The best way to test it is to build and shuffle a deck
...
Then you can pass
the two halves to merge to see if it works
...
it-ebooks
...
Write the simple version of mergeSort, the one that divides the deck in half, uses
selectionSort to sort the two halves, and uses merge to create a new, sorted
deck
...
Write a recursive version of mergeSort
...
selectionSort();
deck = deck
...
The goal of this exercise is to practice top-down programming by implementing
“insertion sort”
...
sorting-algorithms
...
Write a method named insertionSort that implements this algorithm
...
Write a toString method for the Deck class
...
When it’s printed, this string should display the same
results as the print method in “The Deck Class” on page 175
...
Consider using java
...
StringBuilder; you can find the documentation by doing
a web search for “Java StringBuilder”
...
it-ebooks
...
it-ebooks
...
The main objective
is to be the first player to get rid of all your cards
...
Place the remaining cards face down to create the “draw pile”
...
The card must
match the rank or suit of the previously played card, or be an eight, which is a
“wild card”
...
• If the draw pile ever runs out, the discard pile is shuffled (except the top card)
and becomes the new draw pile
...
Eights are worth 20, face cards are worth
10, and all others are worth their rank
...
wikipedia
...
The code for this chapter is in the directory ch14 in the repository for this book
...
185
www
...
info
Decks and Hands
To implement this game, we need to represent a deck of cards, a discard pile, a draw
pile, and a hand for each player
...
The Deck class from the previous chapter meets some of these requirements, but
there are two problems:
• Hands and piles have different sizes, and their sizes change as the game pro‐
gresses
...
• It’s not clear that a Deck object is the right way to represent hands and piles
...
We can solve the first problem by replacing the Card array with an ArrayList, which
is in the java
...
An ArrayList is a collection, which is an object that
contains other objects
...
For our purposes, ArrayList is a
good choice because it provides methods to add and remove elements, and it grows
and shrinks automatically
...
We’ll
define a new class, CardCollection, to represent a collection of cards
...
A subclass is a new class that “extends” an existing class; that is, it has the attributes
and methods of the existing class, plus more
...
label = label;
this
...
it-ebooks
...
This declaration says that cards is not just an ArrayList, it’s an ArrayList of
Card objects
...
It also initializes cards with an empty ArrayList
...
We will
write a CardCollection method that does the same thing:
public void addCard(Card card) {
this
...
add(card);
}
Until now, we have used this explicitly to make it easy to identify attributes
...
So from here on, we will drop it:
public void addCard(Card card) {
cards
...
The following method
takes an index, removes the card at that location, and shifts the following cards left to
fill the gap:
public Card popCard(int i) {
return cards
...
It is most efficient to choose the last one, so we don’t have to shift any following cards
...
size();
}
For convenience, CardCollection also provides an empty method that returns true
when size is zero:
public boolean empty() {
return cards
...
it-ebooks
...
We will use these wrapper
methods to implement less trivial methods, like deal:
public void deal(CardCollection that, int n) {
for (int i = 0; i < n; i++) {
Card card = popCard();
that
...
The second parameter, n, is the
number of cards to deal
...
Instead,
you have to use the methods get and set
...
get(i);
}
The last method gets the last card (but doesn’t remove it):
public Card last() {
int i = size() - 1;
return cards
...
The only modifiers we provide are the two versions of popCard and the
following version of swapCards:
public void swapCards(int i, int j) {
Card temp = cards
...
set(i, cards
...
set(j, temp);
}
We use swapCards to implement shuffle, which we described in “Shuffling Decks”
on page 176:
public void shuffle() {
Random random = new Random();
for (int i = size() - 1; i > 0; i--) {
int j = random
...
it-ebooks
...
You can read about
them in the documentation, which you can find by doing a web search for “Java
ArrayList”
...
Next we’ll use it to
define Deck and Hand
...
add(new Card(rank, suit));
}
}
}
}
The first line uses the keyword extends to indicate that Deck extends the class Card
Collection
...
Another way to say the same thing is that Deck “inherits from”
CardCollection
...
In Java, classes may only extend one superclass
...
lang
...
So in this example,
Deck extends CardCollection, which in turn extends Object
...
Constructors are not inherited, but all other public attributes and methods are
...
So you can create a
Deck object like this:
Deck deck = new Deck("Deck");
The first line of the constructor uses something new, super, which is a keyword that
refers to the superclass of the current class
...
So in this case, super invokes the CardCollection constructor, which initializes the
attributes label and cards
...
Inheritance
www
...
info
|
189
That’s it for the Deck class
...
We could define two classes, one for hands and one for piles, but there is not much
difference between them
...
Here’s what the definition looks like:
public class Hand extends CardCollection {
public Hand(String label) {
super(label);
}
public void display() {
System
...
println(getLabel() + ": ");
for (int i = 0; i < size(); i++) {
System
...
println(getCard(i));
}
System
...
println();
}
}
Like Deck, Hand extends CardCollection, so it inherits methods like getLabel, size,
and getCard, which are used in display
...
In summary, a Deck is just like a CardCollection, but it provides a different con‐
structor
...
Dealing Cards
At this point we can create a Deck and start dealing cards
...
shuffle();
Hand hand = new Hand("Hand");
deck
...
display();
Hand drawPile = new Hand("Draw Pile");
deck
...
out
...
\n",
drawPile
...
Here’s the
output of the previous example:
190
|
Chapter 14: Objects of Objects
www
...
info
Hand:
5 of Diamonds
Ace of Hearts
6 of Clubs
6 of Diamonds
2 of Clubs
Draw Pile has 47 cards
...
If you are a careful reader, you might notice something strange about this example
...
addCard(card);
}
}
Notice that the first parameter is supposed to be a CardCollection
...
deal(hand, 5);
The argument is a Hand, not a CardCollection
...
If a method expects a CardCollection, you can give it a
Hand, a Deck, or a CardCollection
...
If it seems strange that an object can belong to more than one type, remember that
this happens in real life, too
...
But not every animal is a mammal, and not every mammal is a cat
...
And that’s probably a good
thing, since it makes it easy to reuse these classes if we want to make another game in
the future
...
We’ll use two classes: Player, which encap‐
sulates player strategy, and Eights, which creates and maintains the state of the game
...
it-ebooks
...
name = name;
this
...
The constructor takes the
player’s name as a string and saves it in an instance variable
...
The primary method that Player provides is play, which decides which card to dis‐
card during each turn:
public Card play(Eights eights, Card prev) {
Card card = searchForMatch(prev);
if (card == null) {
card = drawForMatch(eights, prev);
}
return card;
}
The first parameter is a reference to the Eights object that encapsulates the state of
the game
...
The second parameter, prev, is
the card on top of the discard pile
...
searchForMatch looks in the player’s hand for a card that
matches the previously played card:
public Card searchForMatch(Card prev) {
for (int i = 0; i < hand
...
getCard(i);
if (cardMatches(card, prev)) {
return hand
...
If there are no cards that match, it returns null
...
it-ebooks
...
draw();
System
...
println(name + " draws " + card);
if (cardMatches(card, prev)) {
return card;
}
hand
...
It uses the Eights object to draw a card
...
Otherwise it
adds the card to the player’s hand and continues
...
cardMatches is a straightforward translation of the rules of
the game:
public static boolean cardMatches(Card card1, Card card2) {
if (card1
...
getSuit()) {
return true;
}
if (card1
...
getRank()) {
return true;
}
if (card1
...
size(); i++) {
Card card = hand
...
getRank();
if (rank == 8) {
sum -= 20;
} else if (rank > 10) {
sum -= 10;
} else {
sum -= rank;
}
}
return sum;
}
The Player Class
www
...
info
|
193
The Eights Class
In “Shuffling Decks” on page 176 we introduced top-down development, which is a
way of developing programs by identifying high-level goals, like shuffling a deck, and
breaking them into smaller problems, like finding the lowest element in an array or
swapping two elements
...
Looking at the rules of Crazy Eights, we can identify some methods we’ll need:
• Create the deck, the discard and draw piles, and the player objects
...
• Check whether the game is over
...
• Draw a card
...
• Display the state of the game
...
Now we can start implementing the pieces
...
One of the exercises at the end of the
chapter asks you to modify this code to handle more players
...
Here’s a constructor that initializes the instance variables and deals the cards:
public Eights() {
Deck deck = new Deck("Deck");
deck
...
deal(one
...
it-ebooks
...
deal(two
...
deal(discardPile, 1);
drawPile = new Hand("Draw pile");
deck
...
in);
}
The next piece we’ll need is a method that checks whether the game is over
...
getHand()
...
getHand()
...
Here is a method for
that:
public void reshuffle() {
Card prev = discardPile
...
dealAll(drawPile);
discardPile
...
shuffle();
}
The first line saves the top card from discardPile
...
Then we put the saved card back into discardPile and shuffle
drawPile
...
empty()) {
reshuffle();
}
return drawPile
...
The Eights Class
www
...
info
|
195
The last two pieces are displayState and waitForUser:
public void displayState() {
one
...
display();
discardPile
...
out
...
out
...
size() + " cards");
}
public void waitForUser() {
in
...
last();
Card next = player
...
addCard(next);
System
...
println(player
...
out
...
play, which
we saw in the previous section
...
Finally, we use takeTurn and the other methods to write playGame:
public void playGame() {
Player player = one;
// keep playing until there's a winner
while (!isDone()) {
displayState();
waitForUser();
takeTurn(player);
player = nextPlayer(player);
}
// display the final score
one
...
displayScore();
}
Done! Notice the result of bottom-up development is similar to top-down: we have a
high-level method that calls helper methods
...
196
|
Chapter 14: Objects of Objects
www
...
info
Class Relationships
This chapter demonstrates two common relationships between classes:
composition:
Instances of one class contain references to instances of another class
...
inheritance:
One class extends another class
...
Composition is also known as a HAS-A relationship, as in “Eights HAS-A Scanner”
...
This vocabulary provides a concise way to talk about an objectoriented design
...
As we saw in “Class Diagrams” on page 138, the UML representation of a
class is a box with three sections: the class name, the attributes, and the methods
...
Relationships between classes are represented by arrows: composition arrows have a
standard arrow head, and inheritance arrows have a hollow triangle head (usually
pointing up)
...
Figure 14-1
...
UML is an international standard, so almost any software engineer in the world could
look at this diagram and understand our design
...
We hope this final chapter has been a useful summary of all the techniques presented
in the book, including variables, methods, conditionals, loops, arrays, objects, and
algorithms
...
it-ebooks
...
inheritance:
The ability to define a new class that has the same instance variables and meth‐
ods of an existing class
...
superclass:
An existing class that is extended by another class
...
bottom-up development:
A way of developing programs by identifying simple pieces, implementing them,
and then assembling them into more complex algorithms
...
IS-A:
A relationship between two classes where one class extends another class; the
subclass “is” an instance of the superclass
...
See “Using the
Code Examples” on page xi for instructions on how to download the repository
...
Exercise 14-1
...
play method
...
Think of other ways you can minimize penalty points, such as playing the highest
ranking cards first
...
198
|
Chapter 14: Objects of Objects
www
...
info
Exercise 14-2
...
If you implemented multiple strategies in the previous exercise, you can
play them against each other to evaluate which one works best
...
Exercise 14-3
...
Modify the Eights class to create an ArrayList of players, and modify next
Player to select the next player
...
When we designed the program for this chapter, we tried to minimize the number of
classes
...
For example, card
Matches is a static method in Player, but it would be more natural if it were an
instance method in Card
...
You can solve this problem by adding a new class, EightsCard, that extends
Card and provides a method, match, that checks whether two cards match according
to the rules of Crazy Eights
...
And
while you’re at it, you could add a method named scoreCard to EightsCard
...
Exercises
www
...
info
|
199
www
...
info
APPENDIX A
Development Tools
The steps for compiling, running, and debugging Java code depend on your develop‐
ment environment and operating system
...
Instead, we provide this appendix with a
brief introduction to DrJava—an integrated development environment (IDE) that is
well suited for beginners—and other development tools, including Checkstyle for
code quality and JUnit for testing
...
Examples include jdoodle
...
net,
tutorialspoint
...
If you are unable to install software on your computer (which is often the case in
public schools and Internet cafés), you can use these online development environ‐
ments for almost everything in this book
...
• A simple text editor such as Notepad++ or Sublime Text, and/or an IDE such as
DrJava, Eclipse, jGrasp, or NetBeans
...
it-ebooks
...
The IDE we recommend is DrJava, which is an open-source development
environment written in Java (see Figure A-1)
...
Scroll down to “Java Platform, Standard Edition” and click the download
button under JDK
...
Don’t forget to run the installer after you download it!
To install DrJava, visit http://drjava
...
We recommend
that you save it to your Desktop or another convenient location
...
Refer to the DrJava documentation (http://drjava
...
Figure A-1
...
When running DrJava for the first time, we recommend you change three settings
from the Edit > Preferences menu under Miscellaneous: set the Indent Level to 4, check
the Automatically Close Block Comments box, and uncheck the Keep Emacs-style
Backup Files box
...
It provides the ability to try out code quickly, without having to write a
class definition and save/compile/run the program
...
202
|
Appendix A: Development Tools
www
...
info
Figure A-2
...
There is one subtle detail to note when using the Interactions feature
...
Notice in Figure A-2 how the variable declarations end with semicolons, but
the logic expressions in the following lines do not
...
out
...
What’s nice about this feature is that you don’t have to create a new class, declare a
main method, write arbitrary expressions inside System
...
println statements,
save the source file, and get all of your code to compile in advance
...
Command-Line Interface
One of the most powerful and useful skills you can learn is how to use the commandline interface, also called the “terminal”
...
It allows you to run programs, manage files and directories, and
monitor system resources
...
There are many good tutorials online for learning the command line for your operat‐
ing system; just search the web for “command line tutorial”
...
it-ebooks
...
Figure A-3 shows an example where the Hello
...
After changing to that location and listing the files, we use the javac
command to compile Hello
...
Running ls again, we see that the compiler gener‐
ated a new file, Hello
...
We run the program
using the java command, which displays the output on the following line
...
Compiling and running Hello
...
Note that the javac command requires a filename (or multiple source files separated
by spaces), whereas the java command requires a single class name
...
Taking time to learn this efficient and elegant way of interacting with your operating
system will make you more productive
...
Command-Line Testing
As described in “Debugging Code” on page 8, it’s more effective to program and
debug your code little by little than to attempt writing everything all at once
...
Throughout the book, we illustrate techniques for testing your programs
...
But at some point, you will get tired of typing the same test cases over and over
...
The basic idea is to store the test cases
204
|
Appendix A: Development Tools
www
...
info
in plain text files and trick Java into thinking they are coming from the keyboard
...
Make sure you can compile and run the Convert
...
2
...
java, create a plain text file named test
...
Enter the following line and save the file:
193
...
Create a second plain text file named test
...
Enter the
following line and save the file:
193
...
Open a terminal, and change to the directory with these files
...
in > test
...
The first one redirects the
contents of test
...
in, as if it were entered from the keyboard
...
out to a new file test
...
In other words, the test
...
By the way, it’s perfectly okay to compile your programs in DrJava (or some other
environment) and run them from the command line
...
At this point, we just need to compare the contents test
...
exp
...
If not,
then we found a bug, and we can use the output to begin debugging our program
...
exp test
...
If there are no differ‐
ences, then it displays nothing, which in our case is what we want
...
Usually
the program is at fault, and diff provides some insight about what is broken
...
Interpreting the results from diff can be confusing, but fortunately there are many
graphical tools that show the differences between two files
...
Development Tools
www
...
info
|
205
Figure A-4
...
Regardless of what tool you use, the goal is the same
...
Running Checkstyle
Checkstyle is a command-line tool that can be used to determine if your source code
follows a set of style rules
...
You can download the latest version as a JAR file from http://checkstyle
...
net/
...
Open a terminal in that location, and run the following command:
java -jar checkstyle-*-all
...
xml *
...
The output indicates the file and line num‐
ber of each problem
...
java:
Hello
...
xml is inside the JAR file and represents most of Google’s
style rules
...
xml or provide your own configu‐
ration file
...
206
|
Appendix A: Development Tools
www
...
info
If you apply Checkstyle to your source code often, you will likely internalize good
style habits over time
...
In
particular, they can’t evaluate the quality of your comments, the meaning of your vari‐
able names, or the structure of your algorithms
...
Good variable names communicate the intent of your program and how the
data is organized
...
Tracing with a Debugger
A great way to visualize the flow of execution, including how parameters and argu‐
ments work, is to use a debugger
...
Set a breakpoint, a line where you want the program to pause
...
Step through the code one line at a time and watch what it does
...
Check the values of variables and see when and how they change
...
Press Ctrl+B to toggle a breakpoint on the current line; it should now be high‐
lighted in red
...
These commands are also available from the Debugger
menu, in case you forget the shortcut keys
...
The debug pane
displays the call stack, with the current method on top of the stack, as shown in
Figure A-5
...
You can also press Automatic Trace to watch DrJava run your code one line at a
time
...
When
the program is paused, you can examine (or even change) the value of any variable
using the Interactions Pane
...
You might expect the code do one thing, but then the debugger
shows it doing something else
...
Development Tools
www
...
info
|
207
Figure A-5
...
Execution is currently paused on the first
line of printTwice
...
You can edit your code while debugging it, but we don’t recommend it
...
See http://drjava
...
html for more information about using the
debugger feature of DrJava
...
Writing code like this can get repetitive, but
there are tools to make it easier
...
For example, to test fibonacci from “One More Example” on page 82, we could
write:
public static void main(String[] args) {
if (fibonacci(1) != 1) {
System
...
println("fibonacci(1) is incorrect");
}
if (fibonacci(2) != 1) {
System
...
println("fibonacci(2) is incorrect");
}
208
|
Appendix A: Development Tools
www
...
info
if (fibonacci(3) != 2) {
System
...
println("fibonacci(3) is incorrect");
}
}
This test code is self-explanatory, but it’s longer than it needs to be and it doesn’t scale
very well
...
Using a unit
test framework addresses these and other issues
...
org)
...
If the name of your class is
Class, the name of the test class is ClassTest
...
For example, suppose that the fibonacci method belongs to a class named Series
...
framework
...
fibonacci(1));
assertEquals(1, Series
...
fibonacci(3));
}
}
This example uses the keyword extends, which indicates that the new class,
SeriesTest, is based on an existing class, TestCase, which is imported from the
package junit
...
Many development environments can generate test classes and test methods automat‐
ically
...
assertEquals is provided by the TestCase class
...
If so, it does nothing; otherwise it displays a detailed error
message
...
If they are not
equal, the test fails
...
err messages
...
To run JUnit directly from DrJava, click the Test button on the toolbar
...
Otherwise, DrJava
will take you directly to the first assertion that failed
...
it-ebooks
...
JDK:
The “Java Development Kit” that contains the compiler, Javadoc, and other tools
...
text editor:
A program that edits plain text files, the format used by most programming lan‐
guages
...
command-line interface:
A means of interacting with the computer by issuing commands in the form of
successive lines of text
...
in and/or System
...
wildcard:
A command-line feature that allows you to specify a pattern of filenames using
the * character
...
breakpoint:
A line of code where the debugger will pause a running program
...
unit test:
Code that exercises a single method of a program, testing for correctness and/or
efficiency
...
it-ebooks
...
awt
...
We are only going to scratch the surface
of graphics programming; you can read more about it in the Java tutorials at https://
docs
...
com/javase/tutorial/2d/
...
awt
...
awt
...
A Canvas is a blank rectangular area of
the screen onto which the application can draw
...
Here is an example program that draws a circle using the fillOval method:
import java
...
Canvas;
import java
...
Graphics;
import javax
...
JFrame;
public class Drawing extends Canvas {
public static void main(String[] args) {
JFrame frame = new JFrame("My Drawing");
Canvas canvas = new Drawing();
canvas
...
add(canvas);
frame
...
setVisible(true);
}
public void paint(Graphics g) {
g
...
it-ebooks
...
You can read about the other methods in the documentation,
which you can find by doing a web search for “Java Canvas”
...
Create a JFrame object, which is the window that will contain the canvas
...
Create a Drawing object (which is the canvas), set its width and height, and add it
to the frame
...
Pack the frame (resize it) to fit the canvas, and display it on the screen
...
The application doesn’t
end after the main method returns; instead, it waits for the JFrame to close
...
Graphics Methods
You are probably used to Cartesian coordinates, where x and y values can be positive
or negative
...
That way, x and y are always positive integers
...
Figure B-1
...
Graphical coordinates are measured in pixels; each pixel corresponds to a dot on the
screen
...
it-ebooks
...
You don’t have to
create the Graphics object; it gets created when you create the Canvas, and it gets
passed as an argument to paint
...
*/
public void fillOval(int x, int y, int width, int height)
The four parameters specify a bounding box, which is the rectangle in which the oval
is drawn
...
The bounding box itself is not drawn (see Figure B-2)
...
Diagram of an oval inside its bounding box
...
setColor(Color
...
Color
...
awt
...
Other colors include:
black
lightGray
blue
magenta
cyan
orange
darkGray
pink
gray
white
green
yellow
You can create your own colors by specifying the red, green, and blue (RGB) compo‐
nents
...
The color (0, 0,
0) is black, and (255, 255, 255) is white
...
it-ebooks
...
setBackground(Color
...
wikipedia
...
We can use the oval we just
drew as the face, and then add two ears
...
Here’s a method that takes a Rectangle and invokes fillOval:
public void boxOval(Graphics g, Rectangle bb) {
g
...
x, bb
...
width, bb
...
width / 2;
int dy = bb
...
x, bb
...
translate(-dx / 2, -dy / 2);
boxOval(g, half);
half
...
The next three lines create a smaller rectangle for the
ears
...
The result is shown in Figure B-3
...
A “Hidden Mickey” drawn using Java graphics
...
See the exercises
at the end of this appendix for more example drawings
...
it-ebooks
...
coordinate:
A value that specifies a location in a two-dimensional graphical window
...
bounding box:
A common way to specify the coordinates of a rectangular area
...
Exercises
The code for this chapter is in the ap02 directory of ThinkJavaCode
...
Before you start the exercises, we recommend that you compile and run the
examples
...
Draw the flag of Japan: a red circle on a white background that is wider than it is tall
...
Modify Mickey
...
The result should look like “Mickey Moose”, shown in Figure B-4
...
Figure B-4
...
Java 2D Graphics
www
...
info
|
215
Exercise B-3
...
For an explanation of what is going on, see https://en
...
org/wiki/
Moire_pattern
...
In the directory app02 in the repository for this book, you’ll find a file named
Moire
...
Open it and read the paint method
...
Now run it
...
Modify the program so that the space between the circles is larger or smaller
...
3
...
The distance between the circles should be
small enough that the Moiré interference is apparent
...
Write a method named radial that draws a radial set of line segments as shown
in Figure B-5 (right), but they should be close enough together to create a Moiré
pattern
...
Just about any kind of graphical pattern can generate Moiré-like interference pat‐
terns
...
Figure B-5
...
216
|
Appendix B: Java 2D Graphics
www
...
info
APPENDIX C
Debugging
Although there are debugging suggestions throughout the book, we thought it would
be useful to organize them in an appendix
...
The best debugging strategy depends on what kind of error you have:
• Compile-time errors indicate that there is something wrong with the syntax of
the program
...
• Run-time errors are produced if something goes wrong while the program is
running
...
• Logic errors cause the program to do the wrong thing
...
The following sections are organized by error type; some techniques are useful for
more than one type
...
Incremental development, which we presented in “Writ‐
ing Methods” on page 73, can help
...
When there is an error, you will have a pretty
good idea where it is
...
For each sit‐
uation, we have some suggestions about how to proceed
...
it-ebooks
...
If the compiler reports 100 error messages, that doesn’t mean there are 100 errors in
your program
...
It tries to recover and pick up again after the first error, but sometimes it
reports spurious errors
...
We suggest that you only fix one error at
a time, and then recompile the program
...
I’m getting a weird compiler message, and it won’t go away
...
It may be written in terse jargon, but
often there is a carefully hidden kernel of information
...
Actually, it tells you where the compiler was when it noticed a problem, which is not
necessarily where the error is
...
Generally the error will be prior to the location of the error message, but there are
cases where it will be somewhere else entirely
...
If you don’t find the error quickly, take a breath and look more broadly at the entire
program
...
Now, start looking for common syntax errors:
1
...
All
method definitions should be nested within a class definition
...
2
...
3
...
4
...
Make
sure that you use double quotes for strings and single quotes for characters
...
For each assignment statement, make sure that the type on the left is the same as
the type on the right
...
218
|
Appendix C: Debugging
www
...
info
6
...
7
...
If you are invoking a void method, make sure you are not trying to do
something with the result
...
If you are invoking an instance method, make sure you are invoking it on an
object with the right type
...
9
...
If you try that in a static method—with or without this—you get
a message like “non-static variable x cannot be referenced from a static context
...
I can’t get my program to compile no matter what I do
...
Check your development environ‐
ment to make sure the program you are editing is the program the compiler is
compiling
...
You
might be editing one version of the file, but compiling a different version
...
Now compile again
...
If you have examined the code thoroughly, and you are sure the compiler is compil‐
ing the right source file, it is time for desperate measures: debugging by bisection
...
If you are working on Bob
...
java
...
• Delete about half the code from Bob
...
Try compiling again
...
Bring back about half of what you deleted and repeat
...
Delete about half of the remaining code and repeat
...
it-ebooks
...
This process is ugly, but it goes faster than you might think, and it is very reliable
...
Some error messages come with tidbits of advice, like “class Golfer must be declared
abstract
...
lang
...
lang
...
” It sounds like the compiler is telling you to declare Golfer as
an abstract class, and if you are reading this book, you probably don’t know what
that is or how to do it
...
The solution in this case is to make sure Golfer
has a method called compareTo that takes an Object as a parameter
...
Error messages give you evidence that
something is wrong, but the remedies they suggest are unreliable
...
My program hangs
...
Often that
means it is caught in an infinite loop or an infinite recursion
...
Run the program
...
Go to the section titled “Infinite loop”
...
If that happens, go to the section titled
“Infinite recursion”
...
220
| Appendix C: Debugging
www
...
info
• If neither of the previous suggestions helps, you might not understand the flow
of execution in your program
...
Infinite loop
If you think you have an infinite loop and you know which loop it is, add a print
statement at the end of the loop that displays the values of the variables in the condi‐
tion, and the value of the condition
...
out
...
out
...
out
...
The last time through the loop, the condition should be false
...
Infinite recursion
Most of the time, an infinite recursion will cause the program to throw a
StackOverflowError
...
If you know which method is causing an infinite recursion, check that there is a base
case
...
If not, you need to rethink the algorithm and identify a base
case
...
Now when
you run the program you see a few lines of output every time the method is invoked,
and you can see the values of the parameters
...
Flow of execution
If you are not sure how the flow of execution is moving through your program, add
print statements to the beginning of each method with a message like “entering
Debugging
www
...
info
|
221
method foo”, where foo is the name of the method
...
You can also display the arguments each method receives
...
When I run the program I get an exception
...
The stack trace includes the method that was running, the method that invoked it, the
method that invoked that one, and so on
...
NullPointerException:
You tried to access an instance variable or invoke a method on an object that is
currently null
...
Remember that when you declare a variable with an array type, its elements are
initially null until you assign a value to them
...
out
...
x);
ArrayIndexOutOfBoundsException:
The index you are using to access an array is either negative or greater than
array
...
If you can find the site where the problem is, add a print
statement immediately before it to display the value of the index and the length
of the array
...
Find the nearest assignment statement and see if it is
doing the right thing
...
StackOverflowError:
See “Infinite recursion” on page 221
...
If you are using a projectbased development environment like Eclipse, you might have to import the file
222
| Appendix C: Debugging
www
...
info
into the project
...
This problem depends on your file system, so it can be hard to track down
...
I added so many print statements I get inundated with output
...
There are two ways to proceed: either simplify the output, or sim‐
plify the program
...
As you
develop a program, you should write code to generate concise, informative traces of
what the program is doing
...
For
example, if you are sorting an array, sort a small array
...
Also, clean up the code
...
For example, if you suspect that the error is in a
deeply-nested part of the program, rewrite that part with a simpler structure
...
The process of finding the minimal test case often leads you to the bug
...
Reorganizing the program can help you find subtle bugs
...
Logic Errors
My program doesn’t work
...
Only you know what the program is supposed to do,
and only you know that it isn’t doing it
...
You
need a hypothesis about what the program is actually doing
...
it-ebooks
...
See “Flow of execution” on page 221
...
• Is a section of code producing an unexpected effect? Make sure you understand
the code, especially if it invokes methods in the Java library
...
They might not
do what you think they do
...
If it doesn’t do what
you expect, the problem might not actually be the program; it might be in your head
...
Once you find the
discrepancy between your model and reality, you can solve the problem
...
If you want frac‐
tions, use double
...
• Floating-point numbers are only approximate, so don’t rely on them to be per‐
fectly accurate
...
Instead of writing if (d == 1
...
abs(d - 1
...
000001)
...
If you meant to check equivalence, you should use the equals method
instead
...
If you want a different
notion of equivalence, you have to override it
...
See “Flow of execution” on page 221
...
Writing complex expressions is fine as long as they are readable, but they can be hard
to debug
...
rect
...
getLocation()
...
getWidth(), -rect
...
it-ebooks
...
getWidth();
int dy = -rect
...
getLocation();
Point newLocation = location
...
setLocation(newLocation);
The second version is easier to read, partly because the variable names provide addi‐
tional documentation
...
Another problem that can occur with big expressions is that the order of operations
x
may not be what you expect
...
PI;
That is not correct, because multiplication and division have the same precedence,
x
and they are evaluated from left to right
...
If you are not sure of the order of operations, check the documentation, or use paren‐
theses to make it explicit
...
PI);
This version is correct, and more readable for other people who haven’t memorized
the order of operations
...
If you have a return statement with a complex expression, you don’t have a chance to
display the value before returning
...
min(a
...
x), Math
...
y, b
...
max(a
...
width, b
...
width)
- Math
...
x, b
...
max(a
...
height, b
...
height)
- Math
...
y, b
...
min(a
...
x);
int y2 = Math
...
y, b
...
max(a
...
width, b
...
width);
int y2 = Math
...
y + a
...
y + b
...
it-ebooks
...
And by reusing x1 and y1, you made the code smaller, too
...
If you use the println method, the output is displayed immediately, but if you use
print (at least in some environments), the output gets stored without being displayed
until the next newline
...
If you suspect that this is happening, change some
or all of the print statements to println
...
First, get away from the computer for a few minutes
...
• Superstitious beliefs (“the computer hates me”) and magical thinking (“the pro‐
gram only works when I wear my hat backwards”)
...
If you suffer from any of these symptoms, get up and go for a walk
...
What is it doing? What are possible causes of that
behavior? When was the last time you had a working program, and what did you do
next?
Sometimes it just takes time to find a bug
...
Good places to find bugs are buses, showers, and bed
...
It happens
...
Sometimes you need a another pair
of eyes
...
Your program should be as simple as possible, and you should be working on the
smallest input that causes the error
...
You should
understand the problem well enough to describe it concisely
...
it-ebooks
...
This phe‐
nomenon is so common that some people recommend a debugging technique called
“rubber ducking”
...
Buy a standard-issue rubber duck
...
When you are really stuck on a problem, put the rubber duck on the desk in
front of you and say, “Rubber duck, I am stuck on a problem
...
”
3
...
4
...
5
...
We’re not kidding, it works! See https://en
...
org/wiki/Rubber_duck_debugging
...
But not always
...
In these cases, you might have to rethink the
algorithm, or adjust your mental model
...
After you fix the bug, don’t just start in making new errors
...
Next time you see something
similar, you will be able to find the bug more quickly
...
Debugging
www
...
info
|
227
www
...
info
Index
Symbols
Arrays class, 106, 107
assignment, 14, 24, 57
attribute, 132
AWT, 131, 211
% operator, 35
== operator, 152
A
abecedarian, 128
accessor, 150
accumulator, 108, 112
addition
integer, 16
string, 20
time, 154
address, 29, 38, 151
algorithm, 2, 9
alias, 106, 112
aliasing, 136, 179
anagram, 129
angle brackets, 187
argument, 43, 48
arithmetic
floating-point, 19
integer, 17, 18
ArithmeticException, 23, 222
array, 103
2D, 173
copying, 106
element, 104
index, 104
length, 107
of cards, 175
of objects, 167
of strings, 163
ArrayIndexOutOfBoundsException, 105, 222
ArrayList, 186
B
base case, 65, 67
BigInteger, 143, 144
binary, 65, 67
binary search, 169, 172
boolean, 57, 77
bottom-up development, 194, 198
bounding box, 213, 215
branch, 59, 67
break, 98
breakpoint, 207, 210
bug, 2, 9
byte code, 3, 10
C
call stack, 65, 207, 210
camel case, 45
Canvas, 211
Card, 161
case-sensitive, 5, 14, 45, 122
chaining, 60, 67
char, 5, 117
Character, 123
charAt, 117
Checkstyle, 206
Church, Alonzo, 79
class, 5, 10, 47
Canvas, 211
Card, 161
229
www
...
info
definition, 4, 145
Graphics, 211
JFrame, 212
Math, 43
Point, 131
Rectangle, 133
Scanner, 30
System, 29
Time, 146
utility, 30
class diagram, 138, 140
class variable, 164, 172
client, 149, 156
collection, 186
Color, 213
command-line interface, 203, 210
comment, 10
documentation, 53
inline, 5
comparable, 166
compareTo, 121
comparison operator, 57
compile, 3, 9, 218
compile-time error, 21, 25, 217
complete ordering, 165
composition, 21, 25, 44, 75
computer science, 2, 9
concatenate, 20, 25, 125
conditional statement, 59, 66
constant, 33, 39
constructor, 146, 156, 162, 175, 179
value, 148
continue, 98
coordinate, 212, 215
counter, 109
Crazy Eights, 185
D
data encapsulation, 145, 156
De Morgan’s laws, 58, 66
dead code, 73, 82
debugger, 207, 210
debugging, 2, 9, 217
by bisection, 219
experimental, 8
rubber duck, 227
declaration, 13, 24, 132
decrement, 97, 99
degrees, 43
230
|
dependent, 150
deterministic, 108, 112
diagram
class, 138
stack, 50, 64, 80
state, 15, 104, 132
divisible, 36
division
floating-point, 91
integer, 17, 18
do-while, 97
documentation, 51, 55, 139
Javadoc comments, 53
Javadoc tags, 78
dot notation, 132, 140
double, 17
Double, 123
doubloon, 129
DrJava, 201
E
efficiency, 101, 111, 169, 178, 183, 187
element, 103, 104, 112
empty array, 124, 125
empty string, 120, 125
encapsulate, 92, 99
encapsulation, 126, 135
data, 145
encode, 162
enhanced for loop, 111, 112
equals, 121, 152, 153
equivalent, 152, 157, 165
error
compile-time, 21, 217
logic, 23, 217, 224
message, 8, 21, 21, 218
run-time, 22, 217
syntax, 218
escape sequence, 6, 10, 118
exception, 22, 217, 222
Arithmetic, 23
ArrayIndexOutOfBounds, 105
InputMismatch, 62
NegativeArraySize, 104
NullPointer, 137, 167
StackOverflow, 172
StringIndexOutOfBounds, 119
executable, 3, 10
experimental debugging, 8
Index
www
...
info
expression, 17, 24, 43, 44
big and hairy, 224
boolean, 61
extends, 186, 189
extract digits, 36
F
factorial, 79, 83, 143
fibonacci, 82
FileNotFoundException, 222
final, 33, 92, 165, 167
flag, 61, 67
floating-point, 17, 24
flow of execution, 47, 54, 221
for, 96
format specifier, 34, 39
format string, 34, 39, 151
frame, 50, 54
functional decomposition, 76, 83
G
garbage collection, 138, 140
generalization, 93, 94, 126, 135
generalize, 92, 99
getter, 150, 156
GitHub, xi
Google style, 7
Graphics, 211
Greenfield, Larry, 8
H
hanging, 220
HAS-A, 197, 198
hello world, 4
helper method, 177, 181
hexadecimal, 29, 151
high-level language, 3, 9
histogram, 109, 112, 173
HTML, 53, 78, 139
I
IDE, 201
identical, 157
if statement, 59
immutable, 118, 125, 156, 166
import statement, 30, 38
increment, 97, 99
incremental development, 73, 82
independent, 150
index, 104, 112, 168
indexOf, 121
infinite loop, 90, 99, 220
infinite recursion, 148, 172, 220, 221
information hiding, 146, 156
inheritance, 186, 197, 198
initialize, 15, 24, 61
InputMismatchException, 62
instance, 145, 156
instance method, 152, 154, 157
instance variable, 146, 156
Integer, 123
integer division, 17, 18
interpret, 3, 9
invoke, 43, 54
IS-A, 197, 198
iteration, 89
J
JAR, 202, 210
java
...
util, 30
Javadoc, 53, 55, 78, 139, 201
JDK, 201, 210
JFrame, 212
JVM, 3, 201, 210
K
keyword, 14, 24, 147
L
language
complete, 79
high-level, 3
low-level, 3
leap of faith, 81, 83, 181
length
array, 107
string, 119
library, 29, 38, 139
Linux, 8
literal, 33, 39
local variable, 49, 54
logarithm, 62, 90
logic error, 23, 25, 217, 224
logical operator, 58, 66, 165
long, 44
Index
www
...
info
|
231
loop, 90, 99
for, 96
infinite, 90
nested, 167
search, 169
while, 89
loop body, 89, 99
loop variable, 93, 99, 105, 119
low-level language, 3, 9
M
magic number, 33, 39
main, 5, 45
map to, 162
Math class, 43
mental model, 224
merge sort, 178, 181
method, 5, 10, 47
accessor, 150
boolean, 77
constructor, 146
definition, 4, 45
equals, 152, 153
getter, 150
helper, 177
instance, 152, 154
modifier, 156, 188
mutator, 150
parameters, 49
pure, 155
setter, 150
static, 154
toString, 151
value, 71, 72
void, 71
Mickey Mouse, 214
modifier method, 156, 157, 188
modulus, 35, 39
mutable, 134
mutator, 150
N
NegativeArraySizeException, 104
nesting, 60, 67, 167
new, 41, 103, 131, 147
newline, 6, 10, 64
nextInt
Random, 109
Scanner, 32
232
nondeterministic, 108, 112
null, 137, 167
NullPointerException, 137
O
object, 117
array of, 167
as parameter, 133
displaying, 151
mutable, 134
type, 145
Object class, 189
object code, 3, 9
object-oriented, 131, 135, 140, 197
off-by-one, 179
operand, 17, 24
operator, 16, 24
assignment, 57
cast, 35
logical, 58, 66, 165
modulus, 35
new, 41, 103, 131, 147
relational, 57, 66
string, 19
order of operations, 20, 25, 225
ordering, 165
overload, 76, 83, 148, 179
override, 152, 157, 198
P
package, 29
paint, 212
palindrome, 128
param tag, 78
parameter, 45, 48, 54, 133
multiple, 49
parameter passing, 48, 54
parse, 22, 25, 123, 125
partial ordering, 165
pi, 43
pixel, 212, 215
Point, 131
portable, 3, 9
posttest loop, 97, 99
precedence, 20, 225
pretest loop, 97, 99
primitive, 117, 125
print, 6, 151
array, 168
| Index
www
...
info
Card, 163
print statement, 4, 10, 151, 223, 226
printDeck, 176
printf, 34, 122, 151
println, 4
private, 146, 149
problem solving, 1
program, 1, 9
program development, 73, 92, 99, 177, 194
programming, 2, 9
pseudocode, 177
pseudorandom, 108, 112
public, 45
pure method, 155, 157
Q
quote mark, 5, 6, 118
R
radians, 43
Random, 109
rank, 161
rational number, 158
readability, 21
Rectangle, 133
recursion, 62, 67, 79, 171, 180
infinite, 148, 172, 221
recursive, 63, 67
redirection operator, 205, 210
reduce, 108, 110, 112
reference, 104, 112, 132, 136, 163, 179
relational operator, 57, 66
replace, 119
repository, xi
return, 61, 72, 134
inside loop, 169
return statement, 225
return tag, 78
return type, 72, 82
return value, 72, 82
RGB, 213, 215
rounding error, 19, 25
rubber duck, 227
run-time error, 22, 25, 137, 167, 217
S
scaffolding, 75, 83
Scanner, 30
Scrabble, 129, 158
search, 107, 112
selection sort, 177, 181
semicolon, 4, 14, 22
sequential search, 169, 172
setter, 150, 157
shadowing, 148, 156
short circuit, 58, 66
shuffle, 176, 177
signature, 52, 54
sort
merge, 178
selection, 177
source code, 3, 9
src
...
it-ebooks
...
err, 62, 98, 209
System
...
out, 29, 117, 205
int, 13
long, 19, 44
object, 145
String, 5, 13, 131
void, 45
type cast, 35, 39
T
UML, 138, 140, 197
Unicode, 118, 125
unit test, 208, 210
utility class, 30, 106
utility method, 122
U
table, 90
two-dimensional, 92
tag, 78, 83
temporary variable, 72, 82, 225
terminal, 203
testing, 182
text editor, 201, 210
this, 147, 187
Time, 146
addition, 154
toCharArray, 119
token, 31, 39
toLowerCase, 118
top-down development, 177, 181, 192, 194
Torvalds, Linus, 8
toString, 151
toUpperCase, 118
traversal, 107, 112
traverse, 119, 169
Turing complete, 79, 83
Turing, Alan, 79, 118
type, 24
array, 103
boolean, 57
char, 13, 117
double, 17
234
|
V
value, 13, 24
value constructor, 148
value method, 71, 72, 82
variable, 13
instance, 146
local, 49
loop, 93, 105, 119
private, 146, 149
static, 164
temporary, 72, 225
virtual machine, 3, 201
void, 45, 71
void method, 71
W
while, 89
wildcard, 206, 210
wrapper class, 123, 125
wrapper method, 188, 198
Index
www
...
info
About the Authors
Allen Downey is a Professor of Computer Science at Olin College of Engineering
...
C
...
He has a Ph
...
in Computer Science from U
...
Berkeley and Master’s and Bachelor’s
degrees from MIT
...
He has
a Ph
...
in Computer Science from Purdue University and Bachelor’s degrees in CS
and German from the University of Utah
...
It is a large bird native to Australia, found in many habitats such as forests, open
plains, or riverlands, often nesting in eucalyptus trees
...
They are typically around 2 feet in length and weigh
between 1–2 pounds
...
This allows them to grab and manipulate
objects with one foot while gripping a branch with the other
...
The diet of the red-tailed black cockatoo is primarily made of up of eucalyptus seeds,
though it will also eat nuts, fruits, insects, and various grains
...
However, this species
is typically very shy around humans
...
In addition, while Australia requires a special license to keep and breed these
birds, they are still affected by illegal smuggling for the pet trade—they can have long
lifespans in captivity and are in high demand
...
To learn more about how you can help, go to animals
...
com
...
The cover fonts are URW
Typewriter and Guardian Sans
...
www
...
info
Title: Think Java
Description: Currently used at many colleges, universities, and high schools, this hands-on introduction to computer science is ideal for people with little or no programming experience. The goal of this concise book is not just to teach you Java, but to help you think like a computer scientist. You'll learn how to program - a useful skill by itself—but you'll also discover how to use programming as a means to an end. Authors Allen Downey and Chris Mayfield start with the most basic concepts and gradually move into topics that are more complex, such as recursion and object-oriented programming. Each brief chapter covers the material for one week of a college course and includes exercises to help you practice what you've learned.
Description: Currently used at many colleges, universities, and high schools, this hands-on introduction to computer science is ideal for people with little or no programming experience. The goal of this concise book is not just to teach you Java, but to help you think like a computer scientist. You'll learn how to program - a useful skill by itself—but you'll also discover how to use programming as a means to an end. Authors Allen Downey and Chris Mayfield start with the most basic concepts and gradually move into topics that are more complex, such as recursion and object-oriented programming. Each brief chapter covers the material for one week of a college course and includes exercises to help you practice what you've learned.