Guia para Programar en Java
Guia para Programar en Java
PROGRAMMING IN
Java
A Guide to Programming
in Java
Java
Corporation.
Sun
, Sun
Microsoft
Windows
, Visual Basic
, and Microsoft
Calculator are
either registered trademarks or trademarks of Microsoft Corporation in the United
States and/or other countries. Screen Shots and Icons reprinted with permission
from Microsoft
Corporation.
Mac OS
4, Itanium
2, and Opteron.
The Intel Pentium 4 (P4) CPU
has a clock rate of 3.06 GHz.
The AMD Opteron CPU has a
clock rate of 2.4 GHz. These
CPUs contain more than 40
million transistors on a single
chip.
Real-time Clock
A battery chip called a real-
time clock keeps track of the
date and time in a computer
even when the computer is
off.
Chapter 1 An Introduction to Computers 3
s
a
m
p
l
e
real time. A multiuser OS is supported by mainframes and minicomputers
and allows for two or more users at the same time. The terms multiprocessing
and multitasking are often used interchangeably when referring to an
OS that allows for multiple applications (processes or tasks) to run
at the same time. This type of OS determines how to divide processor
time between running applications. A multiprocessing OS should not be
confused with a multiprocessing computer system, which has more than
one processor and performs parallel processing because the processors are
used simultaneously for multiprocessing. Multithreading refers to an OS
that can execute different parts of a single program, called threads, at the
same time. A real-time OS responds to input immediately. This type of
OS is used in situations where immediate feedback is required, such as
navigation systems or medical monitoring equipment.
Environment refers to a computers hardware and software configura-
tion. For example, a Windows XP environment means that the computer is
running the Windows XP Professional OS software and hardware includes
a 300MHz processor or better, 128MB of RAM or more, and at least 1.5GB
of hard disk space. The hardware requirements are based on what will
be needed to allow the OS software to properly manage the computers
tasks. The term platform is sometimes synonymous with environment.
Environment types vary widely and can refer to the computer type or
the way the user interacts with the computer as well as the software/hard-
ware configuration. A desktop environment refers to a desktop or notebook
computer running an OS designed for the typical hardware found in a
desktop or notebook computer. A multiuser environment is sometimes called
time sharing because each user gets a portion of the processors time.
A distributed environment shares the load of processing among several
computers. When discussing environments, a distinction is usually made
between multiprocessing and multitasking. A multiprocessing environment
means that more than one processor is being used for executing an appli-
cation, and a multitasking environment is one in which processing time for
multiple applications is divided among one processor. Most environments
run an OS with a graphical user interface (GUI):
Windows XP Operating System
Mainframes and
Supercomputers
A mai nf r ame i s a l ar ge
computer system that supports
multi-user applications and
tasks that require the storage
and pr ocessi ng of huge
amounts of information. Large
corporations, airlines, banks,
government agencies, and
universities use mainframes.
A supercomputer is the fastest
and most powerful type of
computer. Supercomputers
focus on executing a few
programs as fast as possible
and are used for weather
forecasting and nuclear energy
research.
TIP For information on a
specific operating system, refer
to the appropriate chapter at
Lvp.com.
4 Chapter 1 An Introduction to Computers
s
a
m
p
l
e
The functions of an OS are based on the intended OS platform.
Functionality is implemented through utility programs that are written
as part of the OS. A utility program has one clearly defined task, unlike
an application which can usually perform many different tasks. Utility
programs are run by the OS to manage input and output, read and write
to memory, manage the processor, maintain system security, and manage
files and disks. One type of utility program, called a device driver, is needed
for printing, viewing graphics, using a CD/DVD drive, and using periph-
erals in general. Some utility programs load when the computer starts and
are called memory-resident because they are always in memory.
Features are added to an OS by incorporating utility programs to per-
form tasks that are in addition to the tasks required to run the computer.
For example, an OS intended for a desktop or notebook environment will
often include utilities for disk defragmentation, text narration and other
accessibility tools, and system restore and backup tools. For example:
Windows XP Utilities
Mobile Computing
Improved technology has allowed the miniaturization of computer
components and special long-lasting batteries. Computers now come
in many shapes, sizes, and with many levels of features. Among these
computers are notebooks, tablets, handhelds, smart phones, and wearables.
Because of their portability, these types of computers are classified as
mobile computing devices:
A notebook computer is a portable, lightweight computer with a
CPU, memory, and hard disk space comparable to that of a typical
desktop computer.
A tablet PC is a computer designed similar to a pad of paper and
a pencil. Users simply write on a screen with a device called a
stylus that is shaped like a thin pencil. Handwriting recognition
software is used to interpret a users handwriting. A keyboard can
also be attached.
Bluetooth
Bl uet oot h i s a wi r el es s
technology used to allow
mobile computing devices to
communicate.
utility program
memory-resident
Chapter 1 An Introduction to Computers 5
s
a
m
p
l
e
Handheld computers, also called PDAs, are palm-sized and contain
applications for storing contact information, schedules, lists, and
games. Handhelds come with a stylus for input and have a screen
that is several inches vertically. Many types of application software
have been written for handhelds, including spreadsheets and word
processors. Some handhelds recognize handwriting, have a built-in
keyboard, include a cellular phone, and provide Internet access.
Smartphones are cellular phones that are able to send and receive
e-mail messages and access the Internet. Some smartphones have
digital camera, MP3 player, and color display capabilities.
Wearable computers vary greatly in size and application. MP3 play-
ers have been incorporated into clothing, and one type of wearable
computer includes voice recognition. Wearable computers are also
in the form of goggles, which incorporate a monitor, digital camera,
ear bud, and microphone. Wrist-top computers are worn like a tra-
ditional wrist watch and work as a pager, provide Internet access,
and contain other features usually found in a handheld PC.
One issue involved with using so many types of PCs is cross-platform
connectivity, which is the ability for one type of PC to link to and share
data with a different type of PC. Notebook and desktop PCs typically have
good cross-platform connectivity because their file formats can be used on
either computer. Tablets and handhelds use a different OS and generate
different file formats, requiring special hardware and software to use their
files on a desktop or notebook PC. Wearable computers typically have a
cable that allow a connection to other types of PCs, but special software
must be used to communicate between the devices.
Programming Languages
A programming language is a set of words, codes, and symbols that allow
a programmer to give instructions to the computer. Many programming
languages exist, each with their own rules, or syntax, for writing these
instructions.
Programming languages can be classified as low-level and high-level
languages. Low-level programming languages include machine language
and assembly language. Machine language, which is referred to as a first
generation programming language, can be used to communicate directly
with the computer. However, it is difficult to program in machine language
because the language consists of 0s and 1s to represent the status of a
switch (0 for off and 1 for on). Assembly language uses the same instruc-
tions and structure as machine language but the programmer is able to
use meaningful names or abbreviations instead of numbers. Assembly
language is referred to as a second generation programming language.
High-level programming languages, which are often referred to as third
generation programming languages (3GL), were first developed in the late
1950s. High-level programming languages have English-like instructions
and are easier to use than machine language. High-level programming
languages include Fortran, C, Basic, COBOL, and Pascal. In order for the
computer to understand a program written in a high-level language, pro-
grammers convert the source code into machine language using a compiler
or an interpreter. A compiler is a program that converts an entire program
Fourth and Fifth
Generation Languages
Fourth generation languages
(4GL) , such as SQL, have
higher English-like instructions
than most high-level languages
and are typically used to access
databases. Fifth generation
languages are used for artificial
intelligence.
Handheld Computers
Handheld comput er s are
widely used in occupations
that require constant travel,
such as parcel delivery, meter
reading, and sales.
cross-platform connectivity
6 Chapter 1 An Introduction to Computers
s
a
m
p
l
e
into machine code before the program is executed. An interpreter translates
and executes an instruction before moving on to the next instruction in
the program.
In the 1980s, object-oriented programming (OOP) evolved out of the need to
better develop complex programs in a systematic, organized approach. The
OOP approach allows programmers to create modules that can be used
over and over again in a variety of programs. These modules contain code
called classes, which group related data and actions. Properly designed
classes encapsulate data to hide the implementation details, are versatile
enough to be extended through inheritance, and give the programmer
options through polymorphism. Object-oriented languages include Java,
C++ and Visual Basic .NET.
Networks
A network is a combination of hardware and software that allows
computers to exchange data and share software and devices, such as
printers. Networks are widely used by businesses, universities, and other
organizations because a network:
allows users to reliably share and exchange data
can reduce costs by sharing devices such as printers
offers security options including password protection to restrict
access to certain files
simplifies file management through centralized software updates
and file backups
provides e-mail for network users
Networks are classified by their size, architecture, and topology. A
common size classifications is LAN (Local-Area Network), which is a
network used to connect devices within a small area such as a building or
a campus. A WAN (Wide-Area Network) is used to connect devices over
large geographical distances. A WAN can be one widespread network or
it can be a number of LANs linked together.
The computers and other devices in a LAN each contain an expansion
card called a network interface card:
Network interface card
MAN and HAN
A MAN (Metropolitan Area
Network) and a HAN (Home
Area Network) are network
technologies classified by the
size of a network. A MAN is a
high-speed network that typi-
cally connects LANs within a
city or town. A HAN is used
to connect personal devices
within the home.
interpreter
object-oriented programming
Chapter 1 An Introduction to Computers 7
s
a
m
p
l
e
A cable plugs into the adapter card to connect one device to another to
form a LAN. Cables are not required for network cards that have wireless
capabilities. Network interface cards are available for desktop and mobile
computers and take various other forms including an adapter card, a PC
card, or a Flash memory card
Along with the physical, or hardware, aspects of setting up a network,
there is also the software aspect. A network operating system is software that
allow users and devices to communicate over the network. A networked
environment refers to a set of networked computers running an OS that can
handle the communication between the computers. The operating system
installed must be capable of supporting networking functions, such as
security access features and support for multiple users. Operating systems
capable of network functions are available for Linux, Windows, Unix, and
Mac. The network architecture, discussed next, must also be considered
when choosing a network OS.
Network architecture includes the type of computers on the network and
determines how network resources are handled. Two common models are
peer-to-peer and client/server. In a peer-to-peer network, each computer on
the network is considered equal in terms of responsibilities and resource
sharing. A client/server network consists of a group of computers, called
clients, connected to a server. A server is a computer with more RAM, a
larger hard disk, and sometimes multiple CPUs that is used to manage
network functions.
Physical topology refers to the arrangement of the nodes on a network.
A node is a location on the network with a device capable of processing
information, such as a computer or a printer. There are three common
physical topologies:
The bus topology is a physical LAN topology that uses a single cen-
tral cable, called the bus or backbone to attach each node directly:
LAN using a bus topology
Ethernet
The Ethernet LAN protocol was
developed by Bob Metcalfe in
1976. Ethernet uses a bus or
star topology with twisted-
pair wiring, coaxial cable,
or fiber optic cable transmis-
sion media. Newer protocols
include Fast Ethernet, which
operates at 100 Mbps, Gigabit
Ethernet which operates at
1 Gbps, and 10G Ethernet,
which operates at 10 Gbps.
Transmission Media
Comput ers must be con-
nected in order to transmit
data between the nodes. Cable
transmission media includes
twisted-pair wiring, coaxial
cable, and fiber optic cable.
Wireless transmission media
includes inf rared signals,
broadcast radio, cellular radio,
microwaves, and communica-
tions satellites.
The amount of data and the
speed at which data can travel
over a media is called band-
width, which is measured in
bits per second (bps). Each
transmission media has a spe-
cific length or range restric-
tion, data transmission rate,
and cost.
8 Chapter 1 An Introduction to Computers
s
a
m
p
l
e
In a star topology, each node is attached to a hub, which is a device that
joins communication lines at a central location on the network:
LAN using a star topology
In a ring topology, each node is connected to form a closed loop.
A LAN with a ring topology can usually cover a greater distance
than a bus or star topology:
LAN using a ring topology
Wireless networks use high frequency radio waves or infrared sig-
nals instead of cables to transmit data. A router/wireless access
point device is used to allow nodes to transfer data wirelessly.
Another type of topology is logical topology, which refers to the way data
is passed between the nodes on a network. A LANs logical topology is
not always the same as its physical topology.
Baseband and
Broadband Technology
Most LANs use baseband
technology which means the
transmission media carries one
signal at a time. Broadband
technology allows for data
transmission of more than one
signal at a time and is found in
cable television transmission.
Wi-Fi
Wi-Fi (Wireless Fidelity) is
a term used to describe an
802.11 network, which is a
specification or protocol for
wireless networks.
logical topology
Chapter 1 An Introduction to Computers 9
s
a
m
p
l
e
Network users are given a user name and password to log on to a
network through a computer connected to the network. Users are also
assigned a level of access to maintain security. Network users should
follow a certain etiquette referred to as netiquette:
Do not attempt to access the account of another user without
authorization.
Do not share your password, and change it periodically.
Use appropriate subject matter and language, and be considerate
of other peoples beliefs and opinions.
Number Systems
The electrical circuits on an IC have one of two states, off or on. Therefore,
the binary number system (base 2), which uses only two digits (0 and 1), was
adopted for use in computers. To represent numbers and letters, a code
was developed with eight binary digits grouped together to represent a
single number or letter. Each 0 or 1 in the binary code is called a bit (BInary
digiT) and an 8-bit unit is called a byte.
Our most familiar number system is the decimal, or base 10, system. It
uses ten digits: 0 through 9. Each place represents a power of ten, with
the first place to the left of the decimal point representing 10
0
, the next
place representing 10
1
, the next 10
2
, and so on (remember that any number
raised to the zero power is 1). In the decimal number 485, the 4 represents
410
2
, the 8 represents 810
1
, and the 5 represents 510
0
. The number 485
represents the sum 4100 + 810 + 51 (400 + 80 + 5):
Decimal Base 10 Equivalent
485 410
2
+ 810
1
+ 510
0
= 400 + 80 + 5
The binary, or base 2, system works identically except that each place
represents a power of two instead of a power of ten. For example, the
binary number 101 represents the sum 12
2
+ 02
1
+ 12
0
or 5 in base ten.
Some decimal numbers and their binary equivalents are:
Decimal Binary Base 2 Equivalent
0 0 = 02
1
+ 02
0
= 02 + 01 = 0 + 0
1 1 = 02
1
+ 12
0
= 02 + 11 = 0 + 1
2 10 = 12
1
+ 02
0
= 12 + 01 = 2 + 0
3 11 = 12
1
+ 12
0
= 12 + 11 = 2 + 1
4 100 = 12
2
+ 02
1
+ 02
0
= 14 + 02 + 01 = 4 + 0 + 0
The hexadecimal system is used to represent groups of four binary
digits. The hexadecimal, or base 16, system is based on 16 digits: 0 through
9, and the letters A through F representing 10 through 15 respectively.
Each place represents a power of sixteen. For example, the hexadecimal
number 1F represents the sum 116
1
+ 1516
0
. Some decimal numbers and
their hexadecimal equivalents are:
Decimal Binary Hexadecimal Base 16 Equivalent
0 0000 0000 0 = 016
0
= 01 = 0
10 0000 1010 A = 1016
0
= 101 = 10
25 0001 1001 19 = 116
1
+ 916
0
= 116 + 91 = 16 + 9
30 0001 1110 1E = 116
1
+ 1416
0
= 116 + 141 = 16 + 14
binary number system
bit
byte
base 10
base 2
base 16
netiquette
10 Chapter 1 An Introduction to Computers
s
a
m
p
l
e
For clarity, a non-base 10 number should have the base subscripted after
the number. For example, to show the difference between 100 in base 10
and 100 in base 2 (which represents 4), the base 2 number should be writ-
ten as 100
2
.
Every letter of an alphabet (Latin, Japanese, Cherokee, and so on) and
symbols of every culture (=, @, , and so on) have been given a representa-
tion in a digital code called Unicode. Unicode uses a set of sixteen 1s and 0s
to form a 16-bit binary code for each symbol. For example, the uppercase
letter V is Unicode 00000000 01010110, which can be thought of as the base
10 number 86 (86
10
). Lowercase v has a separate code of 00000000 01110110,
or 11810.
Storing Data in Memory
Computer memory is measured in bytes. For example, a computer might
have 512MB of RAM. In computers and electronics MB stands for megabytes
where mega represents 2
20
or 1,048,576 bytes and GB stands for gigabytes,
which is 2
30
or 1,073,741,820 bytes.
Data stored in memory is referred to by an address. An address is a
unique binary representation of a location in memory. Therefore, data
can be stored, accessed, and retrieved from memory by its address. For
data to be addressable in memory, it must usually be at least one byte in
length. For example, to store JIM in memory each character is converted
to Unicode and stored in two bytes of memory with each memory location
designated by its address:
Because JIM is a character string, it will probably be stored in adjacent
memory addresses.
Bits grouped in units of 16 to 64 (2 to 8 bytes) are called words. Data
stored in a word is also located by an address. The size of a word depends
on the computer system.
The binary representation of an integer number is usually stored in four
bytes of memory. Because an integer is stored in four bytes, the range of
integers that can be stored is 2,147,483,648 to 2,147,483,647. An overflow error
occurs when the number of bits that are needed to represent the integer is
greater than the size of four bytes.
Real numbers, also called floating point numbers, are numbers that contain
decimal points. The binary representation of a real number is usually 4 to
8 bytes of memory. The binary number 111.10 is equivalent to the real deci-
mal number 7.5 and is stored in memory as the binary number 0.111102
3
.
In this form, the bits that represent the mantissa (fractional part) are stored
in one section of a word and the exponent, in this example 3 (11
2
), is stored
in another section of the word:
ASCII and EBCDIC
ASCII (American Standard
Co d e f o r I nf o r ma t i o n
Interchange) and EBCDIC
( Ext ended Binar y Coded
Decimal Interchange Code)
are two other digital coding
schemes. Unlike Unicode,
ASCII and EBCDIC are not
large enough to support Asian
and other languages that use a
different alphabet.
words
overflow error
real numbers
mantissa
exponent
Chapter 1 An Introduction to Computers 11
s
a
m
p
l
e
The overflow problem discussed for integers can also occur in real
numbers if the part of the word storing the exponent is not large enough.
A roundoff error occurs when there are not enough bits to store the
mantissa.
What is a File?
A file is related data stored on a persistent media. A file can be an appli-
cation (program) or the product of an application. For example, a word
processor application is used to create document files. As another example,
a digital camera is used to create photo files. A file is stored on a persistent
media so that it is retained even after the computer or computerized device
is turned off. A file can be used over and over again whenever the data it
stores is needed.
A file is really just 1s and 0s because it is stored in binary code. Computers
are programmed to translate bytes and words into symbols. Depending
on the file type, these symbols are either human-readable or computer-
readable after translation. Human-readable files are called text files, and
computer-readable files are called binary files. Simple files, such as a text
document, can be measured kilobytes, for example 64K. The K comes from
the word kilo and represents 2
10
or 1,024. Therefore, a 64K file uses 65,536
bytes (642
10
) of storage.
File types are distinguished by the extension that comes after the file
name. An application adds a unique extension to the files it creates. For
example, MyResume.doc is a document file type. A DOC file is a binary file
created by Microsoft Word. Executables are EXE files and are also binary
files. A file named TestData.txt is a plain text file. A TXT file contains
only letters, numbers, and common symbols readable by humans. Folders
are used to organize commonly related files.
Binary files are more complex than text files and often contain data for
photos, formatted text, spreadsheets, sound, and so on. The disadvantage
of binary files is that they require another application to interpret the
contents. A binary file may have content similar to:
U_}9UT}]__
U_ wu s U U w] U/ U_ U Wwwt wwU WwwD
UET_w
_wuUuWw{uWwwuuuUUwwDl
>~
UUU]UU]U]]D
W__W_]uDwuWuWUUwWUwD
pseudocode
flowcharts
Chapter 3 Introducing Java 67
s
a
m
p
l
e
Each flowchart symbol has a different meaning. The indicates start
or end. The shape indicates input/ouput. Other flowchart symbols
will be introduced throughout the text as new concepts are covered.
Chapter Summary
This chapter introduced Java, which is an object-oriented program-
ming language. OOP languages evolved out of the need to better develop
complex programs. In addition to being object-oriented, Java is platform
independent. Platform-independent applications can run on any computer,
regardless of the operating system or hardware configuration.
Object-oriented languages use classes to define objects. A class defines
the type of data and actions associated with an object, but not the actual
data for an object. A package groups related classes.
A Java application is a package with at least one class. Statements in an
application provide instructions. Methods are a named set of statements
that perform a single, well-defined task. Comments in an application
provide details about the code to the reader. Comments can be single or
multiline and can also be extracted for documentation.
The code typed by a programmer is called source code. The source code
is translated to bytecode with a compiler. Program execution occurs when
the bytecode is interpreted with a Java Virtual Machine (Java VM). The
Java VM can reside on any computer. A just-in-time (JIT) compiler converts
bytecode to machine code before execution by the Java VM. Although
less portable, machine code is faster. If a program contains errors, it will
not compile. One type of error is the syntax error, which results when a
statement violates the rules of Java.
Program output is through the output stream. The standard output
stream is typically the computer screen and requires the System.out meth-
ods print() and println(). These methods require a string argument.
Escape sequences are used to display special characters. Output can be
formatted with the format() method.
Code conventions are a set of guidelines for writing an application. The
code conventions introduced in this chapter are:
An introductory comment should begin a program. This comment
should include information such as your name, class name, the
date, and a brief statement about the program.
Package names should begin with a lowercase letter and then an
uppercase letter should begin each word within the name. Package
names may not contain spaces.
Class names should be nouns and begin with an uppercase letter
and then an uppercase letter should begin each word within the
name. Class names may not contain spaces.
A comment block should be included before each class and
method. A comment block is not typically placed before the main()
method.
68 Chapter 3 Introducing Java
s
a
m
p
l
e
Comments should not reiterate what is clear from the code.
Statements in a method should be indented.
An open curly brace ({) should be placed on the same line as
the class or method declaration, and the closing curly brace (})
should be on a separate line and aligned with the class or method
declaration.
Programs are created to solve problems. However, problems of any
complexity require outlining, or designing, a solution before typing any
source code. One method of design is called an algorithm. An algorithm
can be implemented through steps written in plain English, steps written
in a mixture of code and English called pseudocode, or steps presented
visually with a flowchart.
Chapter 3 Introducing Java 69
s
a
m
p
l
e
Vocabulary
Algorithm A set of steps that outline how to solve
a problem.
Argument Dat a passed to a met hod for
processing.
Bytecode Compiled Java source code.
Class The description of an object.
Code conventions A set of guidelines for writing
an application.
Comment Text that provides information to the
reader of program code.
Comment block Multiline comments that describe
a program, class, or method.
Compiling The process where source code is con-
verted to code the computer understands.
Controlling class The class in an application that
contains the main() method.
Encapsulation An object-oriented language
feature.
Escape Sequence A backslash followed by a symbol
that together represent a character.
Execute To run a program.
Flowchart A vi sual representat ion of an
algorithm.
Importable Package code that can be used by an
application.
Inheritance An object-oriented language feature.
Interpreter Software that runs each bytecode
instruction of a compiled Java program.
Java application A package with a controlling class
and possibly other classes.
Java Virtual Machine (Java VM) The Java bytecode
interpreter.
Just-in-time compiler (JIT) Software that converts
bytecode to specific machine code.
Library see Package.
Machine code The most basic computer language,
which is comprised of just 1s and 0s.
Method A named set of statements that perform
a single, well-defined task. A method is always a
member of a class.
Object A named entity that consists of related
data and instructions for performing actions on
that data.
Object- oriented programmi ng ( OOP) A
systematic, modular approach to developing complex
programs.
OOP see Object-oriented programming.
Output Stream Sends data to an output device,
typically the computer screen.
Package A group of related classes. Also called a
library.
Platform-independent application A program that
can be run on any computer regardless of operating
system or hardware configuration.
Polymorphism An object-oriented language
feature.
Pseudocode An algorithm written in a mix of
English and program code.
Run see Execute.
Source code The code typed by a programmer.
Statement An instruction in a program.
String A set of characters.
Syntax error A statement that violates the rules
of Java.
70 Chapter 3 Introducing Java
s
a
m
p
l
e
Java
/* */ Used to enclose single or multiline
comments.
/** */ Used to enclose documentation
comments.
// Used to begin a single line comment.
{ } Used to begin and end a set of related
statements.
; Required at the end of each program statement.
\\ Escape sequence for displaying a backslash.
\" Escape sequence for displaying a double quota-
tion mark.
\n Escape sequence for displaying a newline.
\t Escape sequence for displaying a tab.
class Used to declare a class.
format() Method that displays more precisely for-
matted output to the screen.
java.lang.System The class that contains the out
member.
main() The method in the controlling class that
is automatically executed when a Java application
is run.
out The java.lang.System member that represents
the standard output stream.
package Statement used to declare a package.
print () Method that displays output to the
screen.
println() Method that displays output to the
screen and then moves the insertion point to the
next line.
public An access modifier that declares a class or
method as available to any code.
static A declaration used for class methods.
void Indicates a method will not return a value.
Chapter 3 Introducing Java 71
s
a
m
p
l
e
Critical Thinking
1. a) List three features of every object-oriented
programming language.
b) Explain, in your own words, what you think
the meaning is of each of the three features
listed in part (a).
2. Draw a sketch that shows the relationship, and/
or hierarchy, of object, class, and package for the
package File, class FileReader, and the object
fileInput.
3. Write an appropriate comment block for the
beginning of a program to describe an applica-
tion that is intended to calculate test averages.
4. Write an appropriate comment for describ-
ing a class that displays the average of a set of
scores.
5. Write a statement that declares a package with
the name gradeCalculator.
6. Write a statement that declares a class named
AverageScore that is available to any code.
7. Explain the difference between source code and
bytecode.
8. Describe machine code.
9. Explain the difference between a Java compiler
and the Java VM.
10. What is the advantage of compiling Java source
code using a JIT?
11. The following application has seven syntax
errors. What are they?
//
* Test.java
* What's wrong application.
* Student Name
*/
package testMyKnowledge;
/**
* The Test class should display a string,
*/
public class Test {
private static int main(string[] args) {
System.out.println("Testing...)
}
12. Explain the difference between the print() and
println() methods.
13. Explain the advantages of using the format()
method in place of the print()and println()
methods.
14. There are five places in which the application
below does not follow the code conventions
outlined in this chapter. Where are they?
/*
* getGreeting.java
* What's wrong application.
* Student Name
*/
package notSoGood;
/**
* Good Morning is displayed.
*/
public class getGreeting {
public static void main(String[] args) {
//Output Good Morning to the screen
System.out.println("Good Morning");
} }
15. Explain the similarities and differences between
pseudocode and a flowchart.
True/False
16. Determine if each of the following are true or
false. If false, explain why.
a) Java applications can run only on the
Windows platform.
b) Statements must end with a semicolon.
c) Comments have no effect on program
execution.
d) The mai n() met hod i s pl aced i n t he
controlling class.
e) Related statements are enclosed with brackets
([]).
f) A file containing only source code can be
executed on a computer.
g) Compiled source code is called machine
code.
h) A program containing syntax errors will
compile.
i) An algorithm is a set of steps that outline
how to solve a problem.
j) Pseudocode cannot be used to implement an
algorithm.
72 Chapter 3 Introducing Java
s
a
m
p
l
e
Exercises
Exercise 1 BingoCard
Create a BingoCard application that displays a traditional bingo card with five columns of five unique
numbers. The column labels are B, I, N, G, and O. Column B contains numbers ranging from 1 through
15, column I has numbers ranging from 16 through 30, column N has four numbers ranging from 31
through 45 and a Free Space in the middle of the column, column G has numbers ranging from 46
through 60, and column O has numbers ranging from 61 through 75. The application output should
look similar to:
Exercise 2 BingoRules
Create a BingoRules application that displays the rules for playing bingo. Place each rule on a separate
line and place a blank line between rules. The application output should look similar to:
Exercise 3 Rectangle
Create a Rectangle application that displays a rectangle of asterisks (*). The rectangle should be 15
asterisks wide and 7 asterisks high. The application output should look similar to:
Chapter 3 Introducing Java 73
s
a
m
p
l
e
Exercise 4 RockPaperScissorsRules
Create a RockPaperScissorsRules application that displays the rules for playing Rock Paper Scissors.
Place each rule on a separate line and place a blank line between rules. The application output should
look similar to:
Exercise 5 TicTacToeBoard
Create a TicTacToeBoard application that displays a tic-tac-toe board with an X in the center. The appli-
cation output should look similar to:
Exercise 6 TicTacToeRules
Create a TicTacToeRules application that displays the rules for playing tic-tac-toe. Place each rule on a
separate line and place a blank line between rules. The application output should look similar to:
74 Chapter 3 Introducing Java
s
a
m
p
l
e
Exercise 7 Smile
Create a Smile application that displays a smiling face made of keyboard characters. The application
output should look similar to:
Exercise 8 JavaTerminology
Create a JavaTerminology application that displays at least five words from the vocabulary list in this
chapter and the corresponding definition. Place each word on a separate line followed by the definition.
Place a blank line between entries. The application output should look similar to:
Exercise 9 FlowchartSymbols
Create a FlowchartSymbols application that illustrates the two flowchart symbols that were introduced
in this chapter. The application output should look similar to:
Chapter 3 Introducing Java 75
s
a
m
p
l
e
Exercise 10 CompilerDocumentation
Create a CompilerDocumentation application that creates compiler-specific documentation for the
compiler you will be using in your class.
a) Add the compiler name to the right of Compiler and then explain how to create a new
project, enter source code, compile, and run a Java application using a format similar
to:
b) Explore the compilers help features. Add documentation that explains how to use
the compilers Help features.
Exercise 11 BinaryNumbers
As discussed in Chapter 1, computers are digital and they recognize two states: on and off. Therefore, the
binary number system (base 2), which uses only two digits (0 and 1), was adopted for use in computers.
Our most familiar number system is the decimal, or base 10, system. It uses ten digits: 0 through 9.
a) Create a BinaryNumbers application that illustrates the binary numbers 1 through
20 and their decimal equivalents. Refer to chapter 1 for the conversion formula or if
you have the Windows operating system, use the Microsoft Calculator in the Start j
All Programs j Accessories menu to convert the numbers. In the Microsoft Calculator,
select View j Scientific and then enter the number and select Bin to convert the decimal
(Dec) number:
76 Chapter 3 Introducing Java
s
a
m
p
l
e
The application output should look similar to:
b) The hexadecimal, or base 16, system is based on 16 digits: 0 through 9, and the letters
A through F representing 10 through 15 respectively. Modify the BinaryNumbers
application to include a Hexadecimal column that contains the corresponding
hexadecimal numbers.
Exercise 12 ProgrammingLanguages
a) Create a ProgrammingLanguages application that displays information about object-
oriented programming languages. The application output should look similar to:
b) Use books and the Internet to research other object-oriented programming languages
and add three additional object-oriented programming languages to the list.
Chapter 4 Variables and Constants 77
s
a
m
p
l
e
Variables and constants are two important concepts explained in this
chapter. Using primitive and abstract data types to declare variables is
covered. User input, numeric expressions, and assignment operators are
also discussed.
Declaring Variables
A variable is a name for a value stored in memory. Variables are used in
programs so that values can be represented with meaningful names. For
example, when a variable named length is used in a program, it is clear
that its value is a distance. Variables should be used to represent values
because they make code easier to read, understand, and modify.
A variable must be declared before it is used. A declaration takes the
form:
<type> <name>
The declaration includes two parts. The first is the data type, which
determines the type of data the variable will store. The second part of a
declaration is the variable name, called the identifier. For example, in the
declaration
int length;
int is the data type and length is the identifier. An int stores an integer
value, which is a positive or negative whole number. When an integer
variable is declared it stores the value 0.
An identifier must begin with a letter and contain only letters, numbers,
and some special characters. Typically variable identifiers begin with a
lowercase letter. Any word after the first in a variable identifier should
begin with an uppercase letter. For example, rectangleLength. This code
convention allows variables to be easily recognized.
Multiple variables with the same data type can be declared in a single
statement, similar to:
int length, width;
Grouping variables together in a single statement is good programming
style when the variables represent related items. Declarations should not
be grouped together in the same statement just because the variables are
all the same type.
Chapter 4
Variables and Constants
data type
declaration
identifier
78 Chapter 4 Variables and Constants
s
a
m
p
l
e
Using Variables
Applications typically contain many variables, as in RectangleArea:
/**
* Calculates and displays the area of a rectangle
*/
public class RectangleArea {
public static void main(String[] args) {
int length = 10; //longer side of rectangle
int width = 2; //shorter side of rectangle
int area; //calculated area of rectangle
area = length * width;
System.out.println("Area of rectangle: " + area);
}
}
RectangleArea produces output similar to:
Variable declarations should be grouped at the beginning of a method.
A blank line after the declarations makes it easy to determine where the
declarations end.
The value of a variable is changed through assignment. An assignment
statement is formed with the variable name on the left side of an equal
sign and the value it is to receive on the right side of the equal sign. The
equal sign (=) is an operator that indicates that the variable on the left is to
receive the value on the right. The value on the right can be a literal, which
is any actual value. It could also be another variable or an expression. For
example, area was assigned the value of the length multiplied by the width
(length * width). Note that the * symbol indicates multiplication.
An assignment statement can be part of a variable declaration. In addition
to being declared, the variable is initialized. For example, in RectangleArea,
variables length and width were assigned values when declared.
A System.out.println() statement can be used to output the value of
a variable. Variable identifiers are not enclosed by quotation marks. To
append, or concatenate, the value of a variable to a string, the + operator
is used. The + operator converts the value of the variable to a string and
then concatenates the strings before output.
It is important to realize that a variable can store only one value at any
one time. For example, after the following statements execute
int x;
x = 5;
x = 10;
the value of x is 10 because this was the last value assigned to x.
assignment
concatenation
equal sign
literal
initialize
Chapter 4 Variables and Constants 79
s
a
m
p
l
e
Review: RectanglePerimeter
Create a RectanglePerimeter application that calculates and displays the perimeter of a rectangle with width
4 and length 13. The perimeter of a rectangle is calculated as 2w + 2l. Use variables as appropriate.
Primitive Data Types
The int data type is called a primitive data type. A variable that is
defined with a primitive data type stores a single piece of data. Java supports
several primitive data types, including:
Type Bytes Data Range
int 4 a positive or negative integer from 2,147,483,648
to 2,147,483,647
double 8 a positive or negative number that may contain
a decimal portion in the range 1.7E+308 to
1.7E+308
char 2 a single character
boolean true or false
An int variable uses 4 bytes of memory to store its value and is used
for representing whole numbers.
Values that are represented by the double data type are sometimes
referred to as floating point, meaning that the values contain numbers after
the decimal point. Because of the many digits that are possible in a double,
a variable of this type uses 8 bytes of memory.
A char variable requires 2 bytes of memory because Java uses the 16-
bit Unicode character encoding. Assignment to a char variable requires
enclosing a single character in single quotation marks, as in 'a'.
Variables that are type boolean can have only one of two valuestrue
or false. Boolean variables are particularly useful for representing yes/no
or on/off values.
When choosing a data type, it is important to choose the most appropri-
ate type for the quantity being represented. If a value could possibly have
a decimal portion, then double is the best choice. If a variable will represent
only whole numbers, then int is the best choice even though double will
work. Using the most appropriate data types for variables has two benefits.
First, both the compiler and the reader will understand the possible values
for a variable. Second, the compiler allocates the appropriate memory for
the variable.
Review: Distance part 1 of 2
Create a Distance application that calculates and displays the total distance of a race with three segments.
The first segment is 12.2 km, the second is 10.6 km, and the third is 5.8 km. Use variables of the appropriate
type.
String Data
Strings are comprised of a set
of characters and therefore
cannot be represented by a
primitive data type. The String
class in the java.lang package
is used to create string vari-
ables. Strings are discussed in
more detail in Chapter 6.
TIP Java also supports the
byte, short, long, and float
primitive data types.
floating point
choosing data types
TIP Primitive data types are
also called built-in data types.
80 Chapter 4 Variables and Constants
s
a
m
p
l
e
Abstract Data Types
In addition to primitive data types, a variable can be declared using an
abstract data type. One kind of abstract data type is the class. Many classes
are provided in Java, and many more classes will be created throughout
this text. Each class defines not just a single piece of data like a primitive
data type, but a set of data along with methods for performing actions on
that data.
A variable declared with a class is called an object. The variable itself
actually stores a reference to the area in memory where the objects data
and methods are stored:
Application output should be similar to:
Chapter 5 Conditional Control Structures 129
s
a
m
p
l
e
Exercise 14 BacteriaGrowth
The formula y = ne
kt
can be used for estimating growth where:
y is the final amount
n is the initial amount
k is a constant
t is the time
For example, this formula could be used for estimating population growth in a region or for estimating
cell growth in a lab experiment. Create a BacteriaGrowth application that calculates how many bacte-
ria will be present based on this formula. The application should prompt the user initial bacteria, the
constant k, and the time. Refer to Exercise 12 for documentation for the Math methods for this exercise.
Application output should look similar to:
Exercise 15 Decay
The formula used in Exercise 14 for growth problems can also be used in decay problems. In decay prob-
lems, k is negative. Create an application that allows the user to select from the following options:
calculate the final amount: ne
kt
calculate the initial amount: y / e
kt
calculate the constant (called the half-life): (log (y/n)) / t
(where log e = 0.4343)
The application should prompt the user to select one of the three choices and based on the selected
option prompts the user to enter the appropriate known information. For example, a radioactive mass of
200 grams will reduce to 100 grams in 10 years. Based on this information, the half-life is calculated to
be 0.06931. Refer to Exercise 12 for documentation for the Math methods for this exercise. Application
output should look similar to:
130 Chapter 5 Conditional Control Structures
s
a
m
p
l
e
Exercise 16 TrigFunctions
Create a TrigFunctions application that prompts the user for an angle in degrees and then displays the
sine, cosine, and tangent of the angle. The application should display output similar to:
The Math library provides methods for performing trigonometric functions:
Class Math (java.lang.Math)
Methods
sin(double angle) returns the sine of angle, where angle is in
radians.
cos(double angle) returns the cosine of angle, where angle is
in radians.
tan(double angle) returns the sine of angle, where angle is in
radians.
toRadians(double deg)
converts degrees to radians.
Exercise 17 InverseTrigFunctions
Create an InverseTrigFunctions application that prompts the user for an angle in degrees and then
displays the arcsin, arccos, and arctan of the angle. The application should display output similar to:
The Math library provides methods for performing trigonometric functions:
Class Math (java.lang.Math)
Methods
asin(double s) returns the angle, in radians, that has the
sine s.
acos(double s) returns the angle, in radians, that has the
cosine s.
atan(double s) returns the angle, in radians, that has the
tangent s.
toDegrees(double rad)
converts radians to degrees.
Chapter 6 Loop Structures and Strings 131
s
a
m
p
l
e
Loop structures, counters and accumulators, and flags are explained
in this chapter. Debugging techniques and the String class are also
discussed.
The while Statement
The while statement is a loop structure, which executes a set of statements
over and over again based on a condition. Loop structures are used to
perform tasks such as summing a set of numbers as they are entered by
the user or repeatedly prompting the user for a value until valid data is
entered. The while statement takes the form:
while (<condition>) {
<statements>
}
The condition of the while loop is a Boolean expression, which is evaluated
before the statements are executed. When the condition is true the state-
ments are executed, when the condition is false program flow continues to
the next statement after the closing curly brace of the while. Each execution
of the loop is called an iteration. Note that a while loop may never execute
if the condition initially evaluates to false.
The following while statement executes five times:
int num = 0;
while (num < 5) {
num += 1;
}
After the fifth execution, num is equal to 5, making the condition false.
The do-while Statement
The do-while statement is an alternative form of the while statement. In
the do-while statement the condition is not evaluated until after the first
execution of the loop. Therefore, the do-while executes at least once.
The do-while takes the following form:
do {
<statements>
} while (<condition>);
Chapter 6
Loop Structures and Strings
loop structure
iteration
Nested Loops
A loop structure can contain
another loop structure. Loops
placed within a loop are called
nested loops. Each time the
outer loop iterates, the inner
loop iterates until its condition
is met.
132 Chapter 6 Loop Structures and Strings
s
a
m
p
l
e
The following do-while example prompts the user until a valid number
is entered:
do {
System.out.print("Enter a number less than 4:");
playerNum = input.nextInt();
} while (playerNum >= 4);
Infinite Loops
The condition of a loop is used to determine when the loop should stop
executing. A while continues until its condition is false. What happens,
though, if the condition never becomes false? The result is an infinite
loopone which continues forever. For example, the following generates
an infinite loop. Can you see why?
int num = -1;
while (num < 0) {
num = -1;
}
The code causes the application to simply stop responding or just hang.
When this happens, close the output window to end the application. Note
that some compilers may require a different procedure to end an infinite
loop.
Syntax errors are a common cause of infinite loops. For example, a
semicolon after the condition causes the statement to check the condition,
do nothing, check the condition, do nothing, and on and on:
while (num < 0); { //an infinite loop here--added semicolon
num += 1;
}
Another example of a syntax error that can lead to an infinite loop is
omitting the curly braces:
while (num < 0) //an infinite loop here--no braces
System.out.print("Enter a value: ");
num = input.nextInt();
In this case, only the first statement is executed and num is never assigned
the input. Although properly done, the indentation makes it difficult to
find the syntax error.
A logic error can also lead to an infinite loop condition. For example, in
the code below num is initialized to 1 and never decremented to a number
less than 0 in the loop, making the condition of the loop structure always
true:
int num = 1;
do {
num += 1;
} while (num >= 0);
In this case, the loop isnt infinite because num is eventually assigned a
number so large that an overflow results. An overflow occurs when there
are not enough bits to store a number. This may generate a run-time error
or, in the case of the code above, actually cause the condition to become
false. An overflow changes the sign of the number stored.
overflow
Chapter 6 Loop Structures and Strings 133
s
a
m
p
l
e
Review: Prompter
Create a Prompter application that prompts the user for two numbers. The first number is a min value and
the second is a max value. Prompter then prompts the user for a number between the min and max numbers
entered. The user should be continually prompted until a number within the range is entered. Be sure to
include the min and max numbers in the prompt.
Counters and Accumulators
Many algorithms require counting and summing values. For example,
an application that calculates the average of a set of numbers must sum
the numbers and then divide the total by the count. The AverageValue
application performs counting and summing. A run of the application
looks similar to:
The AverageValue application is based on the pseudocode:
Prompt user for a value
while (value != 0)
count value
add value to sum of values
prompt user for another value
Display average of values (sum/count)
A program that counts the number of values entered by the user is
actually counting the number of loop iterations. To count loop iterations,
a statement similar to the following is used within the loop:
numValues += 1;
Each time the statement executes, one is added to the current value of the
variable. This type of variable is called a counter because it is incremented
by a constant value. Counters are useful for keeping track of the number
of times a user enters a value, makes a guess, or types a password. A
counter should be initialized when it is declared and then incremented
by a fixed amount.
A similar assignment statement is used to sum values as they are
entered by the user:
sumOfValues += newValue;
Each time the statement executes, the value of newValue is added to the
current value of the variable. This type of variable is called an accumulator
because its value accumulates. As with a counter, an accumulator should
be initialized when it is declared.
134 Chapter 6 Loop Structures and Strings
s
a
m
p
l
e
The AverageValue code includes both a counter (numValues) and an
accumulator (sumOfValues):
/* AverageValue application. */
import java.util.Scanner;
/**
* Displays the average of a set of numbers
*/
public class AverageValue {
public static void main(String[] args) {
final int SENTINEL = 0;
int newValue;
int numValues = 0;
int sumOfValues = 0;
double avg;
Scanner input = new Scanner(System.in);
/* Get a set of numbers from user */
System.out.println("Calculate Average Program");
System.out.print("Enter a value (" + SENTINEL + " to quit): ");
newValue = input.nextInt();
while (newValue != SENTINEL) {
numValues += 1;
sumOfValues += newValue;
System.out.print("Enter a value(" + SENTINEL + " to quit): ");
newValue = input.nextInt();
}
input.close();
/*Calculate average of numbers entered by user */
avg = (double)sumOfValues / (double)numValues;
System.out.println("Average is " + avg);
}
}
The AverageValue code uses a constant named SENTINEL. This constant
stores a value to act as a flag, or sentinel, to signify that the loop should
stop iterating. AverageValue defines the sentinel with a constant. Another
approach is to use a variable and prompt the user for the sentinel value.
Review: Evens
Create an Evens application that displays the even numbers between 1 and 20, inclusive.
Review: NumbersSum
Create a NumbersSum application that prompts the user for a number and then displays the numbers 1
through the number entered, each on a separate line. Below the numbers, the sum is displayed.
Review: PercentPassing
Create a PercentPassing application that prompts the user for a set of scores and then calculates the percent-
age of scores above 70%. The user should have the option to enter as many scores as needed. (Hint: Use an
if statement and another counter.)
flag, sentinel
Chapter 6 Loop Structures and Strings 135
s
a
m
p
l
e
The for Statement
The for statement is a loop structure that executes a set of statements a
fixed number of times. The for statement takes the form:
for (<initialization>; <condition>; <increment>) {
<statements>
}
The initialization is performed only once when a for statement is executed.
The condition is a Boolean expression, which is evaluated before each loop
iteration. When the condition is true the statements are executed, when
false, program flow continues to the next statement after the closing curly
brace of the for. After each loop iteration, the increment is executed.
The following statement uses a counter to control the iterations of a for
statement. The counter i is the loop control variable. When i is greater than
10, looping terminates:
for (int i = 1; i <= 10; i++) {
System.out.println(i);
}
Note that the counter is declared in the initialization of the for statement
(int i = 1). With a declaration in this location, the scope of the counter
is from the initialization to the closing curly brace of the for statement.
The application will not recognize the variable outside of that statement.
Declaring variables so that their scope is limited to where they are needed
is good programming style because it produces cleaner code and helps
eliminate the possibility of errors.
The statement above uses the ++ operator in the increment part of the
for statement (i++). The ++ operator is called the increment operator because
it increases the value of a variable by 1. The ++ operator is a good choice
in the increment of a for statement because the effect is to increase the
operand by 1. However, ++ should not be used within an expression, such
as i++ <= 10, because the value returned by the operator is used in the
expression, not the final value of the operand.
Any combination of components can be left out of a for statement. This
can be useful when a counter is declared and initialized outside the state-
ment, as in the following code:
int num;
System.out.print("Enter the starting number: ");
num = input.nextInt();
for (; num <= 10; num++) {
System.out.println(num);
}
A for statement may also count down from a start value to an end value
using the decrement operator, --:
for (int countDown = 10; countDown <= 0; countDown--) {
System.out.println(countDown);
}
While it is possible to modify a loop control variable from within a for
loop or to terminate a loop prematurely, this is considered poor program-
ming style. Good programming style dictates that changes to the loop
control variable occur in the increment portion of the loop only and that
the loop end only when the condition is false.
TIP Counter variables in a
for loop are often named i,
j, or k.
Expressions Using ++
or
I f t he + + or - - operat or
appears before the operand,
it is called prefix (i.e. ++i). An
operator after the operand is
called postfix (i.e. i++). Either
operator location has the
same effect on the final value
of the operand. However,
in an expression, the prefix
version uses the value of the
operand after the operation.
For example, when x is 12,
the statement ++x returns 13.
In the postfix version, x++,
12 is returned. Therefore, a
statement such as x++ >= 13 is
false and could be ambiguous.
Using the ++ and -- operators
in an expression is poor
programming style.
programming style
loop control variable
increment operator
scope
136 Chapter 6 Loop Structures and Strings
s
a
m
p
l
e
Review: Factorial
Create a Factorial application that prompts the user for a number and then displays its factorial. The factorial
of a number is the product of all the positive integers from 1 to the number. For example, 5! = 5*4*3*2*1.
Review: OddSum
Create an OddSum application that prompts the user for a number and then sums the odd numbers from 1
to the number entered.
Debugging Techniques
The source of bugs, which are often logic errors, can be hard to deter-
mine without tools for debugging an application. Debugging is the process
of getting an application to work correctly. One tool included with many
compilers is called a debugger.
A debugger is used to select statements where execution will be sus-
pended. These statements are called breakpoints. Application output goes
to a Debug Window and statements can be executed one at a time between
breakpoints by using a Step command. When stepping through an applica-
tion, selected variables are displayed in a Watch window along with their
value. When a watch variable is assigned a new value, the Watch window
is updated. Stepping through code and watching variables can an effective
way to determine logic errors.
Another debugging tool is called a variable trace and is done manu-
ally. A variable trace is a table listing the values of variables at the points
of assignment. For the following code, num1 and num2 would be included
in a variable trace:
int num1 = 0;
int num2 = 0;
while (num1 < 10) {
if (num1 % 3 == 0) {
num2 += num1;
System.out.print(num2 + " ");
}
num1 += 1;
}
The variables are listed in the order that assignment occurs within the
loop. Output is also listed to better understand the code:
debugger
breakpoints
variable trace
TIP A bug is an error in a
program.
TIP A common error with
loops is an off-by-one error.
This occurs when a loop iter-
ates one too many or one too
few times due to a Boolean
expression error.
Chapter 6 Loop Structures and Strings 137
s
a
m
p
l
e
A third debugging technique involves adding additional println() state-
ments to an application. Adding println() statements just after a variable is
assigned a new value or before and after a condition is evaluated can help
detect the source of a logic error. For example, the code segment below
includes additional statements for debugging:
int num1 = 0;
int num2 = 0;
System.out.println("num1 before while: " + num1); //debug
while (num1 < 10) {
System.out.println("num1 in while: " + num1); //debug
if (num1 % 3 == 0) {
num2 += num1;
System.out.println("num2:" + num2); //debug
System.out.println(num2 + " ");
}
num1 += 1;
}
When run, the code above displays the following output, which can be
compared to the values expected. Note the similarity to a variable trace:
Commenting out statements can be an effective way to locate a bug
through process of elimination. Typically the // characters are easiest to
type at the beginning of a statement to comment it out.
Review: Variable Trace
Using paper and pencil, create a variable trace for the following code, tracing the values of num1, num2, i, and
any output:
int num1 = 0;
int num2 = 0;
for (int i = 0; i <= 4; i++) {
num1 = i * i;
num2 += num1;
System.out.print(num1 + " ");
}
System.out.println(num2);
additional println()
commenting out code
138 Chapter 6 Loop Structures and Strings
s
a
m
p
l
e
The String Class
Primitive data types such as int and double are used for storing numeric
data. However, when data is comprised of a sequence of characters, a data
type for storing strings is needed. Java includes the String class in the
java.lang package for storing and manipulating strings. The String class
is large, with numerous methods for string manipulation. Some of the
String class methods include:
Class String (java.lang.String)
Methods
length() returns an integer corresponding to the number
of characters in the string.
substring(int start, int end)
returns a substring of the string, which starts
at start position and ends one character before
the end position.
substring(int start)
returns a substring of the string, which starts
at start position and extends to the end of the
string.
toLowerCase() returns a copy of the string with all lowercase
letters.
toUpperCase() returns a copy of the string with all uppercase
letters.
trim() returns a copy of the string with all leading and
trailing spaces removed.
replaceFirst(String str, String str2)
returns a string with the first occurrence of str
replaced by str2.
replaceAll(String str, String str2)
returns a string with all occurrences of str
replaced by str2.
The position of a character in a string is called its index. The first char-
acter of a string is at index 0. The last character of a string is at index
length() 1. The MiddleThree class below displays the three letters in the
middle of a string:
public class MiddleThree {
public static void main(String[] args) {
String phrase, threeLetters;
int phraseLength;
int mid;
Scanner input = new Scanner(System.in);
/* get string from user */
System.out.print("Enter text that contains at least
three characters: ");
phrase = input.nextLine();
input.close();
/* determine middle of phrase */
phraseLength = phrase.length();
mid = phraseLength / 2;
index
More on Concatenation
As introduced in Chapter 4,
concatenation appends one
string to another. When the
+ operator is used to join a
string and a numeric, the com-
piler first converts any non-
String data to a String object
before joining the strings. The
String class also contains the
concat() method for joining
two strings.
Chapter 6 Loop Structures and Strings 139
s
a
m
p
l
e
/* display middle three characters */
threeLetters = phrase.substring(mid - 1, mid + 2);
System.out.println("Middle three characters are: "
+ threeLetters);
}
}
Note that the String objects (phrase, threeLetters) can be declared in the
same way primitives are declaredthe data type followed by the vari-
able name. With the String class, the following two statements perform
the same task:
String alpha = new String("abc"); //these assignments are
String alpha = "abc"; //efffectively the same
The MiddleThree application produces output similar to:
A string is said to be immutable because it cannot be changed. Methods
that manipulate the original string, for example toLowerCase(), create
a new string in memory because the original string cannot be changed.
Assigning a new string to a String object simply changes the object refer-
ence to point to the new string in memory. For example, the following code
generates a new string. Assigning the string to the text object changes the
objects reference:
String text;
text = "heLlO";
text = text.toLowerCase();
System.out.println(text);
The code produces the output:
Until a String object is assigned a value, it refers to null. Calling a method
from a null String object generates the exception NullPointerException.
Review: AccountSetup
Create an AccountSetup application that prompts the user for a user name and a password. The application
should prompt the user until a password with at least eight characters is entered. The user name and pass-
word should be converted to all lowercase letters and then an appropriate message displayed. Application
output should look similar to:
immutable
NullPointerException
null
140 Chapter 6 Loop Structures and Strings
s
a
m
p
l
e
Comparing Strings
Strings are compared when determining equality or alphabetical order.
In chapter 5, relational operators, including == and >, were used to compare
primitive types. When objects need to be compared, methods from their
class are used. Some of the String class methods for comparing strings
include:
Class String (java.lang.String)
Methods
equals(String str)
returns true when the string is the same as str.
Returns false otherwise.
equalsIgnoreCase(String str)
same as equals() except that uppercase and
lowercase differences between the strings are
ignored.
compareTo(String str)
returns 0 when str is the same as the string, a
negative integer is returned when str comes
alphabetically after the string, and a positive
integer is returned when str comes alphabeti-
cally before the string. Note that uppercase and
lowercase letters are considered different.
compareToIgnoreCase(String str)
same as compareTo() except that uppercase and
lowercase differences between the strings are
ignored.
indexOf(String str)
returns the integer corresponding to the
location of the first occurrence of str in the
string. Otherwise 1 is returned.
lastIndexOf(String str)
returns the integer corresponding to the
location of the last occurrence of str in the
string. Otherwise 1 is returned.
startsWith(String str)
returns true when the string begins with str.
Returns false otherwise.
endsWith(String str)
returns true when the string ends with str.
Returns false otherwise.
The AlphaOrder class compares two strings and then displays them in
alphabetical order:
public class AlphaOrder {
public static void main(String[] args) {
String word1, word2;
Scanner input = new Scanner (System.in);
Unicode
The Unicode Standard is
a 16-bit encoding system
that assigns a value for
each character and symbol
of every language. Java
uses this standard when
def i ni ng st ri ngs, and
String class methods use
the character values when
comparing strings.
Chapter 6 Loop Structures and Strings 141
s
a
m
p
l
e
System.out.print("Enter a word: ");
word1 = input.nextLine();
System.out.print("Enter a second word: ");
word2 = input.nextLine();
input.close();
if (word1.compareToIgnoreCase(word2) == 0) {
System.out.println("Words are equal.");
} else if (word1.compareToIgnoreCase(word2) < 0) {
System.out.println("In alphabetical order: " + word1
+ " " + word2);
} else {
System.out.println("In alphabetical order: " + word2
+ " " + word1);
}
}
}
AlphaOrder produces output similar to the following:
Review: FormalGreeting
Create a FormalGreeting application that prompts the user for his or her name, including title. The applica-
tion should display Hello, sir. if the string starts with Mr., Hello, maam. if the string starts with Ms., Mrs.,
or Miss, and Hello, name. otherwise where name is the users name.
Chapter 6 Case Study
In this case study, a word guessing game will be created. The word
guessing game allows the player to guess the letters of a secret word. At
the start of the game, the player is shown only how many letters the word
contains through a set of dashes. When a letter matching one in the word
is guessed, it replaces the appropriate dash. Play continues until the entire
word is guessed letter-by-letter or when the player chooses to guess the
entire word.
WordGuess Specification
WordGuess is played between the computer and a single player. The
secret word is BRAIN. At the start of the game, six dashes are displayed
(), one for each letter of the word. The player is repeatedly prompted
for a letter guess. When a letter matching one in the word is guessed, the
letter replaces the corresponding dash. Letters may be entered as upper-
case or lowercase. However, only uppercase letters should be displayed. If
the player enters an exclamation point (!), the player is prompted to guess
the word. At that point the player either wins (a correct guess) or loses
(an incorrect guess). Alternatively, the player can continue to guess letters
until the entire word is revealed. The games ends by showing the player
the total number of guesses.
142 Chapter 6 Loop Structures and Strings
s
a
m
p
l
e
The WordGuess interface should display a row of dashes, one dash for
each letter in the word. Prompts should be used to get letter guesses from
the player. As corresponding letters are guessed, the letter is displayed
instead of the dash. At the end of the game, the user should be shown the
word along with the number of guesses.
The WordGuess output sketch:
The WordGuess algorithm:
1. Display a row of dashes to represent the word.
2. Prompt the user for a letter guess.
3. If the letter guessed is part of the word, then display that letter in
place of the corresponding dash.
4. Repeat steps 2 and 3 until all the letters have been guessed or an
exclamation point has been entered by the user.
5. If an exclamation point has been entered, prompt the user to guess
the entire word.
6. If the player correctly guesses the entire word or all the letters have
been guessed, then display a message indicating that the player
has won, otherwise the message should indicate that the player
has lost.
7. Display the secret word and the number of guesses.
Chapter 6 Loop Structures and Strings 143
s
a
m
p
l
e
The WordGuess flowchart:
A class is written in a separate file and consists of a declaration and
a body. The class declaration includes the access level, the keyword class,
and the class name. The class body contains variables, constructors, and
methods. Constructors are used to initialize variables in a class. Variables
and methods are called the members of a class. A class takes the form:
<access _ level> class <name> {
<variables>
<constructors>
<methods>
}
Functional
Decomposition
The process of creating clearly
defined functions, or behavior,
for a class is sometimes called
functional decomposition. A
well-written class has been
functionally decomposed into
a set of methods that cannot
be simplified further.
class declaration, body
member
constructor
client code
TIP In Java, the controlling
class is the client code.
Chapter 8 Classes and Object-Oriented Development 181
s
a
m
p
l
e
The Circle class code is based on the design on the previous page:
/**
* Circle class.
*/
public class Circle {
private static final double PI = 3.14;
private double radius;
/**
* constructor
* pre: none
* post: A Circle object created. Radius initialized to 1.
*/
public Circle() {
radius = 1; //default radius
}
/**
* Changes the radius of the circle.
* pre: none
* post: Radius has been changed.
*/
public void setRadius(double newRadius) {
radius = newRadius;
}
/**
* Calculates the area of the circle.
* pre: none
* post: The area of the circle has been returned.
*/
public double area() {
double circleArea;
circleArea = PI * radius * radius;
return(circleArea);
}
/**
* Returns the radius of the circle.
* pre: none
* post: The radius of the circle has been returned.
*/
public double getRadius() {
return(radius);
}
}
The Circle class has access level public which means that it is visible
to other classes and can be used to instantiate objects in those classes.
The class name is Circle. A class name should be a noun, begin with an
uppercase letter, and each word within the name should also begin with
an uppercase letter. Class names may not contain spaces.
The body of a class starts with an opening brace ({) and ends with a
closing brace (}). Member variables are declared after the opening brace,
and outside of any methods. Variable declarations in the body of a class
have a local scope that extends from the opening brace of the class body
to the closing. Note that the Circle class also has a member variable that
is a constant.
naming conventions
Organizing Files
Each class is writ ten in a
separate file. The client code
and the classes it uses are then
compiled together as part of a
project.
Interface
The public methods of a class
define the interface of an
object. The interface is how
client code can interact with
an object.
182 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
The visibility of a member variable is controlled with an access modifier.
Declaring a variable as private makes it visible to the class, but not to
client code. This encapsulates the data and provides information hiding.
For example, the Circle class contains a private variable radius that can be
used by any of the methods of the class, but cannot be directly accessed
by statements in the client code where the Circle object was created.
A constructor is automatically called when an object is created. The con-
structor is where variables are initialized. Variables that are not initialized
may contain data that could generate a run-time error when a method of
the class is executed.
The methods in a class are accessor methods, modifier methods, or
helper methods. Accessor methods are called to determine the value of
a variable. For example, in the Circle class, getRadius() is an accessor
method. It returns the value of the variable radius. A modifier method is
called to change the value of a variable. In the Circle class, setRadius() is a
modifier method. It assigns a value passed in a parameter to the variable
radius. Accessor and modifier methods have access level public so that
they may be called from the class where the Circle object was created.
Helper methods are called from within a class by other methods. They
are used to help complete a task and have access level private. The Circle
class does not contain helper methods.
An application that includes Circle objects can include statements that
call the public methods, but statements that refer to the private members
will generate a compiler error.
Review: Circle part 1 of 4
Modify the Circle class to include a member method named circumference. The circumference() method
should return the circumference of the circle (2r). Test the class with the following client code:
public static void main(String[] args) {
Circle spot = new Circle();
spot.setRadius(3);
System.out.println("Circle radius: " + spot.getRadius());
System.out.println("Circle circumference: " + spot.circumference());
}
Review: Coin part 1 of 2
Create a Coin class that includes a variable faceUp that stores either a 0 for heads up or 1 for tails up, an
accessor method named showFace() that returns a 0 if the coin is heads up or a 1 if the coin is tails up, and a
modifier method named flipCoin() that assigns a random integer between 0 and 1, inclusive, to the variable
faceUp. Test the class with the following client code:
public static void main(String[] args) {
Coin nickel = new Coin();
if (nickel.flipCoin() == 0) {
System.out.println("Heads up!");
} else {
System.out.println("Tails up!");
}
}
helper method
accessor method
modifier method
TIP Access modifiers and
visibility were introduced in
Chapter 7.
Chapter 8 Classes and Object-Oriented Development 183
s
a
m
p
l
e
Writing Constructors
The constructor of a class is automatically executed when an object
is instantiated. Once an object is instantiated, the method members of
the class can be called in any order. Unexpected results may occur if an
accessor method is called before a member variable has been set to a valid
value. To prevent this, variables should be initialized in the constructor.
A constructor takes the form:
public <class name>(<parameters>) {
<statements>
}
The constructor of a class does not have a return type and always has the
same name as the class. When a constructor contains parameters, they
are separated by commas.
Constructors can be overloaded to provide more options for instantiat-
ing an object. For example, if the radius of the circle object is known when
the Circle object is created, it would be more efficient to assign the value
to radius when the object is created:
Circle spot = new Circle(5);
A constructor can be added to the Circle class to handle creating an object
with a parameter that contains the circle radius:
/**
* Circle class.
*/
public class Circle {
private static final double PI = 3.14;
private double radius;
/**
* constructor
* pre: none
* post: A Circle object created. Radius initialized to 1.
*/
public Circle() {
radius = 1; //default radius
}
/**
* constructor
* pre: none
* post: A Circle object created with radius r.
*/
public Circle(double r) {
radius = r;
}
rest of Circle class
When a class contains more than one constructor, the compiler uses
the number and types of parameters to determine which constructor to
execute.
overloading constructors
184 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Review: Circle part 2 of 4
Modify the Circle class to include an overloaded constructor that accepts the radius of the Circle object, as
shown in the previous section.
Review: Rectangle part 1 of 5
Design and then create a Rectangle class that has overloaded constructors. The first constructor requires no
parameters. The second has two parameters, one for length and a second for width. Member variables store
the length and width of the rectangle, and member methods assign and retrieve the length and width and
return the area and perimeter of the rectangle. Test the class by writing appropriate client code.
Instance and Class Members
Each object, or instance, of a class has its own copy of variables called
instance variables. For example, the Circle class contains the instance
variable radius. A class may also contain class variables. A class variable is
declared with the keyword static and only one copy is maintained for all
objects to refer to. For example, the Circle class contains the class variable
PI. Note that because PI is a constant, it also includes the keyword final:
/**
* Circle class.
*/
public class Circle {
private static final double PI = 3.14; //class constant
private double radius; //instance variable
rest of Circle class
In the statements below, two Circle objects are instantiated. Each
instance has its own copy of the instance variable radius, but both objects
refer to the same copy of the class constant PI:
Methods can be either instance methods or class methods. Accessor
and modifier methods are instance methods because they change the state
of an object. They must be called from an instance of a class. Chapter 7
introduced class methods that are declared with the keyword static. Class
methods can be called from the class itself, rather than an object of the
class, to perform a task. For example, consider the Circle class with the
following class method added:
/**
* Displays the formula for the area of a circle.
* pre: none
* post: The formula for area of a circle has been displayed.
*/
public static void displayAreaFormula() {
System.out.println("The formula for the area of a
circle is a=Pi*r*r");
}
instance variable
class variable
instance methods
class methods
Chapter 8 Classes and Object-Oriented Development 185
s
a
m
p
l
e
The following client code calls the displayAreaFormula() class
method:
public class TestCircle {
public static void main(String[] args) {
Circle spot = new Circle(5);
System.out.println("Circle radius:" + spot.getRadius());
System.out.println("Circle area: " + spot.area());
Circle.displayAreaFormula();
}
}
The class method is called from the class itself (Circle) rather than an object
of the class. The TestCircle application displays the following output:
To summarize the differences between instance and class members:
instance variables are created each time an object is declared.
class variables and constants are created once for the class and then
objects of the class refer to this copy.
instance methods can only be called from an object of the class.
class methods can be called from the class itself.
Review: Circle part 3 of 4
Modify the Circle class to include a class method named displayAreaFormula, as shown in the previous sec-
tion. Modify existing client code to test the new method.
Review: Rectangle part 2 of 5
Modify the Rectangle class to include a class method named displayAreaFormula. Modify existing client code
to test the new method.
The Object Class
The Object class is the superclass of all other classes. Classes, such as
Circle and String, are subclasses of Object:
The Bank client code uses the class designs and looks similar to:
import java.util.Scanner;
import java.text.NumberFormat;
public class Bank {
public static void main(String[] args) {
Account munozAccount = new Account(250, "Maria", "Munoz", "110 Glades Road",
"Mytown", "FL", "33445");
Scanner input = new Scanner(System.in);
double data;
NumberFormat money = NumberFormat.getCurrencyInstance();
System.out.println(munozAccount);
System.out.print("Enter deposit amount: ");
data = input.nextDouble();
munozAccount.deposit(data);
System.out.println("Balance is: " + money.format(munozAccount.getBalance()));
System.out.print("Enter withdrawal amount: ");
data = input.nextDouble();
munozAccount.withdrawal(data);
System.out.println("Balance is: " + money.format(munozAccount.getBalance()));
}
}
Nested Classes and
Inner Classes
A nested class is a class
defined in another class as
a member of that class. The
member class has access to
other data members, just as
other members of the class. A
nested class is also called an
inner class, unless it is declared
static.
Chapter 8 Classes and Object-Oriented Development 189
s
a
m
p
l
e
The Account class is implemented below:
import java.text.NumberFormat;
public class Account {
private double balance;
private Customer cust;
/**
* constructor
* pre: none
* post: An account created. Balance and
* customer data initialized with parameters.
*/
public Account(double bal, String fName, String lName,
String str, String city, String st, String zip) {
balance = bal;
cust = new Customer(fName, lName, str, city, st, zip);
}
/**
* Returns the current balance.
* pre: none
* post: The account balance has been returned.
*/
public double getBalance() {
return(balance);
}
/**
* A deposit is made to the account.
* pre: none
* post: The balance has been increased by the amount of the deposit.
*/
public void deposit(double amt) {
balance += amt;
}
/**
* A withdrawal is made from the account if there is enough money.
* pre: none
* post: The balance has been decreased by the amount withdrawn.
*/
public void withdrawal(double amt) {
if (amt <= balance) {
balance -= amt;
} else {
System.out.println("Not enough money in account.");
}
}
this
The keyword this can be
used to distinguish between
a parameter and a member
variable. For example, it can
be convenient to use t he
same name for both a method
parameter and a member
variable in a class, in which
case, the member variable is
preceded by this. If in the
Account class, the constructor
used double balance as a
parameter, then the statement
in the body must be written as:
this.balance = balance;
190 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
/**
* Returns a String that represents the Account object.
* pre: none
* post: A string representing the Account object has
* been returned.
*/
public String toString() {
String accountString;
NumberFormat money = NumberFormat.getCurrencyInstance();
accountString = cust.toString();
accountString += "Current balance is " + money.format(balance);
return(accountString);
}
}
The Customer class is implemented below:
public class Customer {
private String firstName, lastName, street, city,
state, zip;
/**
* constructor
* pre: none
* post: A Customer object has been created.
* Customer data has been initialized with parameters.
*/
public Customer(String fName, String lName, String str,
String c, String s, String z) {
firstName = fName;
lastName = lName;
street = str;
city = c;
state = s;
zip = z;
}
/**
* Returns a String that represents the Customer object.
* pre: none
* post: A string representing the Account object has
* been returned.
*/
public String toString() {
String custString;
custString = firstName + " " + lastName + "\n";
custString += street + "\n";
custString += city + ", " + state + " " + zip + "\n";
return(custString);
}
}
Chapter 8 Classes and Object-Oriented Development 191
s
a
m
p
l
e
Running the Bank application produces output similar to:
Review: Bank
Modify the Customer class to include changeStreet(), changeCity(), changeState(), and changeZip() methods.
Modify the Account class to include a changeAddress() method that has street, city, state, and zip parameters.
Modify the Bank application to test the changeAddress() method.
Object-Oriented Development
Object-oriented programming requires that the solution to a task be
implemented as a system of objects. In this system, objects communicate
with other objects to provide a solution to the task. This approach to creat-
ing software is called object-oriented development.
In object-oriented development, the programmer reads the specification
and selects objects to model the specification. Some of these objects will
require new classes designed and written by the programmer. Other
objects can be created from existing classes previously written by the
programmer or by other programmers. For example, the JRE contains
numerous classes for use in a Java application. Reusability is an important
feature of object-oriented programming because it reduces development
time and decreases the likelihood of bugs.
To demonstrate object-oriented development, consider the following
Carnival program specification:
A carnival has many games that are similar in nature. These games
allow the player three tries, and the player who is successful all
three times is a winner. For example, the Balloon Dart Toss game
allows the player to throw three darts at a wall of balloons. If each
dart pops a balloon, then the player is a winner. The Ring Toss and
Break A Plate games work similarly.
reusability
TIP The JRE was first discussed
in Chapter 4.
192 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
designing objects
Every player gets a prize. There are winning prizes and consolation
prizes. The Balloon Dart Toss prizes are tiger plush and sticker. The
Ring Toss prizes are bear key chain and pencil, and the Break A
Plate prizes are pig plush and plastic dinosaur. The Balloon Dart
Toss and Ring Toss games are $2 to play. The Break A Plate game
costs $1.50.
The player comes to the carnival with some spending money and
can play games until the money runs out. The player also holds
onto all the prizes won.
The Carnival application should produce output similar to the
following when Shonda has $5 spending money and Luis has $3:
In the first step of object-oriented development, objects are selected to
model the specification. In this case, the carnival can be modeled with
game booth objects and player objects. A game booth object should store
data about the cost of playing the game, the winning prize, and the con-
solation prize. Game booth methods should start the game and give the
cost to play. A player object should store data about the spending money
of the player and the prizes won. Player methods should play the game
and show the list of prizes won.
The designs for the Carnival classes are:
selecting objects for the
model
Chapter 8 Classes and Object-Oriented Development 193
s
a
m
p
l
e
The Carnival client code uses the class designs and looks similar to:
GameBooth balloonDartToss = new GameBooth(2,"tiger plush", "sticker");
GameBooth ringToss = new GameBooth(2,"bear keychain", "pencil");
GameBooth breakAPlate = new GameBooth(1.5, "pig plush", "plastic dinosaur");
Player shonda = new Player(5); //$5 spending money
Player luis = new Player(3); //$3 spending money
System.out.print("Shonda goes to Balloon Dart Toss. ");
System.out.println(shonda.play(balloonDartToss));
System.out.print("Luis goes to Ring Toss. ");
System.out.println(luis.play(ringToss));
System.out.print("Shonda goes to Ring Toss. ");
System.out.println(shonda.play(ringToss));
System.out.print("Luis goes to Break A Plate. ");
System.out.println(luis.play(breakAPlate));
System.out.println("Shonda won: " + shonda.showPrizes());
System.out.println("Luis won: " + luis.showPrizes());
Note how simple the application appears. All the work is being done by
the objects, rather than with individual statements in the main() method.
The Carnival application, like other object-oriented applications, is modular.
It uses components that are separately written and maintained.
Another aspect of object-oriented development is that objects send
information to other objects to perform a task. When information is passed
from one object to another, the object is said to be passing a message. For
example, in the pseudocode above, the Player objects are passed a message
that includes the cost of game and the prize the player won.
The GameBooth class is implemented below. Note that in the start()
method, the players throws are simulated with random numbers. The
player is said to win if three ones are generated:
import java.util.Random;
public class GameBooth {
private double cost;
private String firstPrize, consolationPrize;
/**
* constructor
* pre: none
* post: A GameBooth object created.
* The cost and prizes are set.
*/
public GameBooth(double charge, String p1, String p2) {
cost = charge;
firstPrize = p1;
consolationPrize = p2;
}
modular
message
client code
implementing the classes
194 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
/**
* Game is played and prize awarded.
* pre: none
* post: Player had three tries. Player successful all
* three times received the first prize. A consolation
* prize has been awarded otherwise.
*/
public String start() {
int toss;
int successes = 0;
Random rand = new Random();
/* play game */
for (int i = 0; i < 3; i++) { //player gets three tries
toss = rand.nextInt(2);
if (toss == 1) {
successes += 1; //1 is a successful toss
}
}
/* award prize */
if (successes == 3) {
return(firstPrize);
} else {
return(consolationPrize);
}
}
/**
* Returns the cost to play the game.
* pre: none
* post: Cost of the game has been returned.
*/
public double getCost() {
return(cost);
}
}
The Player class is implemented below:
public class Player {
private double spendingMoney;
private String prizesWon;
/**
* constructor
* pre: none
* post: A Player object created. Spending money given to
* player. The prizes won set to none.
*/
public Player(double money) {
spendingMoney = money;
prizesWon = "";
}
Chapter 8 Classes and Object-Oriented Development 195
s
a
m
p
l
e
/**
* Player pays for and then plays a game.
* pre: none
* post: Player's spending money decreased by cost of game.
* The player has a new prize added to existing prizes.
*/
public String play(GameBooth game) {
String newPrize;
if (game.getCost() > spendingMoney) {
return("Sorry, not enough money to play.");
} else {
spendingMoney -= game.getCost(); //pay for game
newPrize = game.start(); //play game
prizesWon = newPrize + ", " + prizesWon;
return("prize won: " + newPrize);
}
}
/**
* Returns the list of prizes won.
* pre: none
* post: The list of prizes has been returned.
*/
public String showPrizes() {
return(prizesWon);
}
}
Running the Carnival application produces output similar to:
Although the classes may look long, once written they are available for
many different implementations of a Carnival or another application that
involves games.
Review: Carnival
Modify the Player class to override the toString() method. When a Player object is passed to the println()
method, a message should display how much money the player has left and the prizes won so far.
Modify the GameBooth class to keep track of the number of prizes awarded. There should be separate
totals for the first prizes awarded and the consolation prizes awarded. Add a method to the GameBooth
class named prizesAwarded() that displays the number of first prizes and the number of consolation prizes
given away.
Modify the Carnival client code to pass the Player objects to println() in the last two statements, and in
separate statements, display how many prizes were given away by each booth.
196 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Chapter 8 Case Study
In this case study, a Rock Paper Scissors game will be created using
object-oriented development. Rock Paper Scissors is a popular game played
between two individuals for decision making or just for competitive fun.
The rules of the game are Rock dulls Scissors (Rock wins), Scissors cuts
Paper (Scissors wins), and Paper covers Rock (Paper wins). The two players
make a throw at the same time. The hand signals thrown by the players
are then compared to the rules of the game to determine the winner. In
the computerized version, the user plays against the computer.
RPS2 Specification
The computerized version of the Rock Paper Scissors game is played
by one user that throws either rock, paper, or scissors. The game then
randomly selects either rock, paper, or scissors for the computers throw
and the winner is determined by comparing the two choices. Rock wins
over scissors, scissors wins over paper, and rock wins over scissors. The
player can initially choose to play multiple rounds. At the end of the
rounds, an overall winner is declared.
The RPS2 interface should show the result of each round and the overall
winner. The RPS2 output sketch:
The RPS2 algorithm:
1. Prompt the player for the number of rounds.
2. For each round:
Prompt for the players throw.
Generate the computers throw.
Announce the winner of the round.
3. Announce an overall winner.
TIP An RPS application was
also developed for the Chapter
5 Case Study.
Chapter 8 Classes and Object-Oriented Development 197
s
a
m
p
l
e
RPS2 Code Design
The RPS2 application can be modeled with a player object and a game
object. The player object should store the players throw (either rock,
paper, or scissors) and contain methods that make and return the players
throw. The game object should store the computers throw, the number
of computer wins, and the number of player wins and contain methods
that make and return the computers throw, determine the winner of each
round, and determine an overall winner.
The designs for the RPS2 classes are:
Based on the algorithm and the class designs, the RPS2 code design will
include two objects and a loop. The pseudocode for the RPS2 client code
follows:
declare game object
declare player object
prompt player for number of rounds
for (i = 0; i < rounds; i++) {
prompt player for throw
player.makeThrow(playerThrow);
gameObject.makeThrow();
gameObject.announceWinner(playerObject.getThrow);
}
gameObject.bigWinner
198 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
RPS2 Implementation
The RPS2 implementation involves creating three files. One file contains
the client code and the other two files are the classes.
The RPS2Player class is implemented below:
/**
* models the player in a game of RPS
*/
public class RPSPlayer {
private int playerThrow; //ROCK=1, PAPER=2, SCISSORS=3
/**
* constructor
* pre: none
* post: RPSPlayer object created. The player is given a
* default throw.
*/
public RPSPlayer() {
playerThrow = 1; //default throw
}
/**
* Sets the player's throw.
* pre: newThrow is the integer 1, 2, or 3.
* post: Player's throw has been made.
*/
public void makeThrow(int newThrow){
playerThrow = newThrow;
}
/**
* Returns the player's throw.
* pre: none
* post: Player's throw has been returned.
*/
public int getThrow() {
return(playerThrow);
}
}
Chapter 8 Classes and Object-Oriented Development 199
s
a
m
p
l
e
The RPSGame class is implemented below:
/**
* Models a game of RPS
*/
import java.util.Random;
public class RPSGame {
public static final int ROCK = 1, PAPER = 2, SCISSORS = 3;
private int compThrow;
private int playerWins = 0, computerWins = 0;
/**
* constructor
* pre: none
* post: RPSGame object created. Computer throw generated.
*/
public RPSGame() {
Random rand = new Random();
compThrow = rand.nextInt(3) + 1; //random int between 1 and 3
playerWins = 0;
computerWins = 0;
}
/**
* Computer's throw is generated (ROCK, PAPER, or SCISSORS)
* pre: none
* post: Computer's throw has been made.
*/
public void makeCompThrow(){
Random rand = new Random();
compThrow = rand.nextInt(3) + 1; //random int between 1 and 3
}
/**
* Returns the computer's throw.
* pre: none
* post: Computer's throw has been returned.
*/
public int getCompThrow() {
return(compThrow);
}
/**
* Determines the winner of the round.
* pre: playerThrow is the integer 1, 2, or 3.
* post: Displays a message indicating throws. Compares player's
* throw to computer's throw and displays a message indicating
* the winner.
*/
public void announceWinner(int playerThrow) {
/* Inform player of throws */
System.out.print("You throw ");
switch (playerThrow) {
case ROCK: System.out.println("ROCK."); break;
case PAPER: System.out.println("PAPER."); break;
case SCISSORS: System.out.println("SCISSORS."); break;
}
200 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
System.out.print("Computer throws ");
switch (compThrow) {
case ROCK: System.out.println("ROCK."); break;
case PAPER: System.out.println("PAPER."); break;
case SCISSORS: System.out.println("SCISSORS."); break;
}
/* Determine and annouce winner */
if (playerThrow == ROCK && compThrow == ROCK) {
System.out.println("It's a draw!");
} else if (playerThrow == ROCK && compThrow == PAPER) {
System.out.println("Computer wins!");
computerWins += 1;
} else if (playerThrow == ROCK && compThrow == SCISSORS) {
System.out.println("You win!");
playerWins += 1;
}
if (playerThrow == PAPER && compThrow == ROCK) {
System.out.println("You win!");
playerWins += 1;
} else if (playerThrow == PAPER && compThrow == PAPER) {
System.out.println("It's a draw!");
} else if (playerThrow == PAPER && compThrow == SCISSORS) {
System.out.println("Computer wins!");
computerWins +=1;
}
if (playerThrow == SCISSORS && compThrow == ROCK) {
System.out.println("Computer wins!");
computerWins += 1;
} else if (playerThrow == SCISSORS && compThrow == PAPER) {
System.out.println("You win!");
playerWins += 1;
} else if (playerThrow == SCISSORS && compThrow == SCISSORS) {
System.out.println("It's a draw!");
}
}
/**
* Displays the overall winner.
* pre: none
* post: Computer and player wins compared and
* an overall winner announced.
*/
public void bigWinner() {
if (computerWins > playerWins){
System.out.println("Computer wins!");
} else if (playerWins > computerWins){
System.out.println("You win!");
} else {
System.out.println("It's a draw!");
}
}
}
Chapter 8 Classes and Object-Oriented Development 201
s
a
m
p
l
e
The RPS2 client code follows:
/*
* RPS2.java
*/
import java.util.Scanner;
/**
* Computer plays Rock Paper Scissors against one player.
*/
public class RPS2 {
public static void main(String[] args) {
RPSGame rps = new RPSGame();
RPSPlayer rpsOpponent = new RPSPlayer();
int rounds;
int playerThrow;
Scanner input = new Scanner(System.in);
/* play RPS */
System.out.print("How many rounds? ");
rounds = input.nextInt();
for (int i = 0; i < rounds; i++) {
System.out.print("Enter your throw (ROCK=1,
PAPER=2, SCISSORS=3): ");
playerThrow = input.nextInt();
rpsOpponent.makeThrow(playerThrow);
rps.makeCompThrow();
rps.announceWinner(rpsOpponent.getThrow());
}
rps.bigWinner();
}
}
Note how concise the client code is. The RPS2 application uses objects
to perform all the work.
Although the classes may look long, once written they are available
for many different implementations of the RPS game. Client code can be
written to use the classes in many different ways. For example, multiple
players and games can be instantiated for tournaments.
RPS2 Testing and Debugging
When a new class is written, client code should be written to test the
class. For the RPSGame class, client code should test all the possible throw
combinations, similar to the testing discussed in the Chapter 5 Case
Study.
202 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Review: RPS2 part 1 of 2
Modify the RPSPlayer class to include a playerName variable and methods named assignName and getName. The
assignName() method has a String parameter name that is assigned to playerName. The getName() method
returns the value of playerName. Modify the announceWinner() and bigWinner() methods in the RPSGame
class to include a String parameter name that is the players name. Change the messages displayed in the
announceWinner() and bigWinner() methods to include the players name rather than the word You.
Modifying the two classes should produce output similar to the sketch below:
Review: RPS2 part 2 of 2
Modify the RPS2 client code to perform error checking on the players input. Have the client code verify that
the user has entered a 1, 2, or 3 for a throw before passing the entered value to the makeThrow() method.
Chapter Summary
This chapter introduced writing and designing classes. Classes are the
data types of objects. An object has a state (data) and behavior (actions and
communication in the form of methods). An important aspect of object-
oriented programming is encapsulation, also called information hiding.
In OOP, classes are written to encasulate, or hide, data from outside code.
Client code is code that uses one or more classes.
A class includes a class declaration, variables, constructors, and meth-
ods. The class declaration includes the access level, the keyword class, and
a name. Variables and methods are the members of a class. Variables are
the data members and should be declared private. Accessor and modifier
methods are declared public, while helper methods are declared private.
Constructors are used to initialize variables and can be overloaded so that
objects can be declared with vaying numbers of parameters.
Chapter 8 Classes and Object-Oriented Development 203
s
a
m
p
l
e
The variables and methods of a class are either instance or class mem-
bers. Instance members are copied for each instance of a class. Only one
copy of a class member exists for the class. Every object of a class refers to
the same class member. The keyword static is used for a class member
declaration. Class methods can be called from the class itself. An object
of the class can call either instance or class members.
Every class is a subclass of the Object class. The Object class could also
be called the superclass of all other classes. The equals() and toString()
methods in the Object class are inherited by all other classes. In most cases,
these methods should be redefined in subclasses.
An object that contains an object is said to demonstrate a has-a relation-
ship. Any class that contains a String data member demonstrates a has-a
relationship.
Object-oriented development requires the solution to a task be imple-
mented as a system of objects. In this system, objects pass messages back
and forth to provide a solution to the task.
This chapter discussed several important aspects of the object-oriented
paradigm, including encapsulation, reusability, and modularity.
The code convention introduced in this chapter is:
Class names should be a noun, begin with an uppercase letter, and
each word within the name should also begin with an uppercase
letter.
204 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Vocabulary
Accessor method A method of a class that is used to
determine the value of a variable member. Accessor
methods have access level public.
Behavior The action and communication an object
provides.
Class A data type that defines variables for the state
of an object and methods for an objects behavior.
Class body The variables, constructors, and methods
that implement a class.
ClassCastException An exception thrown when an
object variable is cast with an incompatible class.
Class declaration The first line of a class, which
contains the access level, the keyword class, and
the class name.
Class method A method of a class that can be called
from the class itself. It cannot change the state of an
object. Class methods include the keyword static.
Class variable A variable of a class that exists as
one copy that all instances of a class refer to. Class
variables include the keyword static.
Client code An application that uses one or more
classes.
Constructor The part of a class that is used to
initialize the variable members of a class.
Encapsulation Protecting an objects data from
code outside the class.
Has-a relationship The relationship demonstrated
by a class that contains another class.
Helper method A method of a class that is used
by other methods in a class to help complete a task.
Helper methods have access level private.
Information hiding Also called encapsulation.
Inherit To receive the methods of a superclass.
Instance An object of a class.
Instance method A method of a class that changes
the state of a class. It must be called from an instance
of the class.
Instance variable A variable of a class that is copied
for each instance of the class.
Member A variable or method of a class.
Message Information passed from one object to
another.
Modifier method A method of a class that is used
to change the value of a variable member. Modifier
methods have access level public.
Modular An application that uses components that
are separately written and maintained.
Object An instance of a class. An object stores
data and can perform act ions and provide
communication.
Object casting To cast an object as the appropriate
class.
Object-oriented development The solution to a task
that is implemented as a system of objects.
Override To redefine a method from a superclass
in a subclass.
Reusability A feature of object-oriented program-
ming that reduces development time and decreases
the likelihood of bugs.
State The data an object stores.
Subclass A class below another class in a class
hierarchy. A class that inherits another class.
Superclass The upper-most class in a class hierarchy.
A class that has subclasses.
Visibility The access level of a method.
Chapter 8 Classes and Object-Oriented Development 205
s
a
m
p
l
e
Java
class The keyword used to declare a class.
public An access modifier used in the declaration
of a class to indicate that the class is visible to client
code. Also used in the declaration of class methods to
indicate that the method is visible to client code.
static The keyword used in the declaration of a
variable or method in a class to indicate that the
member is a class method.
private A keyword used in the declaration of class
members when those members should be visible to
the class but not to client code.
206 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Critical Thinking
1. Which members of t he Ci rcle class are
encapsulated?
2. What name must the constructor of a class
have?
3. Explain the difference between the private and
public access modifiers.
4. Consider the following code. Is the last state-
ment valid or invalid? Explain.
Circle dot = new Circle(2);
dot.radius = 5;
5. Use the following class to answer the questions
below:
public class Roo {
private int x;
public Roo {
x = 1;
}
public void setX(int z) {
x = z;
}
public int getX() {
return(x);
}
public int calculate() {
x = x * factor();
return(x);
}
private int factor() {
return(0.12);
}
}
a) What is the name of the class?
b) What is the name of the data member?
c) List the accessor method.
d) List the modifier method.
e) List the helper method.
f) What is the name of the constructor?
g) How many method members are there?
6. What is the difference between a class and an
object?
7. Imagine a band festival where there are many
bands playingthe TwoToos, the EggRolls, and
Goop. Each band can TuneUp, PlayMusic, and
TakeABow. A set list can be read or created. If
this was simulated in an object-oriented pro-
gram, what would appropriate names be for:
a) the class
b) the objects
c) a data member
d) the method members
8. Assume a class for a sports team named
Team.
a) List three possible object names.
b) List three possible method members.
c) List three possible data members.
9. Use the following class data member definitions
to answer the questions below:
public class Moo {
private double y;
private static int x;
private static final z;
a) Which data member is a constant?
b) Which data members are variables?
c) Which dat a member (s) are i nst ance
members?
d) Which data member(s) are class members?
10. Explain the difference between calling an
instance method member and a class method
member.
11. Compare and contrast overriding methods to
overloading methods.
12. The Customer class in the Bank application also
demonstrates a has-a relationship. Explain.
13. How can reusing code decrease the likelihood
of bugs in an application?
14. Explain what is meant by passing a message.
Chapter 8 Classes and Object-Oriented Development 207
s
a
m
p
l
e
True/False
15. Determine if each of the following are true or
false. If false, explain why.
a) The state of an object is described by its
methods.
b) The behavior of an object is described by its
variables.
c) An instance of a class is called an object.
d) Client code is an application that uses a
class.
e) Encapsulation means that all the variables
in a class are available to client code.
f) A constructor is a member of a class.
g) A variable that is visible to a class, but not
to client code is declared with the keyword
private.
h) An accessor method is called to change the
value of a data member.
i) A modifier method returns the value of a
data member.
j) A constructor of a class is automatically
called when an object of the class is instan-
tiated.
k) A class can contain multiple constructors.
l) An instance variable is copied for each
instance of a class.
m) A class variable is declared with the key-
word public.
n) A class method must be called from an object
of the class.
o) A class constant is declared with only the
keyword final.
p) The Object class is a subclass of all other
classes.
q) The toString() method can be redefined in
subclasses.
r) Object-oriented development requires that
only one object be used in an application.
208 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Exercises
Exercise 1 MySavings
Create a MySavings application that displays a menu of choices for entering pennies, nickels, dimes, and
quarters into a piggy bank and then prompts the user to make a selection. The MySavings application
should include a PiggyBank object that can add coins to the piggy bank, remove coins, and return the
total amount in the bank. Application output should look similar to:
Exercise 2 DigitExtractor
Create a DigitExtractor application that prompts the user for an integer and then displays the ones,
tens, and hundreds digit of the number. The DigitExtractor application should include a Num object
that can return the ones digit, tens digit, hundreds digit, and the whole number. Application output
should look similar to:
Chapter 8 Classes and Object-Oriented Development 209
s
a
m
p
l
e
Exercise 3 LunchOrder
Create a LunchOrder application that prompts the user for the number of hamburgers, salads, french
fries, and sodas and then displays the total for the order. The LunchOrder application should include
a Food object with a constructor that accepts the price, fat, carbs, and fiber for an item. Food methods
should return the price of the item and return the fat, carbohydrates, and fiber. Use the chart below for
food prices and nutrition information:
Item Price Fat(g) Carbohydrates(g) Fiber(g)
hamburger $1.85 9 33 1
salad $2.00 1 11 5
french fries $1.30 11 36 4
soda $0.95 0 38 0
Application output should look similar to:
210 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Exercise 4 DiceRollGame
In the Dice Roll game, the player begins with a score of 1000. The player is prompted for the number
of points to risk and a second prompt asks the player to choose either high or low. The player rolls
two dice and the outcome is compared to the players choice of high or low. If the dice total is between
2 and 6 inclusive, then it is considered low. A total between 8 and 12 inclusive is high. A total of
7 is neither high nor low, and the player loses the points at risk. If the player had called correctly, the
points at risk are doubled and added to the total points. For a wrong call, the player loses the points at
risk. Create a DiceRollGame application that uses a DRPlayer object based on this specification. The
DRPlayer object should have two Die member variables that represent the dice. The Die class should
use a random number generator to determine the outcome in a roll() method. Application output
should look similar to:
Exercise 5 Nim2
The game of Nim starts with a random number of stones between 15 and 30. Two players alternate
turns and on each turn may take either 1, 2, or 3 stones from the pile. The player forced to take the last
stone loses. Use object-oriented development to create a Nim2 application that allows the user to play
Nim against the computer. The Nim2 application and its objects should:
Generate the number of stones to begin with.
Allow the player to go first.
Use a random number generator to determine the number of stones the computer
takes.
Prevent the player and the computer from taking an illegal number of stones. For
example, neither should be allowed to take three stones when there are only 1 or 2
left.
Chapter 8 Classes and Object-Oriented Development 211
s
a
m
p
l
e
Exercise 6 GameOf21
In the Game of 21, a player is dealt two cards from a deck of playing cards and then optionally given
a third card. The player closest to 21 points without going over is the winner. Use object-oriented
development to create a Game of 21 application that allows the user to play the Game of 21 against the
computer. The Game of 21 application and its objects should:
Deal a card from a deck of playing cards by generating a random number between 1
and 13. A 1 corresponds to an Ace, numbers 2 through 10 correspond to those cards,
and 11 through 13 correspond to Jack, Queen, and King. The Jack, Queen, and King
have a value of 10 in the Game of 21. An Ace can have a value of either 1 or 11.
Allow the player to stay with two cards or be given a third card.
Announce the winner.
Play rounds until the player says to stop.
Exercise 7 Bowling
In bowling, a ball is rolled down a lane, also called an alley, at a set of ten pins. A game consists of a
bowler bowling for ten frames, where each frame consists of two chances (throws) to knock over all ten
pins. Bowling centers often use computers to electronically keep scores for bowlers. Use object-oriented
development to create a Bowling application that simulates a simplified game of bowling. The Bowling
application and its objects should:
Allow a bowler to bowl ten frames. Each frame consists of two throws, unless a strike
is thrown.
Award 20 points to the bowler when all ten pins are knocked over on the first throw
of a frame.
Award 15 points to the bowler when all ten pins are knocked over within the two
throws of a frame.
Award one point for each pin knocked over in the two throws of a frame when all
ten pins are not knocked over.
If there is more than one bowler in a game, then the bowlers take turns until each
has bowled ten frames.
Use a random number generator to determine how many pins a bowler has knocked
over with each throw.
Display an updated score after each frame.
212 Chapter 8 Classes and Object-Oriented Development
s
a
m
p
l
e
Exercise 8 Adder
The Adder game prompts a player for the answer to an addition problem. The Adder game cre-
ates a problem from two randomly selected integers between 0 and 20. Adder allows the player
three tries to enter a correct answer. If the correct answer is entered on the first try, the player is
awarded 5 points. If the correct answer is entered on the second try, 3 points are awarded. The
correct answer on the third try earns 1 point. If after three tries, the correct answer is still not
entered, the player receives no points and the correct answer is displayed. The game continues until
999 is entered as an answer. At the end of the game, Adder displays the players score. Application
output should look similar to:
Chapter 9 Inheritance and Polymorphism 213
s
a
m
p
l
e
Object-oriented programming is based on a paradigm in which objects
are used to model a specification. Objects are created from classes, which
provide encapsulation. Inheritance extends a class and provides a means
of polymorphism. This chapter discusses inheritance and polymorphism.
Abstract classes and interfaces are also discussed.
Extending a Class
Often times there is an existing class that provides a basis for an object
that models a specification. However, the existing class may need addi-
tional methods or different implementations of existing methods to more
closely represent the object for the model. For example, consider a disk,
which has circular shape. It is similar to a circle. However, a disk is three-
dimensional and also has a thickness. Rather than create a whole new class
to represent a disk, a class named Disk could extend the Circle class.
Making one class an extension of another involves inheritance. Inheritance
allows a class to define a specialized type of an already existing class. In
this case, a disk is a solid circle with a thickness. Classes that are derived
from existing classes demonstrate an is-a relationship. A class is a type
of another class. In this case, a disk is a circle with a thickness.
A class can have many levels of inheritance. For example, consider the
following class hierarchy:
The Puck class inherits the Disk class, which inherits the Circle class. The
Circle class is the superclass of Disk. Disk is the subclass of Circle and the
superclass of Puck. Puck is the subclass of Disk.
Chapter 9
Inheritance and Polymorphism
inheritance
TIP The Object class is the
superclass of all other classes.
is-a relationship
214 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Implementing a Subclass
A class that inherits another class includes the keyword extends in the
class declaration and takes the form:
public class <name> extends <class _ name> {
<class definition>
}
Designing a subclass requires selecting the superclass, or base class,
and then defining any additional variable and method members for the
subclass. In many cases, existing methods in the base class will also be
overridden by new definitions in the subclass, also called the derived class.
For example, the Disk class design appears similar to:
The Disk class implementation, based on the design above, is:
/**
* Disk class.
*/
public class Disk extends Circle {
private double thickness;
/**
* constructor
* pre: none
* post: A Disk object has been created with radius r
* and thickness t.
*/
public Disk(double r, double t) {
super(r);
thickness = t;
}
/**
* Changes the thickness of the disk.
* pre: none
* post: Thickness has been changed.
*/
public void setThickness(double newThickness) {
thickness = newThickness;
}
extends
base class
derived class
Chapter 9 Inheritance and Polymorphism 215
s
a
m
p
l
e
/**
* Returns the thickness of the disk.
* pre: none
* post: The thickness of the disk has been returned.
*/
public double getThickness() {
return(thickness);
}
/**
* Returns the volume of the disk.
* pre: none
* post: The volume of the disk has been returned.
*/
public double volume() {
double v;
v = super.area() * thickness;
return(v);
}
/**
* Determines if the object is equal to another
* Disk object.
* pre: d is a Disk object.
* post: true has been returned if objects have the same
* radii and thickness. false has been returned otherwise.
*/
public boolean equals(Object d) {
Disk testObj = (Disk)d;
if (testObj.getRadius() == super.getRadius()
&& testObj.getThickness() == thickness) {
return(true);
} else {
return(false);
}
}
/**
* Returns a String that represents the Disk object.
* pre: none
* post: A string representing the Disk object has
* been returned.
*/
public String toString() {
String diskString;
diskString = "The disk has radius " + super.getRadius()
+ " and thickness " + thickness + ".";
return(diskString);
}
}
In a subclass, the keyword super is used to access methods of the
base class. For example, the statement super(r) calls the constructor of
the superclass, Circle, and passes an argument for setting the radius
value. Members that are declared private are not accessible to derived
classes. Therefore, accessor methods are used to get inherited member
variable values. For example, the equals() method in the Disk class calls
getRadius().
super
TIP The equals() and toString()
methods override the methods
by the same name in the Circle
class.
visibility
216 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Inherited methods are called directly from an object, just as any method
of the class is called. Whether a method is original to the Disk class or
inherited from the Circle class is transparent to client code, as demonstrated
in the TestDisk application:
public class TestDisk {
public static void main(String[] args) {
Disk saucer = new Disk(10, 0.02);
System.out.println("Disk radius: " + saucer.getRadius());
System.out.println("Disk surface area: " + saucer.area());
System.out.println("Disk volume: " + saucer.volume());
Disk plate1 = new Disk(12, 0.05);
Disk plate2 = new Disk(12, 0.07);
if (plate1.equals(plate2)) {
System.out.println("Objects are equal.");
} else {
System.out.println("Objects are not equal.");
}
System.out.println(plate1);
System.out.println(plate2);
}
}
The TestDisk application displays the following output:
Review: Puck part 1 of 2
Create a Puck class that inherits the Disk class. The Puck class should include member variables weight,
standard, and youth. The standard and youth variables should be boolean variables that are set to either true
or false depending on the weight of the puck. A standard puck weighs between 5 and 5.5 ounces. A youth
puck weighs between 4 and 4.5 ounces. Official hockey pucks, regardless of weight, are one inch-thick with a
three-inch diameter. The Puck class should also contain member methods getWeight(), getDivision(), which
returns a string stating whether the puck is standard or youth, and equals() and toString(), which overrride
the same methods in the Disk class. The Puck constructor should require an argument for weight. Be sure
that the constructor initializes other variables to appropriate values as necessary.
Create a Hockey application that tests the Puck class.
Chapter 9 Inheritance and Polymorphism 217
s
a
m
p
l
e
Polymorphism
Polymorphism is an OOP property in which objects have the ability to
assume different types. In object-oriented programming, polymorphism
is based on inheritance. Because a subclass is derived from a superclass,
a superclass object can reference an object of the subclass. For example,
the following statements are valid because Disk inherits Circle:
Circle wafer;
Disk cookie = new Disk(2, 0.5);
wafer = cookie; //wafer now references cookie
The wafer object, declared a Circle, is polymorphic, as demonstrated in
the statement wafer = cookie where wafer assumes the form of cookie, a
Disk object.
Polymorphism is further demonstrated when the referenced object
determines which method to execute. This is possible when a subclass
overrides a superclass method. In this case, the Disk class has overridden
the equals() and toString() methods. Because of this, the following state-
ment executes the Disk toString() method even though wafer was declared
a Circle object:
/* displays: The disk has radius 2.0 and thickness 0.5. */
System.out.println(wafer);
To further demonstrate polymorphism, the Music application will
be developed in this section. The Music application allows the user to
assemble a small band. The user can assign a band member either vocals
(voice) or a woodwind instrument (piccolo or clarinet). The user can then
select to hear either a solo, duet, or trio performance from this band.
The Instrument class, its subclasses, and the Performance class are
used to model the objects for the Music application. The diagram below
illustrates the client code and classes for the Music application. Note the
hierarchy of the Instrument class and its subclasses:
218 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
The Music client code is shown below:
/*
* Music.java
*/
import java.util.Scanner;
public class Music {
/* Returns a selected instrument.
* pre: none
* post: An instrument object has been returned.
*/
public static Instrument assignInstrument() {
String instrumentChoice;
Scanner input = new Scanner(System.in);
System.out.println("Select an instrument for the
band member. ");
System.out.print("Vocals, Piccolo, or Clarinet: ");
instrumentChoice = input.nextLine();
System.out.print("Enter the band member's name: ");
name = input.nextLine();
if (instrumentChoice.equalsIgnoreCase("V")) {
return(new Vocal(name));
} else if (instrumentChoice.equalsIgnoreCase("P")) {
return(new Piccolo(name));
} else { //default to clarinet
return(new Clarinet(name));
}
}
public static void main(String[] args) {
Performance band;
Instrument bandMember1, bandMember2, bandMember3;
Scanner input = new Scanner(System.in);
String performanceChoice;
/* assign instruments */
bandMember1 = assignInstrument();
bandMember2 = assignInstrument();
bandMember3 = assignInstrument();
System.out.println(bandMember1 + " " + bandMember2 + " "
+ bandMember3 + "\n");
System.out.print("Would you like to hear a Solo, a Duet,
a Trio, or Leave? ");
performanceChoice = input.nextLine();
while (!performanceChoice.equalsIgnoreCase("L")) {
if (performanceChoice.equalsIgnoreCase("S")) {
band = new Performance(bandMember1);
} else if (performanceChoice.equalsIgnoreCase("D")) {
band = new Performance(bandMember1, bandMember2);
} else { //default to trio
band = new Performance(bandMember1, bandMember2,
bandMember3);
}
band.begin();
System.out.print("\nWould you like to hear a Solo,
a Duet, a Trio, or Leave? ");;
performanceChoice = input.nextLine();
}
}
}
Chapter 9 Inheritance and Polymorphism 219
s
a
m
p
l
e
The assignInstrument() method declares an Instrument return type, but
the individual return statements return Vocal, Piccola, and Clarinet types.
The Instrument object returned by the method is polymorphic, changing
to whichever subclass is actually returned.
The Music application produces output similar to:
The Music application allows the user numerous combinations for select-
ing a band and hearing performances. The code for such an application
would be more complicated and less flexible without the object-oriented
principles of inheritance and polymorphism. Music is versatile because it
takes advantage of inheritance and polymorphism.
The documentation for the Instrument, Vocal, Woodwind, Piccolo,
and Clarinet classes is below. Note that the makeSound() method in the
Instrument class is a method that must be implemented (written) in a sub-
class. This is discussed further in the next section. The code for the classes
is also shown in the next section where abstract classes are discussed.
Class Instrument
Constructor/Methods
Instrument(String name)
creates an instrument object with musician
name.
getMusician() returns a string that is the musicians name.
makeSound() an abstract method that should return a String
representing the instruments sound.
220 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Class Vocal (inherits Instrument)
Constructor/Methods
Vocal(String name)
creates a singer object with singer name.
makeSound() returns the String LaLaLa.
toString() returns a String that represents the singer.
Class Woodwind (inherits Instrument)
Constructor/Method
Woodwind(String name)
creates a woodwind instrument object with
musician name.
makeSound() returns the String toot.
Class Piccolo (inherits Woodwind)
Constructor/Methods
Piccolo(String name)
creates a piccoloist object with musician name.
makeSound() returns the String peep.
toString() returns a String that represents the object.
Class Clarinet (inherits Woodwind)
Constructor/Methods
Clarinet(String name)
creates a clarinetist object with musician name.
makeSound() returns the String squawk.
toString() returns a String that represents the object.
The Performance class creates an arrangement of Instrument objects.
The constructors require Instrument arguments, but polymorphism
enables objects of Instructor subclasses to be passed:
/**
* Performance class.
*/
public class Performance {
private String arrangement;
private Instrument solo;
private Instrument duet _ 1, duet _ 2;
private Instrument trio _ 1, trio _ 2, trio _ 3;
/**
* constructor
* pre: none
* post: A soloist has been selected.
*/
public Performance(Instrument s) {
solo = s;
arrangement = solo.makeSound();
}
Chapter 9 Inheritance and Polymorphism 221
s
a
m
p
l
e
/**
* constructor
* pre: none
* post: The members of a duet have been selected.
*/
public Performance(Instrument d1, Instrument d2) {
duet _ 1 = d1;
duet _ 2 = d2;
arrangement = duet _ 1.makeSound() + duet _ 2.makeSound();
}
/**
* constructor
* pre: none
* post: The members of a trio have been selected.
*/
public Performance(Instrument t1, Instrument t2,
Instrument t3) {
trio _ 1 = t1;
trio _ 2 = t2;
trio _ 3 = t3;
arrangement = trio _ 1.makeSound() + trio _ 2.makeSound()
+ trio _ 3.makeSound();
}
/**
* Begins the performance.
* pre: none
* post: The performance has been played.
*/
public void begin() {
System.out.println(arrangement);
}
/**
* Returns a String that represents the performers.
* pre: none
* post: A string representing the performers has
* been returned.
*/
public String toString() {
String program = "The performance includes ";
program += arrangement;
return(program);
}
}
Review: Music part 1 of 2
Modify the Music application to allow the user to select a quartet (four band members) in addition to the
other performances. Changes to the Performance class will also be required to provide the option of creat-
ing a quartet.
222 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Abstract Classes
An abstract class models an abstract concept. For example, a musical
instrument is an abstract concept. An instrument is something that can
be played, but there is no such thing an instrument instrument. There
are however, flutes, piccolos, drums, and cymbals.
Abstract classes cannot be instantiated because they should not repre-
sent objects. They instead describe the more general details and actions
of a type of object. For example, the Instrument class describes the very
basics of an instrumentit can make a sound. The Woodwind class is also
an abtract class because it describes a group of instruments. It includes a
general sound that woodwind instruments make.
Abstract classes are declared with the keyword abstract in the class
declaraction. They are intended to be inherited. The public members of
the abstract class are visible to derived objects. However, an abstract class
can also contain an abstract method. An abstract method is declared with
the keyword abstract and contains a method declaration, but no body.
The abstract class must be implemented in its subclass.
The Instrument class is an abstract class with an abstract method. The
makeSound() method must be implemented in an Instrument subclass:
/**
* Instrument class.
*/
abstract class Instrument {
String musician;
/**
* constructor
* pre: none
* post: A musician has been assigned to the instrument.
*/
public Instrument(String name) {
musician = name;
}
/**
* Returns the name of the musician
* pre: none
* post: The name of the musician playing the instrument
* has been returned.
*/
public String getMusician() {
return(musician);
}
/**
* Should return the sound of the instrument.
* pre: none
* post: The sound made by the instrument is returned.
*/
abstract String makeSound();
}
The Vocal class is a subclass of Instrument. It provides the body for the
makeSound() method:
abstract method
abstract
Chapter 9 Inheritance and Polymorphism 223
s
a
m
p
l
e
/**
* Vocal class.
*/
public class Vocal extends Instrument {
/**
* constructor
* pre: none
* post: A singer has been created.
*/
public Vocal(String singerName) {
super(singerName);
}
/**
* Returns the sound of the instrument.
* pre: none
* post: The sound made by the singer.
*/
public String makeSound() {
return("LaLaLa");
}
/**
* Returns a String that represents the instrument.
* pre: none
* post: A string representing the singer.
*/
public String toString() {
return(super.getMusician() + " sings " + makeSound() + ".");
}
}
The Woodwind class is also an Instrument subclass. It too implements
the makeSound() method. However, Woodwind describes a group of
instruments so it has also been declared abstract:
/**
* Woodwind class.
*/
abstract class Woodwind extends Instrument {
/**
* constructor
* pre: none
* post: A woodwind instrument has been created.
*/
public Woodwind(String player) {
super(player);
}
/**
* Returns the sound of the instrument.
* pre: none
* post: The sound made by the instrument is returned.
*/
public String makeSound() {
return("toot");
}
}
224 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
The Piccolo class is a subclass of Woodwind. It overrides the makeSound()
method:
/**
* Piccolo class.
*/
public class Piccolo extends Woodwind {
/**
* constructor
* pre: none
* post: A piccolo has been created.
*/
public Piccolo(String piccoloist) {
super(piccoloist);
}
/**
* Returns the sound of the instrument.
* pre: none
* post: The sound made by the instrument is returned.
*/
public String makeSound() {
return("peep");
}
/**
* Returns a String that represents the instrument.
* pre: none
* post: A string representing the instrument has
* been returned.
*/
public String toString() {
return(super.getMusician() + " plays " + makeSound() + ".");
}
}
The Clarinet class is also a Woodwind subclass. It too overrides the
makeSound() method:
/**
* Clarinet class.
*/
public class Clarinet extends Woodwind {
/**
* constructor
* pre: none
* post: A clarinet has been created.
*/
public Clarinet(String clarinetist) {
super(clarinetist);
}
/**
* Returns the sound of the instrument.
* pre: none
* post: The sound made by the instrument is returned.
*/
public String makeSound() {
return("squawk");
}
Chapter 9 Inheritance and Polymorphism 225
s
a
m
p
l
e
/**
* Returns a String that represents the instrument.
* pre: none
* post: A string representing the instrument has
* been returned.
*/
public String toString() {
return(super.getMusician() + " plays " + makeSound() + ".");
}
}
Through inheritance and abstraction, a hierarchy of classes can be cre-
ated that begin with a general abstraction and lead to a specific object.
Review: Music part 2 of 2
Modify the Music application to allow the user to select a cymbal or drum in addition to the other instru-
ments for the band members. The Music application changes will require that Percussion, Cymbal, and Drum
classes be created. The Percussion class should be an abstract class that inherits the Instrument class. The
Cymbal and Drum classes should inherit the Percussion class.
Interfaces
An interface is a class with method declarations that have no implemen-
tations. Although an interface may seem similar to an abstract class, it is
very different. An interface cannot be inherited. It may only be imple-
mented in a class. An interface can add behavior to a class, but it does not
provide a hierarchy for the class.
An interface takes the form:
<access _ level> interface <name> {
<return _ type> <method _ name> (<method _ param>);
additional methods
}
The methods defined in an interface are by default public and abstract.
Therefore, the methods in an interface are only declarations followed by
a semicolon.
The Comparable interface is part of the java.lang package. It contains
one method:
Interface Comparable (java.lang.Comparable)
Method
compareTo(Object obj)
returns 0 when obj is the same as the object,
a negative integer is returned when obj is
less than the object, and a positive integer is
returned when obj is greater than the object.
When an interface is implemented in a class, the class must implement
each method defined in the interface. In this case, the Comparable interface
contains just one method. The Circle class shown on the next page has
been modified to implement the Comparable interface.
Comparable interface
226 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
/**
* Circle class.
*/
public class Circle implements Comparable {
private static final double PI = 3.14;
private double radius;
/**
* constructor
* pre: none
* post: A Circle object created. Radius initialized to 1.
*/
public Circle() {
radius = 1; //default radius
}
getRadius(), setRadius(), and other Circle class methods
/**
* Determines if object c is smaller, the same,
* or larger than this Circle object.
* pre: c is a Circle object
* post: -1 has been returned if c is larger than
* this Circle, 0 has been returned if they are the
* same size, and 1 has been returned if c is smaller
* then this Circle.
*/
public int compareTo(Object c) {
Circle testCircle = (Circle)c;
if (radius < testCircle.getRadius()) {
return(-1);
} else if (radius == testCircle.getRadius()) {
return(0);
} else {
return(1);
}
}
The TestCircle client code tests the compareTo() method:
/**
* The Circle class is tested.
*/
public class TestCircle {
public static void main(String[] args) {
Circle spot1 = new Circle(3);
Circle spot2 = new Circle(4);
if (spot1.compareTo(spot2) == 0) {
System.out.println("Objects are equal.");
} else if (spot1.compareTo(spot2) < 0) {
System.out.println("spot1 is smaller than spot2.");
} else {
System.out.println("spot1 is larger than spot2.");
}
System.out.println(spot1);
System.out.println(spot2);
}
}
Chapter 9 Inheritance and Polymorphism 227
s
a
m
p
l
e
The TestCircle application produces the output:
A class can implement multiple interfaces. When more than one inter-
face is implemented, the interface names are separated by commas in the
class declaration.
Review: Disk
Modify the Disk class to implement the Comparable interface. Two disks are equal when they have the same
thickness and same radius. Modify the existing client code to test the new method.
Review: Puck part 2 of 2
Modify the Puck class to implement the Comparable interface. Two pucks are the equal when they have the
same weight. Modify the existing client code to test the new method.
Review: Rectangle part 4 of 4
Modify the Rectangle class to implement the Comparable interface. Two rectangles are the equal when they
have the same width and height. Modify the existing client code to test the new method.
Review: Rectangle part 4 of 5
Create an interface named ComparableArea that contains one method named compareToArea(). This method
should return 0 when the object has the same area as another object, 1 should be returned when the object
has an area less than another object, and 1 returned otherwise.
Modify the Rectangle class to implement the ComparableArea interface as well as the Comparable interface
implemented in the previous review. Modify the existing client code to test the new method.
Chapter 9 Case Study
In this case study, a sales center application will be created. The sales
center has three employees, which include a manager and two associates.
The manager earns a salary and the associates are paid by the hour. The
owner of the sales center wants a computer application to display employee
information and calculate payroll.
multiple interfaces
228 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
SalesCenter Specification
The SalesCenter application stores information about three employees.
There is one manager (Diego Martin, salary $55,000), and two associates
(Kylie Walter earning $18.50 per hour and Michael Rose earning $16.75
per hour). SalesCenter should be able to display the name and title for
a specified employee. Additionally, the SalesCenter application should
calculate and display the pay for a specified employee based on the pay
argument entered by the user. The pay argument should correlate to hours
worked if the pay for an associate is to be calculated. The pay argument
for a manager should correlate to the number of weeks the manager is to
be paid for.
The SalesCenter interface should provide a menu of options. Depending
on the option selected, additional input may be needed. The SalesCenter
output sketch:
The SalesCenter algorithm:
1. Display a menu of options.
2. Prompt the user for a menu choice.
3. If the user has not selected to quit, prompt the user to specify
employee 1, 2, or 3.
4. Perform the action requested by the user.
5. Repeat steps 1 through 4 until the user has selected the option to
quit.
Chapter 9 Inheritance and Polymorphism 229
s
a
m
p
l
e
SalesCenter Code Design
The SalesCenter application can be modeled with objects for a man-
ager and two associates. The manager and associate objects are both
employee objects. Therefore, an Employee abstract class should be used
for subclasses Manager and Associate. The Employee class should define
an emplyees first and last name and include an abstract class for calcu-
lating pay. A managers pay is based on a pay period specified in weeks.
Associates are paid by the hour. The abstract pay() method in Employee
will have different implementations in Manager and Associate.
The SalesCenter class designs are:
230 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Based on the algorithm and the class designs, the SalesCenter code
design will include a loop. The pseudocode for the SalesCenter client code
follows:
import java.util.Scanner;
import java.text.NumberFormat;
public class SalesCenter {
payEmployee(emp, payArg) {
System.out.println(emp);
pay = emp.pay(payArg);
System.out.println(pay);
}
public static void main(String[] args) {
Manager emp1 = new Manager("Diego","Martin", 55000);
Associate emp2 = new Associate("Kylie", "Walter", 18.50);
Associate emp3 = new Associate("Michael", "Rose", 16.75);
Employee emp = emp1; //default employee choice
/* display menu of choices */
do {
prompt user for employee/pay/quit
get user choice;
if (not quit) {
prompt user for employee number 1, 2, or 3
get empNum
switch (empNum) {
case 1: emp = emp1; break;
case 2: emp = emp2; break;
case 3: emp = emp3; break;
}
if (choice == employee) {
display employee name and title;
} else if (choice == pay) {
prompt user for hours or pay period;
payEmployee(emp, payArg);
}
}
} while (not quit);
}
}
SalesCenter Implementation
The SalesCenter implementation involves creating four files. Three files
are the classes and one file is the client code.
Chapter 9 Inheritance and Polymorphism 231
s
a
m
p
l
e
The Employee class is implemented below:
/**
* Employee class.
*/
abstract class Employee {
String firstName, lastName;
/**
* constructor
* pre: none
* post: An employee has been created.
*/
public Employee(String fName, String lName) {
firstName = fName;
lastName = lName;
}
/**
* Returns the employee name.
* pre: none
* post: The employee name has been returned.
*/
public String toString() {
return(firstName + " " + lastName);
}
/**
* Returns the employee pay.
* pre: none
* post: The employee pay has been returned.
*/
abstract double pay(double period);
}
The Manager class is implemented below:
/**
* Manager class.
*/
class Manager extends Employee {
double yearlySalary;
/**
* constructor
* pre: none
* post: A manager has been created.
*/
public Manager(String fName, String lName, double sal) {
super(fName, lName);
yearlySalary = sal;
}
/**
* Returns the manager salary.
* pre: none
* post: The manager salary has been returned.
*/
public double getSalary() {
return(yearlySalary);
}
232 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
/**
* Returns the manager pay for a specified period.
* pre: none
* post: The manager pay for the specified period
* has been returned.
*/
public double pay(double weeks) {
double payEarned;
payEarned = (yearlySalary / 52) * weeks;
return(payEarned);
}
/**
* Returns the employee name and title.
* pre: none
* post: The employee name and title has been returned.
*/
public String toString() {
return(super.toString() + ", manager");
}
}
The Associate class is implemented below:
/**
* Associate class.
*/
class Associate extends Employee {
double hourlyPayRate;
/**
* constructor
* pre: none
* post: An associate has been created.
*/
public Associate(String fName, String lName, double rate) {
super(fName, lName);
hourlyPayRate = rate;
}
/**
* Returns the associate pay rate.
* pre: none
* post: The associate pay rate has been returned.
*/
public double getRate() {
return(hourlyPayRate);
}
/**
* Returns the associate pay for the hours worked.
* pre: none
* post: The associate pay for the hours worked
* has been returned.
*/
public double pay(double hours) {
double payEarned;
payEarned = hourlyPayRate * hours;
return(payEarned);
}
Chapter 9 Inheritance and Polymorphism 233
s
a
m
p
l
e
/**
* Returns the employee name and title.
* pre: none
* post: The employee name and title has been returned.
*/
public String toString() {
return(super.toString() + ", associate");
}
}
The SalesCenter client code is implemented below:
import java.util.Scanner;
import java.text.NumberFormat;
public class SalesCenter {
/**
* Displays employee name and pay.
* pre: none
* post: Employee name and pay has been displayed
*/
public static void payEmployee(Employee emp, double payArg) {
NumberFormat money = NumberFormat.getCurrencyInstance();
double pay;
System.out.println(emp);
pay = emp.pay(payArg);
System.out.println(money.format(pay));
}
public static void main(String[] args) {
Manager emp1 = new Manager("Diego","Martin", 55000);
Associate emp2 = new Associate("Kylie", "Walter", 18.50);
Associate emp3 = new Associate("Michael", "Rose", 16.75);
Scanner input = new Scanner(System.in);
String action;
int empNum;
double payArg;
Employee emp = emp1; //set to default emp1
do {
System.out.println("\nEmployee\\Pay\\Quit");
System.out.print("Enter choice: ");
action = input.next();
if (!action.equalsIgnoreCase("Q")) {
System.out.print("Enter employee number (1, 2, or 3):");
empNum = input.nextInt();
switch (empNum) {
case 1: emp = emp1; break;
case 2: emp = emp2; break;
case 3: emp = emp3; break;
}
if (action.equalsIgnoreCase("E")) {
System.out.println(emp);
} else if (action.equalsIgnoreCase("P")) {
System.out.print("Enter the hours for associate or
pay period for manager: ");
payArg = input.nextDouble();
payEmployee(emp, payArg);
}
}
} while (!action.equalsIgnoreCase("Q"));
}
}
234 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
The SalesCenter application generates output similar to:
SalesCenter Testing and Debugging
Client code should first be written to test each class. Testing should be
done for the client code.
Review: SalesCenter
Modify the SalesCenter application to compensate associates when they have worked more than 40 hours.
Associates should be paid their hourly wage when 40 or fewer hours are worked. However, associates earn
time and a half for hours over 40. For example, an associate paid $10 per hour will earn $300 for 30 hours of
work. However, an associate working 42 hours will earn $400 + $30, or $430. The overtime pay is calculated
as (hours over 40) * (1.5 * base hourly rate).
Chapter Summary
This chapter discussed inheritance and polymorphism, two key aspects
of object-oriented programming. Inheritance allows classes to be derived
from existing classes. By extending an existing class, there is less devel-
opment and debugging necessary. A class derived from an existing class
demonstrates an is-a relationship.
A superclass is also called a base class, and a subclass is called a derived
class. The keyword extends is used to create a derived class from a base
class. The keyword super is used to access members of a base class from
the derived class.
Polymorphism is the ability of an object to assume different types. In
OOP, polymorphism is based on inheritance. An object can assume the
type of any of its subclasses.
Abstract classes model abstract concepts. They cannot be instantiated
because they should not represent objects. An abstract class is intended
to be inherited.
Chapter 9 Inheritance and Polymorphism 235
s
a
m
p
l
e
Abstract classes may or may not contain abstract methods. An abstract
method is a method declaration with no implementation. If a class con-
tains one or more abstract methods, it must be declared abstract. Abstract
methods must be implemented in a class that inherits the abstract class.
An interface is a class that contains only abstract methods. An interface
can be implemented by a class, but it is not inherited. A class that imple-
ments an interface must implement each method in the interface. The
Comparable interface is part of the java.lang package and is used to add
a compareTo() method to classes that implement the interface.
236 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Vocabulary
Abstract class A class that models an abstract
concept. A class that contains one or more abstract
methods must be declared abstract.
Abstract method A method that has been declared,
but not implemented. Abstract methods appear in
abstract classes. They are implemented in a subclass
that inherits the abstract class.
Base class A superclass.
Derived class A subclass.
Inheritance The OOP property in which a class
can define a specialized type of an already exist-
ing class.
Interface A class with abstract methods. An inter-
face cannot be inherited, but it can be implemented
by any number of classes.
Is-a relationship The relationship demonstrated
by a class derived from an existing class.
Polymorphism The OOP property in which objects
have the ability to assume different types.
Java
abstract The keyword used for declaring a class
or a method as abstract.
Comparable A java.lang interface with the
compareTo() method that can be implemented in
classes to provide a means for an object to be com-
pared to another object of the same type.
extends The keyword used in a class declaration to
inherit another class.
interface The keyword used in a class declaration
to declare it an interface.
super The keyword used to call a superclass con-
structor or method.
Chapter 9 Inheritance and Polymorphism 237
s
a
m
p
l
e
Critical Thinking
1. Explain the difference between a has-a and is-a
relationship among classes.
2. If a base class has a public method go() and a
derived class has a public method stop(), which
methods will be available to an object of the
derived class?
3. Compare and contrast implementing an abstract
method to overriding a method.
4. Compare and contrast an abstract class to an
interface.
5. List the method(s) contained in the Comparable
interface.
6. Use the following classes to answer the questions
below:
interface Wo {
public int doThat();
}
public class Bo {
private int x;
public Bo(int z) {
x = z;
}
public int doThis() {
return(2);
}
public int doNow() {
return(15);
}
}
public class Roo extends Bo implements Wo {
public Roo {
super(1);
}
public int doThis() {
return(10);
}
private int doThat() {
return(20);
}
}
a) What type of method is doThat() in Wo?
b) What is Wo?
c) Why is doThat() implemented in Roo?
d) List the methods available to a Roo object.
e) How does the implementation of doThis() in
Roo affect the implementation of doThis() in
Bo?
f) What action does the statement super(1) in
Roo perform?
g) Can the doThis() method in Bo be called
from a Roo object? If so, how?
h) Can a method in Roo call the doThis()
method in Bo? If so, how?
True/False
7. Determine if each of the following are true or
false. If false, explain why.
a) Inheritance allows a class to define a special-
ized type of an already existing class.
b) Classes that are derived from existing classes
demonstrate a has-a relationship.
c) A cl ass can have only one l evel of
inheritance.
d) A class that inherits another class includes
the keyword i n herita nce in the class
declaration.
e) When implementing a subclass, existing
met hods i n t he bas e c l as s can be
overridden.
f) Members of a base class that are declared
private are accessible to derived classes.
g) Inherited methods are called directly from
an object.
h) Polymorphism is an OOP property in which
objects have the ability to assume different
types.
i) Abstract classes can be instantiated.
j) An abstract class must be implemented in its
subclass.
k) An abstract method contains a method
declaration and a body.
l) Inheritance and abstraction allow a hierarchy
of classes to be created.
m) An interface can be inherited.
n) An interface can add behavior to a class.
o) The methods defined in an interface are pri-
vate by default.
p) The Comparable interface contains three
methods.
238 Chapter 9 Inheritance and Polymorphism
s
a
m
p
l
e
Exercises
Exercise 1 UEmployee, Faculty, Staff
Create a UEmployee class that contains member variables for the university employee name and salary.
The UEmployee class should contain member methods for returning the employee name and salary.
Create Faculty and Staff classes that inherit the UEmployee class. The Faculty class should include
members for storing and returning the department name. The Staff class should include members for
storing and returning the job title.
Exercise 2 Account, PersonalAcct, BusinessAcct
Create PersonalAcct and BusinessAcct classes that inherit the Account class presented in Chapter 8.
A personal account requires a minimum balance of $100. If the balance falls below this amount, then
$2.00 is charged (withdrawn) to the account. A business account requires a minimum balance of $500,
otherwise the account is charged $10. Create client code to test the classes.
Exercise 3 Vehicle, Car, Truck, Minivan
Create a Vehicle class that is an abstract class defining the general details and actions associated with
a vehicle. Create Car, Truck, and Minivan classes that inherit the Vehicle class. The Car, Truck, and
Minivan classes should include additional members specific to the type of vehicle being represented.
Create client code to test the classes.
Chapter 10 Arrays 239
s
a
m
p
l
e
Arrays are used to implement many different kinds of algorithms.
This chapter explains how to create and use arrays. Searching arrays, two-
dimensional arrays, and the ArrayList class are also discussed. Arrays of
characters and Unicode are explained.
Declaring Arrays
An array is a structure that can store many of the same kind of data
together at once. For example, an array can store 20 integers, another
array can store 50 doubles, and a third array can store 100 objects, such as
Strings. Arrays are an important and useful programming concept because
they allow a collection of related values to be stored together with a single
descriptive name.
An array has a fixed length and can contain only as many data items
as its length allows:
An array element is one of the data items in an array. For example, in the
array of Strings above, Roxy is an element. Each element has an index value,
with 0 being the index of the first item, 1 the index of the second item,
and so on. In the array above, Roxy is the fourth element in the array and
has the index value 3.
An array must be declared and then space allocated for the elements of
the array. The statements for declaring an array and allocating space for
its elements take the form:
<type>[] <name>; //declare array
<name> = new <type>[<num>]; //allocate space for elements
The declaration includes the type followed by brackets ([]) to indicate an
array. The array name can be any valid identifier. The new operator allocates
space for the number of elements indicated in brackets. The statements on
the next page declare an array and then prompt the user for the number
of elements:
Chapter 10
Arrays
array element
index
declaring and allocating
space for an array
TIP The [ ] bracket s are
operators used for declaring
and creating arrays and for
accessing array elements.
240 Chapter 10 Arrays
s
a
m
p
l
e
Scanner input = new Scanner(System.in);
int numFriends;
String[] friends; //declare array
System.out.print("How many friends? ");
numfriends = input.nextInt();
friends = new String[numFriends]; //allocate space
If the size of the array is known when the application is written, then
the array can be created and space allocated for elements in one statement,
similar to:
String[] friends = new String[5]; //5 friends
When space has been allocated for the elements of an array, the array is
initialized to the default values for that element type. For example, each
element of an int array is automatically initialized to 0. An array of objects,
such as a String array, contains null for each element.
A third way to create an array is to initialize it in the declaration.
Initializing an array means that a value is given for each element. In this
case, the length of the array is determined by the number of elements
between the curly braces:
String[] friends = {"Kermit", "Lucille", "Sammy", "Roxy", "Myah"};
Using Arrays
An array element is accessed by including its index in brackets after
the array name. For example, the following statement displays the third
element:
System.out.println(friends[2]); //displays Sammy
An array element is changed through assignment. For example, the
assignment statement below changes the third element to Sunshine:
friends[2] = "Sunshine";
A run-time error is generated when an invalid index is used. For exam-
ple, the exception ArrayIndexOutOfBoundsException is thrown when the
following statement tries to execute:
friends[5] = "Wilbur"; //ERROR! Generates an exception.
The Array structure includes the length attribute, which can be used at
run time to determine the length of an array:
numElements = friends.length; //5
A for statement is often used to access the elements of an array because
the loop control variable can be used as the array index. Accessing each
element of an array is called traversing an array. For example, the following
statement displays each element of the friends array:
for (int i = 0; i < friends.length; i++) {
System.out.println(friends[i]);
}
Note that the loop iterates from 0 to one less than the length of the array
because length is a count of the elements, not the greatest index value.
changing an element
accessing an element
initial array values
ArrayIndexOutOfBounds
TIP length is a property, not
a method. Therefore, paren-
theses should not follow its
name.
declaring and initializing
TIP An array is an immutable
data structure, which cannot
be changed from its original
size.
traversing
Chapter 10 Arrays 241
s
a
m
p
l
e
Java also provides a type of for loop just for traversing an array.
Sometimes referred to as a for-each statement, the following statement
displays each element in the array:
for (String element : friends) {
System.out.println(element);
}
The statement above displays the names in the array one after the other.
Using a for-each loop to traverse an array does not require a loop con-
trol variable. This type of for statement helps prevent the exception
ArrayIndexOutOfBoundsException.
Although convenient at times, the modified for statement above cannot
be used in situations where the array index value is needed. One example,
is when the elements of an array are to be accessed in reverse order.
Review: StudentRoster
Create a StudentRoster application that prompts the user for the number of students in the class and then
prompts the user for each students name and stores the names in an array. After all the names have been
entered, the application should display the title Student Roster and then list the names in the array.
Review: Squares
Create a Squares application that stores the square of an elements index in an integer array of 5 elements.
For example, the third element, which has index 2, should store 4. The application should then display the
value of each element in the array.
Review: Reverse
Create a Reverse application that stores the number corresponding to the the elements index in an integer
array of 10 elements. For example, the second element, which has index 1, should store 1. The application
should then display the title Countdown and then list numbers stored in the array in reverse order.
Array Parameters
A method declaration can include array parameters. The array passed
to a method can be either an entire array or an element of the array. The
method below includes an array parameter. A second parameter, an int
parameter, corresponds to an element of the array:
public static void tryChanging(int[] numbers, int aNum) {
numbers[1] = 123;
aNum = 456;
}
Note that the data type followed by brackets indicates an array parameter,
similar to an array declaration.
for-each statement
TIP The for-each is new to
Java 5 and requires JDK 5.
242 Chapter 10 Arrays
s
a
m
p
l
e
The statements below call the tryChanging() method shown on the
previous page:
int[] myNums = {5, 8, 3};
System.out.println(myNums[1] + " " + myNums[0]);
tryChanging(myNums, myNums[0]);
System.out.println(myNums[1] + " " + myNums[0]);
The statements produce the output:
An array is a reference data type similar to a class. Therefore, passing a
whole array to a method passes the reference to the elements, allowing the
method to access an element of the array and change its value. However,
because the elements of the array are a primitve data type, passing a single
element passes only the data stored, not a reference to the data location.
Arrays with Meaningful Indexes
Many algorithms make use of the index value of an array element for
simplifying the storage and retrievel of data. For example, a testScores
array with 101 elements indexed from 0 to 100 could store a count of all the
scores of 90 in the element with index 90, the count of scores 82 in element
82, and so on.
The DiceRolls application counts the frequency of dice roll outcomes.
A roll is simulated by generating two random numbers between 1 and
6. The outcome of each roll is then used to increment the counter in the
element at the index corresponding to the outcome. For example, if a 4 is
rolled, then the value at index 4 is incremented:
import java.util.Scanner;
import java.util.Random;
public class DiceRolls {
public static void main(String[] args) {
int[] outcomes = new int[13];
Scanner input = new Scanner(System.in);
int numRolls;
Random rand = new Random();
int outcome;
/* prompt user for number of rolls */
System.out.print("How many rolls? ");
numRolls = input.nextInt();
/* roll dice and add to outcomes */
for (int roll = 0; roll < numRolls; roll++) {
outcome = (rand.nextInt(6) + 1) + (rand.nextInt(6) + 1);
outcomes[outcome] += 1;
}
/* show counts of outcomes */
for (int i = 2; i <= 12; i++) {
System.out.println(i + ": " + outcomes[i]);
}
}
}
Chapter 10 Arrays 243
s
a
m
p
l
e
The DiceRolls application displays output similar to:
In the DiceRolls application, the outcomes ranged from 2 through 12
making it possible to store counters at array indexes directly correspond-
ing to the outcomes. However, this approach for a range of years 1900
through 2000 would require an array of 2001 elements with only the last
100 elements in use. For ranges such as these, the solution is to store coun-
ters at offset array indexes. For example, for an outcome of 1900, a counter
at index 0 would be incremented. for an outcome of 1901, a counter at index
1 would be incremented, and so on.
To determine the array size when offset array indexes will be used,
subtract the low value from the high and add 1:
int[] counts;
counts = new int[HIGH - LOW + 1];
The following statement increments a counter stored at an offset index:
counts[value - LOW] += 1;
Review: DiceRolls part 1 of 2
Modify the DiceRolls application to roll three dice.
Review: DiceRolls part 2 of 2
The DiceRolls application is not written generically. The application has hard-coded data, including the
maximum random number in the nextInt() method and the initial and final values for i in the show counts
for loop. Modify the DiceRolls application to prompt the user for the number of sides on each die, the num-
ber of dice to be rolled, and the number of rolls to make. For example, a ten-sided die will show a number
between a 1 and a 10 on a roll. Rolling three ten-sided dice has the possible outcomes of 3 through 30.
Review: NumberCounts
Create a NumberCounts application that prompts the user for a number and then counts the occurences of
each digit in that number.
offset array indexes
244 Chapter 10 Arrays
s
a
m
p
l
e
Characters and Arrays
Although strings are comprised of characters, a String object cannot
be manipulated as a set of characters. However, the string stored in a
String object can be converted to a char array. Additionally, an individual
character of the String object can be converted to a char. The String class
methods for working with the characters in a string include:
Class String (java.lang.String)
Method
charAt(int index)
returns a char value that corresponds to the
letter at position index.
toCharArray() returns the String object converted to a char
array.
The value returned by the charAt() method is a char data type. A char
data type represents a single character, such as a letter or symbol. The
toCharArray() method converts each character in the string to a char and
then assigns it to the appropriate element in an existing char array.
Letters of every alphabet and symbols of every culture have been given a
representation in a digital code called Unicode. Unicode uses a set of sixteen
1s and 0s to form a sixteen-bit binary code for each symbol. For example,
the uppercase letter V is Unicode 00000000 01010110, which translates to
the base 10 number 86. Lowercase v has a separate code that translates to
the base 10 number 118.
When a letter is assigned to a char variable, the variable actually stores
the Unicode representation of the letter. Uppercase letters from A to Z have
values from 65 through 90. Lowercase letters from a to z have values from
97 through 122. Because char is a primitive data type, char values can be
compared with relational operators, as the code below demonstrates:
char letter1, letter2;
letter1 = 'a';
letter2 = 'A'
if (letter1 > letter2) {
System.out.println("greater than") //greater than displayed
} else {
System.out.println("less than")
}
The CountLetters application counts the frequency of letters in a string.
Each letter in the string is first converted to uppercase and then the coun-
ter at the appropriate index is incremented. Since uppercase letters have a
range from 65 to 90 in Unicode, offset array indexes are used to determine
which element to update:
import java.util.Scanner;
public class CountLetters {
public static void main(String[] args) {
final int LOW = 'A'; //smallest possible value
final int HIGH = 'Z'; //highest possible value
int[] letterCounts = new int[HIGH - LOW + 1];
Scanner input = new Scanner(System.in);
String word;
char[] wordLetters;
int offset; //array index
charAt()
toCharArray()
Unicode
TIP Refer to the appendix
in this text for more Unicode
symbols and their values.
TIP Assignment to a char vari-
able requires single quotation
marks around the character.
TIP The char data type was
introduced in Chapter 4.
Chapter 10 Arrays 245
s
a
m
p
l
e
/* prompt user for a word */
System.out.print("Enter a word: ");
word = input.nextLine();
/* convert word to char array and count letter occurrences */
word = word.toUpperCase();
wordLetters = word.toCharArray();
for (int letter = 0; letter < wordLetters.length; letter++) {
offset = wordLetters[letter] - LOW;
letterCounts[offset] += 1;
}
/* show letter occurrences */
for (int i = LOW; i <= HIGH; i++) {
System.out.println((char)i + ": " + letterCounts[i - LOW]);
}
}
}
Note the statements for creating a char array from a String object. First,
the char array wordLetters was declared. Later, wordLetters was initialized
using the toCharArray() method in the statement:
wordLetters = word.toCharArray();
The number of characters in the string determined the number of array
elements.
Type casting was used in the last statement of the CountLetters applica-
tion ((char)i) to produce labels for the contents of the array. Casting the
int to a char produces the Unicode equivalent character for that number.
The CountLetters application produces output similar to:
type casting
246 Chapter 10 Arrays
s
a
m
p
l
e
Review: CountLetters
The CountLetters application is limited to counting letters in a single word. Modify the CountLetters
application to count the letters in an entire phrase, which contains spaces. Care must be taken to ignore the
spaces and any other nonalphabetic character found in the phrase. Be sure to change comments and vari-
able names appropriately so that the reader of the application code understands that the letters in a phrase
are counted.
Review: NameBackwards
Create a NameBackwards application that prompts the user for his or her name and then displays the name
backwards.
Searching an Array
There are many ways to search an array for a specific value. The sim-
pliest searching algorithm is called linear search and works by proceeding
from one array element to the next until the specified value is found or
until the entire array has been searched. The Search class below contains
a linear() method that returns the index of a specified int element. If the
element is not found, then -1 is returned:
public class Search {
/**
* Returns the index of the element numToFind.
* -1 returned if element not found.
* pre: none
* post: index of numToFind has been returned. -1 has been
* returned if element not found.
*/
public static int linear(int[] array, int numToFind) {
int index = 0;
while ((array[index] != numToFind) &&
(index < array.length - 1)) {
index += 1;
}
if (array[index] == numToFind) {
return(index);
} else {
return(-1);
}
}
}
The condition of the while statement checks all but the last element of
the array, unless the search element is found earlier. If the while statement
completes without finding the element, the index value has been incre-
mented to the last index of the array The if statement then checks the last
element of the array.
linear search
Algorithm Analysis
Algorithm analysis includes
measuring how efficiently an
algorithm performs its task.
A linear search sequentially
checks each element of an array
for a specified element. For an
array with n objects, finding an
element could take as many as
n checks. This measure can be
written as O(n). This notation
is called Big Oh notation and
is a theoretical measure of an
algorithms efficiency.
Chapter 10 Arrays 247
s
a
m
p
l
e
The application below uses the linear() method to find an element in
the array:
import java.util.Scanner;
import java.util.Random;
public class FindNum {
public static void main(String[] args) {
final int MAX = 20;
int[] numArray = new int[MAX];
Random rand = new Random();
Scanner input = new Scanner(System.in);
int num, location;
/* fill array with random numbers */
for (int i = 0; i < numArray.length;i ++) {
numArray[i] = rand.nextInt(MAX);
}
/* prompt user for a number to search for */
System.out.print("Enter a number between 0 and " + MAX
+ ": ");
num = input.nextInt();
/* Search for number and notify user of num location */
location = Search.linear(numArray, num);
if (location == -1) {
System.out.println("Sorry, number not found in array.");
} else {
System.out.println("First occurrence is element "
+ location);
}
}
}
The FindNum application output looks similar to:
Review: FindName
Add a static method to the Search class that performs a linear search on a String array. The linear() method
should overload the existing method, have parameters for accepting a String array and a String variable,
and return an int indicating the position of the String. Create a FindName application that uses the Search
class. FindName should prompt the user for names to fill an array and then prompt the user for the name
to find.
Two-Dimensional Arrays
An array with two dimensions can be used to represent data that cor-
responds to a grid. For example, a checkerboard, the streets in a city, and
seats in a theater can all be represented with a grid. A tic-tac-toe board
represented in a two-dimensional array can be visualized as shown on
the next page.
248 Chapter 10 Arrays
s
a
m
p
l
e
X
X
O
O
TIP A Bank application was
also developed in Chapter 8.
256 Chapter 10 Arrays
s
a
m
p
l
e
The LocalBank algorithm:
1. Display a menu of options.
2. Prompt the user for a menu choice.
3. For all options except the option to add an account, prompt the
user for an account number.
4. Perform the action requested by the user on the account with the
number entered. If the user requested to create a new account, then
add an account and display the new accounts number.
5. Repeat steps 1 through 4 until the user has selected the option to
quit.
LocalBank Code Design
The LocalBank application can be modeled with a Bank object, Account
objects, and Customer objects. The Bank object should store the accounts,
add and remove accounts, and perform transactions that also display
updated account information. A transaction requires finding the correct
account. The Account objects should store the current balance, make
deposits, make withdrawals, and return the current balance and account
ID. An Account object must also have an equals() method for the Bank
object to use when finding an account. The Customer objects should store
the account holders name. The Bank object will display account infor-
mation, therefore, the Account and Customer objects will override the
toString() methods.
The LocalBank class designs are:
Chapter 10 Arrays 257
s
a
m
p
l
e
The Account and Customer class designs are similar to the classes devel-
oped in Chapter 8. In the real world, the existing classes would probably
be reused for the LocalBank application. The modularity of OOP makes
programming more efficient and less error-prone. For this case study,
simplified classes will be developed and used for the application.
Based on the algorithm and the class designs, the LocalBank code
design will include a loop. The pseudocode for the LocalBank client code
follows:
Bank easySave = new Bank();
do {
prompt user for transaction type
if (add account) {
easySave.addAccount();
} else if (not Quit) {
prompt user for account ID;
if (deposit) {
prompt user for deposit amount
easySave.transaction(make deposit, acctID, amt);
} else if (withdrawal) {
prompt user for withdrawal amount
easySave.transaction(make withdrawal, acctID, amt);
} else if (check balance) {
easySave.checkBalance(acctID);
} else if (remove account) {
easySave.deleteAccount(acctID);
}
}
} while (not quit);
258 Chapter 10 Arrays
s
a
m
p
l
e
LocalBank Implementation
The LocalBank implementation involves creating four files. Three files
are the classes and one file is the client code.
The Bank class is implemented below:
/**
* Bank class.
*/
import java.util.ArrayList;
import java.util.Scanner;
public class Bank {
private ArrayList accounts;
/**
* constructor
* pre: none
* post: accounts has been initialized.
*/
public Bank() {
accounts = new ArrayList();
}
/**
* Adds a new account to the bank accounts.
* pre: none
* post: An account has been added to the bank's accounts.
*/
public void addAccount() {
Account newAcct;
double bal;
String fName, lName;
Scanner input = new Scanner(System.in);
System.out.print("First name: ");
fName = input.nextLine();
System.out.print("Last name: ");
lName = input.nextLine();
System.out.print("Beginning balance: ");
bal = input.nextDouble();
newAcct = new Account(bal, fName, lName); //create acct object
accounts.add(newAcct); //add account to bank accounts
System.out.println("Account created. Account ID is: " + newAcct.getID());
}
/**
* Deletes an existing account.
* pre: none
* post: An existing account has been deleted.
*/
public void deleteAccount(String acctID) {
int acctIndex;
Account acctToMatch;
Chapter 10 Arrays 259
s
a
m
p
l
e
acctToMatch = new Account(acctID);
acctIndex = accounts.indexOf(acctToMatch); //retrieve location of account
if (acctIndex > -1) {
accounts.remove(acctIndex); //remove account
System.out.println("Account removed.");
} else {
System.out.println("Account does not exist.");
}
}
/**
* Performs a transaction on an existing account. A transCode of 1 is for deposits
* and a transCode of 2 is for withdrawals.
* pre: transCode is 1 or 2.
* post: A transaction has occurred for an existing account.
*/
public void transaction(int transCode, String acctID, double amt) {
int acctIndex;
Account acctToMatch, acct;
acctToMatch = new Account(acctID);
acctIndex = accounts.indexOf(acctToMatch); //retrieve location of account
if (acctIndex > -1) {
acct = (Account)accounts.get(acctIndex); //retrieve object to modify
if (transCode == 1) {
acct.deposit(amt);
accounts.set(acctIndex, acct); //replace object with updated object
System.out.println(acct);
} else if (transCode == 2) {
acct.withdrawal(amt);
accounts.set(acctIndex, acct); //replace object with updated object
System.out.println(acct);
}
} else {
System.out.println("Account does not exist.");
}
}
/**
* Displays the account information, including the current balance,
* for an existing account.
* pre: none
* post: Account information, including balance, has been displayed.
*/
public void checkBalance(String acctID) {
int acctIndex;
Account acctToMatch, acct;
acctToMatch = new Account(acctID);
acctIndex = accounts.indexOf(acctToMatch); //retrieve location of account
if (acctIndex > -1) {
acct = (Account)accounts.get(acctIndex); //retrieve object to display
System.out.println(acct);
} else {
System.out.println("Account does not exist.");
}
}
}
In the deleteAccount() and transaction() methods, a new Account object
is created for the purposes of finding the account to delete or modify. The
new Account object is instantiated with just the acctID and then this object
is passed to the indexOf() method of the ArrayList class. The indexOf()
260 Chapter 10 Arrays
s
a
m
p
l
e
method searches the ArrayList and automatically invokes the equals()
method of the Account class to determine equality. The Account class is
implemented below. Note that the equals() method requires only that the
account numbers of two object match to be considered equal:
/**
* Account class.
*/
import java.text.NumberFormat;
public class Account {
private double balance;
private Customer cust;
private String acctID;
/**
* constructor
* pre: none
* post: An account has been created. Balance and
* customer data has been initialized with parameters.
*/
public Account(double bal, String fName, String lName) {
balance = bal;
cust = new Customer(fName, lName);
acctID = fName.substring(0,1) + lName;
}
/**
* constructor
* pre: none
* post: An empty account has been created with the specified account ID.
*/
public Account(String ID) {
balance = 0;
cust = new Customer("", "");
acctID = ID;
}
/**
* Returns the account ID.
* pre: none
* post: The account ID has been returned.
*/
public String getID() {
return(acctID);
}
/**
* Returns the current balance.
* pre: none
* post: The account balance has been returned.
*/
public double getBalance() {
return(balance);
}
Chapter 10 Arrays 261
s
a
m
p
l
e
/**
* A deposit is made to the account.
* pre: none
* post: The balance has been increased by the amount of the deposit.
*/
public void deposit(double amt) {
balance += amt;
}
/**
* A withdrawal is made from the account if there is enough money.
* pre: none
* post: The balance has been decreased by the amount withdrawn.
*/
public void withdrawal(double amt) {
if (amt <= balance) {
balance -= amt;
} else {
System.out.println("Not enough money in account.");
}
}
/**
* Returns a true when objects have matching account IDs.
* pre: none
* post: true has been returned when the objects are equal,
* false returned otherwise.
*/
public boolean equals(Object acct) {
Account testAcct = (Account)acct;
if (acctID.equals(testAcct.acctID)) {
return(true);
} else {
return(false);
}
}
/**
* Returns a String that represents the Account object.
* pre: none
* post: A string representing the Account object has been returned.
*/
public String toString() {
String accountString;
NumberFormat money = NumberFormat.getCurrencyInstance();
accountString = acctID + "\n";
accountString += cust.toString();
accountString += "Current balance is " + money.format(balance);
return(accountString);
}
}
The Account class has two constructors. The second constructor is used
in the deleteAccount() and transaction() methods of the Bank class for the
purposes of finding the index of the account matching the given account
ID.
262 Chapter 10 Arrays
s
a
m
p
l
e
The Customer class is implemented below:
/**
* Customer class.
*/
public class Customer {
private String firstName, lastName;
/**
* constructor
* pre: none
* post: A Customer object has been created.
* Customer data has been initialized with parameters.
*/
public Customer(String fName, String lName) {
firstName = fName;
lastName = lName;
}
/**
* Returns a String that represents the Customer object.
* pre: none
* post: A string representing the Customer object has
* been returned.
*/
public String toString() {
String custString;
custString = firstName() + " " + lastName() + "\n";
return(custString);
}
}
The LocalBank client code is implemented below:
/**
* A bank where accounts can be opened or closed and customers can
* make transactions.
*/
import java.util.Scanner;
public class LocalBank {
public static void main(String[] args) {
Bank easySave = new Bank();
Scanner input = new Scanner(System.in);
String action, acctID;
Double amt;
/* display menu of choices */
do {
System.out.println("\nDeposit\\Withdrawal\\Check balance");
System.out.println("Add an account\\Remove an account");
System.out.println("Quit\n");
System.out.print("Enter choice: ");
action = input.next();
Chapter 10 Arrays 263
s
a
m
p
l
e
if (action.equalsIgnoreCase("A")) {
easySave.addAccount();
} else if (!action.equalsIgnoreCase("Q")) {
System.out.print("Enter account ID: ");
acctID = input.next();
if (action.equalsIgnoreCase("D")) {
System.out.print("Enter deposit amount: ");
amt = input.nextDouble();
easySave.transaction(1, acctID, amt);
} else if (action.equalsIgnoreCase("W")) {
System.out.print("Enter withdrawal amount: ");
amt = input.nextDouble();
easySave.transaction(2, acctID, amt);
} else if (action.equalsIgnoreCase("C")) {
easySave.checkBalance(acctID);
} else if (action.equalsIgnoreCase("R")) {
easySave.deleteAccount(acctID);
}
}
} while (!action.equalsIgnoreCase("Q"));
}
}
Running the LocalBank application displays output similar to:
It was possible to create the LocalBank application with fewer classes.
However, by breaking the application into discrete objects, it will be
easier to later extend the classes to enhace the client code. For example,
an account can easily be extended to include an account holders address
by modifying, or extending, the Customer class. Then, only the first con-
structor of the Account class will need to be modifed to handle additional
parameters for creating a Customer object.
264 Chapter 10 Arrays
s
a
m
p
l
e
LocalBank Testing and Debugging
When a new class is written, client code should be written to test the
class. Testing should be done first for each class and then for the client
code.
Review: LocalBank
Modify the Bank class to prompt the user for a full address (street, city, state, and zip) when an account is
opened. Modify the Customer class to include street, city, state, and zip variable members and changeStreet(),
changeCity(), changeState(), and changeZip() method members. Modify the Account class to include a
changeAddress() method member. Modify the Bank class to include a modifyAccount() method member
that requires a parameter for the account ID. modifyAccount() should prompt the user for the new street,
city, state, and zip for the account, find the account with the matching account ID, and then overwrite the
existing account object with the object containing the updated information.
Chapter Summary
This chapter discussed arrays as a structure for storing many of the
same kind of data together at once. A data item stored by an array is called
an element. An element has an index value and is accessed by using the
index inside of [] brackets along with the array name. A for statement and
the for-each statement can be used to access all the elements of an array.
Accessing the elements of an array is called traversing the array. When
the index of an element is needed, the for statement should be used.
An array can be passed to a method as a parameter and is a reference
data type. Passing a single element passes the data stored, not a reference
to the data location.
Many algorithms make use of the index value of an array element for
simplifying the storage and retrieval of data. Offset array indexes are
used when a range should be shifted to correlate to a lower range of index
values.
A String can be converted to an array of characters so that individual
characters can be maipulated. Unicode is the standard for numeric repre-
sentation of every letter and symbol in use.
The linear search is an algorithm for searching an array where each ele-
ment is checked one after the other until the desired element is found.
Two-dimensional arrays represent data that corresponds to a grid. The
number of rows in an existing two-dimensional array corresponds to the
length of the array. The number of columns corresponds to the length of
the first row. Elements in a two-dimensional array are accessed by using
a double bracket ([][]) along with the array name.
The ArrayList class is used for storing a collection of objects. Methods
are used for accessing and retrieving elements and for determining the
number of elements in the collection. An ArrayList object is a dynamic
array, which can vary in size at run time. Because an ArrayList can store
only objects, wrapper classes are used to represent primitive types that
are to be stored in an ArrayList.
Chapter 10 Arrays 265
s
a
m
p
l
e
Vocabulary
Array A structure that can store many of the same
kind of data together at once.
ArrayOutOfBoundsException An exception
thrown when an invalid array index is used.
Collection A group of related elements that are
stored together as a single unit.
Collections framework Classes for implementing
collections.
Dynamic array An array that varies in size at run
time.
Element A data item in an array.
Index The value associated with an element in an
array. Index values begin at 0 and count up.
Linear search An algorithm for searching an array
in which each element of the array is checked one
after the other.
Java
[] The operators for accessing an array element.
ArrayList A java.util class with methods for imple-
menting a dynamic array.
Double A java.lang class for wrapping double values
in an object.
for A statement that can be used to traverse an array.
In one form, it is referred to as a for-each statement
and does not use a counter variable.
Integer A java.lang class for wrapping int values
in an object.
new Operator that allocates space for the elements
in an array.
String A java.lang class with methods for convert-
ing a string to a set of characters or for inspecting
individual characters of a string.
Traversing Iterating through element of an array.
Unicode The sixteen-bit digital code used to
represent every letter and symbol.
Wrapper class A class that wraps primitive values
in an object.
266 Chapter 10 Arrays
s
a
m
p
l
e
Critical Thinking
1. What index value does the third element of an
array have?
2. Write the declaration for an array named
quantities that stores 20 integers.
3. Write a declaration for an array named heights
storing the numbers 1.65, 2.15, and 4.95.
4. Write a for-each statement that displays the inte-
ger values stored in an array named grades.
5. a) Write an algorithm for inserting data into an
array so that existing data is moved up one
position to make room for the new data.
b) Write an algorithm for deleting data from an
array so that existing data is moved to close
the gap made by the deleted data.
6. How does passing an entire array to a method
differ from passing a single element of the
array?
7. Why are offset array indexes required in some
cases.
8. What output is displayed by the statements
below?
String name = "Elaine";
System.out.println(name.charAt(3));
9. Compare and contrast an array to an ArrayList
by describing the differences between the two
for:
a) accessing an element.
b) adding an element.
c) deleting an element.
d) assigning a new value to an element.
e) determining the size of the collection.
10. Give an example of when a dynamic array might
be a better structure choice over an array.
11. How does the ArrayList indexOf() method
determine equality between the object passed
to the method and an element in the array?
12. How can the values of wrapper class objects be
compared?
True/False
13. Determine if each of the following are true or
false. If false, explain why.
a) All data in an array has the same data
type.
b) Index values always begin at 0.
c) The statement int[] empNums = new int[10]
declares an array with 10 elements.
d) In the statement int[] empNums = new int[10],
the elements are automatically initialized to
1.
e) An entire array can be passed to a method.
f) The method toCharArray() converts a String
object to a char array.
g) A linear search never searches an entire
array.
h) The statement int[][] grid = new int[4][4]
declares a total of eight elements.
i) In Unicode, uppercase letters have higher
base 10 number values than lowercase
letters.
j) The size of an array can change during the
execution of a program.
k) The ArrayList class implements a dynamic
array.
l) Primitive data types can be stored directly
in an ArrayList.
Chapter 10 Arrays 267
s
a
m
p
l
e
Exercises
Exercise 1 EvensAndOdds
Create an EvensAndOdds application that generates 25 random integers between 0 and 99 and then
displays all the evens on one line and all the odds on the next line. Application output should look
similar to:
Exercise 2 GeneratedNums
Create a GeneratedNums application that generates the number to store in an array element by sum-
ming its index and the individual digits of the index. For example, the element with index 17 should
store 25 (17 + 1 + 7 = 25) and the element with index 2 should store 4 (2 + 0 + 2 = 4). GeneratedNums
should use an array with 101 elements and then display the value at each element. Application output
should look similar to:
Exercise 3 RandomStats
Create a RandomStats application that generates 500 random numbers between 0 and 9 and then dis-
plays the number of occurrences of each number. Application output should look similar to:
268 Chapter 10 Arrays
s
a
m
p
l
e
Exercise 4 Analysis
A program that analyzes a set of numbers can be very useful. Create an Analysis application that
prompts the user for numbers in the range 1 through 50, terminated by a sentinel, and then performs
the following analysis on the numbers:
Determine the average number
Determine the maximum number
Determine the range (maximum minimum)
Determine the median (the number that occurs the most often)
Displays a bar graph called a histogram that shows the numbers in each five-unit
range (15, 610, 11-15, etc.). The histogram may look similar to:
Exercise 5 Mastermind
The game of Mastermind is played as follows: One player (the code maker) chooses a secret arrange-
ment of colored pegs and the other player (the code breaker) tries to guess it. For each guess, the code
breaker puts forth an arrangement of colored pegs, and the code maker reports two numbers:
1. The number of pegs that are the correct color and in the correct position.
2. The number of pegs that are the correct color regardless of whether they are in the
correct position.
Create a Mastermind application that plays the game of Mastermind with the computer as the code
maker and the user as the code breaker. The application should use a mastermindGame class, which has
a constructor with parameters for the number of pegs in the code (1 to 10) and the number of colors for
the pegs (1 to 9). The secret code generated by a mastermindGame object can contain duplicate colors.
For example, a 5-peg code could be 1 2 2 5 6. A guess with duplicates will require extra attention when
counting the number of pegs of the correct color. For example, if the code is 1 2 3 4 5 6 and the guess
is 2 1 1 2 2 2, then the mastermindGame object should only report two correct colors (a single 1 and a
single 2). Application output should look similar to:
Chapter 10 Arrays 269
s
a
m
p
l
e
Exercise 8 Palindrome
Create a Palindrome application that prompts the user for a string and then displays a message
indicating whether or not the string is a palindrome. A palindrome is a word or phrase that is
spelled the same backwards and forwards. For example, mom is a palindrome, as well as kayak
and Never odd or even.
Exercise 9 CountConsonants
Create a CountConsonants application that prompts the user for a string and then displays the
number of consonants in the string. Application output should look similar to:
Exercise 10 Coder
Create a Coder application that prompts the user for a string and then displays an encoded string.
The encoding should add 2 to the Unicode value of each letter to create a new letter. The application
should keep all spaces between the words in their original places and the letters x and y should
be converted to a and b, respectively. Coder application output should look similar to:
270 Chapter 10 Arrays
s
a
m
p
l
e
Exercise 11 SortedArray
An array is said to be sorted if its elements are in either increasing or decreasing order. One way the
selection sort algorithm works is by repeatedly taking the lowest element from an array and adding it
to a new array, so that all the elements in the new array are sorted from lowest to highest.
Create a SelectionSort class with a constructor that has an int array parameter, member variables
originalArray and sortedArray, public method display() that displays the contents of the sorted array,
private methods sort() that populates a new array with the elements of the original array in order from
lowest to highest, and findLowest() that returns the index of the element containing the lowest value.
Hint: Since elements of an array cannot actually be removed an element can be set to a very high
value after determining its value is the lowest.
Create client code SortedArray, which tests the SelectionSort class. Use the pseudocode below when
implementing the SortedArray client code:
int[] myNums;
SelectionSort sortedArray;
prompt user for the number of values to populate array with
myNums = new int[values];
populate array with random integers between 0 and 100
display contents of original array
sortedArray = new SelectionSort(myNums);
sortedArray.display();
Exercise 12 CourseGrades
Create a CourseGrades application that simulates a grade book for a class with 12 students that each have
5 test scores. The CourseGrades application should use a GradeBook class that has member variables
grades, which is a two-dimensional array or integers, and methods getGrades() for prompting the user
for the test grades for each student, showGrades() that displays the grades for the class, studentAvg()
that has a student number parameter and then returns the average grade for that student, and testAvg()
that has a test number parameter and then returns the average grade for that test.
Exercise 13 PennyPitch
The Penny Pitch game is popular in amusement parks. Pennies are tossed onto a board that has certain
areas marked with different prizes. For example:
The prizes available on this board are puzzle, game, ball, poster, and doll. At the end of the game, if all
of the squares that say BALL are covered by a penny, the player gets the ball. This is also true for the
other prizes. The board is made up of 25 squares (5 x 5). Each prize appears on three randomly chosen
squares so that 15 squares contain prizes.
Chapter 10 Arrays 271
s
a
m
p
l
e
Create a PennyPitch application that displays a Penny Pitch board (use [ and ] to indicate squares) with
prizes randomly placed and then simulates ten pennies being randomly pitched onto the board. After
the pennies have been pitched, the application should display a message indicating which prizes have
been won, it any.
Exercise 14 Life
The Game of Life was devised by mathematician John Conway in 1970. It models a very simple world.
The Life world is a two-dimensional plane of cells. Each cell may be empty or contain a single creature.
Each day, creatures are born or die in each cell according to the number of neighboring creatures on
the previous day. A neighbor is a cell that adjoins the cell either horizontally, vertically, or diagonally.
The rules in pseudocode style are:
if (the cell is alive on the previous day) {
if (the number of neighbors was 2 or 3) {
the cell remains alive
} else {
the cell dies
}
} else if (the cell is not alive on the previous day) {
if (the number of neighbors was exactly 3) {
the cell becomes alive
} else {
the cell remains dead
}
}
For example, the world displayed as:
0000000000
0000000000
000XXX0000
0000000000
0000000000
0000000000
where Xs indicate living cells, becomes:
0000000000
0000X00000
0000X00000
0000X00000
0000000000
0000000000
Create a Life application that has a 20 x 20 grid. To initialize the grid, the application should prompt the
user for the coordinates of live cells on the first day. The application should then generate each days
world as long as the user wishes to continue or until there are no more live cells.
272 Chapter 10 Arrays
s
a
m
p
l
e
Exercise 15 Manacala
The game of Mankala is played on a board like that illustrated below:
Players sit on opposite sides with the large bin to a players right designated her home bin. On a turn,
a player selects one of the six pits to remove the stones from and then sows the stones counterclock-
wise around the board, placing one stone in each pit including the players home bin (but excluding
the opponents home bin). If the last stone lands in the players home bin, the player gets another turn.
If the last stone lands in an empty pit on the players side of the board, the player takes all stones in
the corresponding pit on the opponents side and places them in the players home bin. When a player
cannot play, the game is over and all stones remaining in the opponents pits go to the opponents home
bin. The winner is the player with the most stones in the players home bin at the end of the game.
For example, if the bottom player plays first and chooses the fourth pit to play from, the board
looks like:
Since the last stone landed in the players home bin, the player takes nother turn. The player may
choose the first pit this time in order to capture the opponents stones:
The players turn is now over, and the opponent now has a turn.
Create a Mankala application. The application should use simple characters to illustrate the board,
and letters to identify the pits, similar to that shown below:
3 3 3 3 3 3
0 0
3 3 3 3 3 3
A B C D E F
Chapter 10 Arrays 273
s
a
m
p
l
e
Exercise 16 Inventory
Create an Inventory application that keeps track of the inventory for a sports store. Each item has a
stock number, with the first item having a stock number of 1000. The second item has a stock number
1001, the third has stock number 1002, and so on. Along with a stock number, each item has an item
name and an amount in stock. New items can be added to the inventory at any time. When added, the
item stock number is generated and displayed to the user. Discontinued items should not be deleted
from the inventory, but rather their item name should be changed to discontinued and the amount
in stock should be decreased to 0. The Inventory application should use an ArrayList for maintaining
the invemtory and application output should display a menu of choices, which allow for adding an
item, discontinuing an item, and displaying the amount in stock for an item.
274 Chapter 10 Arrays
s
a
m
p
l
e
Chapter 11 GUIs and Event-Driven Programming 275
s
a
m
p
l
e
Swing is a Java package that provides a set of classes for creating
graphical user interfaces (GUIs). This chapter explains how to use the
basic Swing components to create applications with a GUI. Components
covered in this chapter include frames, panels, labels, buttons, combo
boxes, and text fields.
What is a GUI?
A GUI is a graphical user interface (sometimes pronounced gooey). An
application written for the Microsoft Windows or Mac OSX Tiger operating
system typically has a GUI. The GUI below includes a frame, also called
a window, and a label:
Not only does a GUI use components such as frames, buttons, and
text fields to communicate with the user, but GUIs are event-driven. An
event-driven application executes code in response to events. An event is an
interaction from the user, such as a button click. A GUI responds to an
event by executing a method called an event handler. For example, when
the user clicks a button, the application must be able to determine which
button was clicked and then execute the code that relates to that button.
The Swing Package
The Swing API is part of the Java Foundation Classes (JFC) and contains
numerous components for creating GUIs. This chapter focuses on the
javax.swing package. Two classes in this package are JFrame and JLabel.
The JFrame class is used to instantiate a frame. A frame is a window with
a border, title, and buttons for minimizing, maximizing, and closing the
frame. A frame is a top-level container for a GUI, which holds and displays
all the other components of an interface in a content frame. One of the most
common components in a content frame is a label. Labels, created with the
JLabel class, are used to display text that cannot be changed by the user.
Chapter 11
GUIs and Event-Driven
Programming
TIP The applications created
prior to this chapter had a text-
based, or console, interface.
event-driven application
event handler
javax.swing
frame
container, content frame
labels
276 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The swing package includes the JFrame class with the following
methods:
Class JFrame (javax.swing.JFrame)
Method
setDefaultLookAndFeelDecorated(boolean)
sets the frames created after this class method
is called to have Java Window decorations, such
as borders and a title, when the boolean argu-
ment is true.
setDefaultCloseOperation(class _ constant)
sets the operation that occurs when the user
clicks the Close button. The class _ constant
argument is usually JFrame.EXIT _ ON _ CLOSE.
getContentPane()
returns a Container object corresponding to the
content pane.
setContentPane(Container contentPane)
sets the content pane to contentPane. The
Container class is the superclass for the JPanel
class, a class for creating content panes.
pack() sizes the frame so that all of its contents are at
or above their preferred sizes.
setVisible(boolean)
displays the frame when the boolean argument
is true.
A JFrame object uses a content pane to hold GUI components. A JPanel
object is one choice for a simple content pane. The JPanel class includes
the following methods for adding and removing components:
Class JPanel (javax.swing.JPanel)
Method
add(Component GUIcomponent)
adds a GUIcomponent to the content pane. When
added, components are given an index value,
with the first component at index 0.
remove(int index)
removes the component with index value
index.
After adding components to the JPanel object, the content frame is added
to the JFrame object using the JFrame setContentPane() method described
above.
The swing package includes the JLabel class for creating labels that
can be added to a content pane. JLabels have several constructors, two of
which are described, in addition to the setText() method:
JPanel content pane
Chapter 11 GUIs and Event-Driven Programming 277
s
a
m
p
l
e
Class JLabel (javax.swing.JLabel)
Constructor/Method
JLabel(String str)
creates a JLabel object with text str.
JLabel(String str, align _ constant)
creates a JLabel object with text str and align-
ment align _ constant that can be set to JLabel
class constants LEADING or TRAILING, which are
left and right alignment, respectively.
setText(String str)
sets the text of the JLabel object to str.
The HelloWorldWithGUI1 application creates a frame and a content
pane, adds the content pane to the frame, and then displays the frame:
import javax.swing.*;
public class HelloWorldWithGUI1 {
final static String LABEL _ TEXT = "Hello, world!";
JFrame frame;
JPanel contentPane;
JLabel label;
public HelloWorldWithGUI1(){
/* Create and set up the frame */
frame = new JFrame("HelloWorldWithGUI");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane */
contentPane = new JPanel();
/* Create and add label */
label = new JLabel(LABEL _ TEXT);
contentPane.add(label);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
/**
* Create and show the GUI.
*/
private static void runGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
HelloWorldWithGUI1 greeting = new HelloWorldWithGUI1();
}
public static void main(String[] args) {
/* Methods that create and show a GUI should be
run from an event-dispatching thread */
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
runGUI();
}
});
}
}
TIP The HelloWorldWithGUI1
application output is shown on
the first page of this chapter.
278 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The implementation of a Swing application is different from previous
applications presented in this text. The controlling class contains a con-
structor and members in addition to the main() method. Therefore, the
controlling class is actually used to instantiate an object, which imple-
ments the GUI.
The statement in the main() method runs the GUI from an event-
dispatching thread. A thread is simply a process that runs sequentially
from start to finish. GUIs should be invoked from an event-dispatching
thread to ensure that each event-handler finishes executing before the
next one executes. Thorough coverage of this topic is beyond the scope
of this text. However, the code shown is needed in every application that
implements a Swing GUI.
Review: Name part 1 of 2
Create a Name application that displays your name in a label inside a JFrame.
The JButton Class
A button is a commonly used GUI component. A button can be clicked
by the user to communicate with the application. For example, the
HelloWorldWithGUI2 application includes a button that when clicked
either hides or displays text in the label:
The swing package includes the JButton class for creating buttons:
Class JButton (javax.swing.JButton)
Method
JButton(String str)
creates a JButton object displaying the text
str.
setActionCommand(String cmd)
sets the name of the action performed when the
button is clicked to cmd .
getActionCommand()
returns the name of the action that has been
performed by the button.
addActionListener(Object)
adds an object that listens for the user to click
this component.
Unlike a JLabel, a JButton can respond to interaction from the user.
thread
Chapter 11 GUIs and Event-Driven Programming 279
s
a
m
p
l
e
Handling Events
Swing components use listeners to determine if an event has occurred. A
listener is an object that listens for action events. When an event is heard, the
listener responds by executing an event handler named actionPerformed().
The actionPerformed() method has an ActionEvent parameter passed by
the GUI when an event occurs. The ActionEvent object includes an action
command. An action command is a string describing an event, or action.
The HelloWorldWithGUI2 application output is shown in the previous
section. When the Hide button is clicked, the application GUI changes to
display:
The HelloWorldWithGUI2 application code is below. For this GUI, a
JButton is created, the JButton action command is set, and the current
object is the listener for JButton action events. Note the use of the keyword
this for the listener object to indicate the HelloWorldWithGUI2 object
itself:
import javax.swing.*;
import java.awt.event.*
public class HelloWorldWithGUI2 implements ActionListener {
final static String LABEL _ TEXT = "Hello, world!";
JFrame frame;
JPanel contentPane;
JLabel label;
JButton button;
public HelloWorldWithGUI2(){
/* Create and set up the frame */
frame = new JFrame("HelloWorldWithGUI");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane */
contentPane = new JPanel();
/* Create and add label */
label = new JLabel(LABEL _ TEXT);
contentPane.add(label);
/* Create and add button */
button = new JButton("Hide");
button.setActionCommand("Hide");
button.addActionListener(this);
contentPane.add(button);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
listener
action command
this
280 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
/**
* Handle button click action event
* pre: Action event is Hide or Show
* post: Clicked button has different text, and label
* displays message depending on when the button was clicked.
*/
public void actionPerformed(ActionEvent event) {
String eventName = event.getActionCommand();
if (eventName.equals("Hide")) {
label.setText(" ");
button.setText("Show");
button.setActionCommand("Show");
} else {
label.setText(LABEL _ TEXT);
button.setText("Hide");
button.setActionCommand("Hide");
}
}
/**
* Create and show the GUI.
*/
private static void runGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
HelloWorldWithGUI2 greeting = new HelloWorldWithGUI2();
}
public static void main(String[] args) {
/* Methods that create and show a GUI should be
run from an event-dispatching thread */
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
runGUI();
}
});
}
}
A class that uses a listener must implement an ActionListener. This is
done by adding implements ActionListener to the class declaration and then
defining an actionPerformed() method, which is the only method in the
ActionListener interface. An import java.awt.event statement is required
to import the package containing the ActionListener interface.
The GUI is implemented in the constructor. The segment of code that
creates and adds the button does four things. First, a button that displays
Hide is created. Second, because the user will see a Hide button the action
command associated with this button should be Hide. Third, a listener
is needed to determine when the user clicks the button. The listener is set
to the HelloWorldWithGUI2 object itself (this). Fourth, the button is added
to the content pane.
The actionPerformed() method is passed an ActionEvent argument
by the GUI when the button is clicked. ActionEvent objects have a
getActionCommand() method. This method returns the string assigned
as the objects action command. For the Show/Hide button, the action
command, as well as the button text, is changed each time the button is
clicked.
TIP awt stands for Abstract
Windows Toolkit.
Chapter 11 GUIs and Event-Driven Programming 281
s
a
m
p
l
e
Review: Name part 2 of 2
Modify the Name application to display or hide your name depending on the button clicked by the user,
similar to the HelloWorldWithGUI2 application.
Review: NumClicks
Create a NumClicks application that contains a button displaying how many times the user has clicked that
button. The application interface should look similar to the following after the user has clicked the button
12 times:
For this application it is not necessary to set the action command. A call to the getActionCommand() method
in the actionPerformed() method is also not needed.
Controlling Layout
Layout refers to the arrangement of components. In a Swing GUI, the
layout of a content pane can be controlled by adding borders, using a layout
manager, and setting alignments.
A border can be added to most components, including the content pane.
An invisible, or empty, border can be used to add padding around a
component to give it distance from other components. Adding an empty
border to the content pane adds space between the components and the
edges of the frame. For example, the content pane in the GUI on the left
has no border, but the content pane on the right has an empty border of
20 pixels on the top, left, bottom, and right:
An empty border in the content pane on the right provides
padding between the components and the frame
A layout manager determines the order of components on a content pane.
There are many layout managers to choose from, including FlowLayout,
BoxLayout, and GridLayout. The FlowLayout manager places components
one next to the other in a row. When a row becomes too long, a new
row is started. The FlowLayout manager is the default manager. The
HelloWorldWithGUI applications use this manager.
layout manager
layout
TIP Pixel stands for picture
element and the number of
pixels in a surface depends on
the screen resolution.
borders
FlowLayout manager
282 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The BoxLayout manager places components one after the other in a col-
umn, with one component per line. For example, the GUI below uses the
BoxLayout manager:
The BoxLayout manager places components one after the
other in a column
The GridLayout manager places components into a grid of rows and col-
umns. The intersection of a row and column is called a cell. There is one
component per cell in a GridLayout. The GUI below uses a GridLayout.
An additional button was added to illustrate the grid:
The GridLayout manager places components
into a grid of cells
Another factor that affects layout is alignment. Alignment refers to the
placement of a component within a layout. For example, both GUIs below
use a BoxLayout, have an empty border of 20, 20, 20, and 20 in the content
pane, and a 20, 50, 20, 50 empty border around the label. The GUI on the
left specifies no aligment for the components, and the GUI on the right
center aligns the label and the button:
Alignment affects the placement of components
within a layout
The HelloWorldWithGUI2 application modified to use a layout manager,
borders, and alignment:
GridLayout manager
BoxLayout manager
alignment
TIP The BoxLayout manager
also includes methods for add-
ing glue and rigid areas to
a layout to control placement
of components.
Chapter 11 GUIs and Event-Driven Programming 283
s
a
m
p
l
e
import javax.swing.*;
import java.awt.event.*;
public class HelloWorldWithGUI2 implements ActionListener {
final static String LABEL _ TEXT = "Hello, world!";
JFrame frame;
JPanel contentPane;
JLabel label;
JButton button;
public HelloWorldWithGUI2(){
/* Create and set up the frame */
frame = new JFrame("HelloWorldWithGUI");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane with a BoxLayout and
empty borders */
contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.PAGE _ AXIS));
contentPane.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
/* Create and add label that is centered and
has empty borders */
label = new JLabel(LABEL _ TEXT);
label.setAlignmentX(JLabel.CENTER _ ALIGNMENT);
label.setBorder(BorderFactory.createEmptyBorder(20, 50, 20, 50));
contentPane.add(label);
/* Create and add button that is centered */
button = new JButton("Hide");
button.setAlignmentX(JButton.CENTER _ ALIGNMENT);
button.setActionCommand("Hide");
button.addActionListener(this);
contentPane.add(button);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
rest of HelloWorldWithGUI2 code
The JPanel setLayout() method is used to specify a layout for the content
pane. A BoxLayout object requires arguments for the content pane and the
arrangement. To arrange components in a vertical line, the class constant
PAGE _ AXIS is specified.
The JPanel setBorder() method is used to specify borders for the con-
tent pane. The BorderFactory class has many different kinds of borders
to choose from. For invisible, or empty borders, the createEmptyBorder()
method is used. The arguments specify the width of the top, left, bottom,
and right of the border.
The JLabel and JButton setAlignmentX() methods are used to specify
the vertical alignment of the components within the layout. Both classes
include several alignment constants, including CENTER _ ALIGNMENT.
TIP Experiment wit h t he
numerous types of borders.
setLayout() method
setBorder() method
setAlignment() method
284 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The modified HelloWorldWithGUI2 application produces a GUI that
looks similar to:
For GUIs with components that should be side by side in rows, the
GridLayout manager may be a better choice. The GridLayout manager is
specified in a statement similar to:
contentPane.setLayout(new GridLayout(0, 2, 10, 5))
The GridLayout object requires arguments for specifying the number
of rows and columns and the space between columns and rows. If 0 is
specified for either the rows or columns, the class creates an object with
as many rows or columns as needed. However, only one argument can be
0. In the statement above, the GridLayout object will have as many rows
as needed and 2 columns. There will be 10 pixels between columns and 5
pixels between rows. The GridLayout class is part of the java.awt package.
Code using this manager requires an import java.awt.* statement.
Review: Sunflower
Create a Sunflower application that displays the Latin name for the sunflower when Latin is clicked and the
English name when English is clicked. The application GUI should use a BoxLayout manager and look similar
to the following after Latin has been clicked:
Review: Riddle
Create a Riddle application that displays a riddle and then solves it when Answer is clicked. The application
GUI should use a GridLayout manager and look similar to the following after Answer has been clicked:
GridLayout manager
java.awt
TIP The GridLayout manager
places components in rows
from left to right in the order
that they are added to the con-
tent pane.
Chapter 11 GUIs and Event-Driven Programming 285
s
a
m
p
l
e
Getting Input from the User
A text field allows a user to enter information at run time. Text fields
are usually placed next to a label to prompt the user for the type of data
expected in the text field. For example, the SemesterAvg application
prompts the user to enter three test grades and then displays the average
of the grades when Average is clicked:
The swing package includes the JTextField class with the following
constructors and methods:
Class JTextField (javax.swing.JTextField)
Constructor/Methods
JTextField(int col)
creates a JTextField object with width col.
JTextField(String text, int col)
creates a JTextField object displaying default
text text in a field with width col.
getText() returns a String containing the text in the
JTextField.
addActionListener(Object)
adds an object that listens for the user to press
the Enter key in this component.
The information typed into a text field is a string, even when numeric
data is entered. Conversly, the setText() method of a JLabel expects a string
even when the data is numeric. Class methods in the Double and Integer
classes can be used to convert data between numeric and String types:
Class Double (java.lang.Double)
Method
parseDouble(String text)
returns the double value in the String text.
toString(double num)
returns the String representation of num.
Class Integer (java.lang.Integer)
Method
parseInteger(String text)
returns the int value in the String text.
toString(int num)
returns the String representation of num.
converting between text and
numeric data
286 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The parseDouble() and parseInteger() methods are used to convert
String data to numeric. The SemesterAvg application, the GIUI shown on
the previous page, uses parseDouble():
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SemesterAvg implements ActionListener {
JFrame frame;
JPanel contentPane;
JLabel prompt1, prompt2, prompt3, average;
JTextField grade1, grade2, grade3;
JButton avgButton;
public SemesterAvg(){
/* Create and set up the frame */
frame = new JFrame("Semester Average");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane with a GridLayout */
contentPane = new JPanel();
contentPane.setLayout(new GridLayout(0, 2, 10, 5));
contentPane.setBorder(BorderFactory.createEmptyBorder
(10, 10, 10, 10));
/* Create and add a prompt and then a text field */
prompt1 = new JLabel("Enter the first grade: ");
contentPane.add(prompt1);
grade1 = new JTextField(10);
contentPane.add(grade1);
/* Create and add a second prompt and
then a text field */
prompt2 = new JLabel("Enter the second grade: ");
contentPane.add(prompt2);
grade2 = new JTextField(10);
contentPane.add(grade2);
/* Create and add a third prompt and then a text field */
prompt3 = new JLabel("Enter the third grade: ");
contentPane.add(prompt3);
grade3 = new JTextField(10);
contentPane.add(grade3);
/* Create and add button that will display the
average of the grades */
avgButton = new JButton("Average");
avgButton.setActionCommand("Average");
avgButton.addActionListener(this);
contentPane.add(avgButton);
/* Create and add a label that will display the
average */
average = new JLabel(" ");
contentPane.add(average);
/* Add content pane to frame */
frame.setContentPane(contentPane);
Chapter 11 GUIs and Event-Driven Programming 287
s
a
m
p
l
e
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
/**
* Handle button click action event
* pre: none
* post: The average of the grades entered has been
* calculated and displayed.
*/
public void actionPerformed(ActionEvent event) {
String eventName = event.getActionCommand();
if (eventName.equals("Average")) {
double avgGrade;
String g1 = grade1.getText();
String g2 = grade2.getText();
String g3 = grade3.getText();
avgGrade = (Double.parseDouble(g1) + Double.parseDouble(g2)
+ Double.parseDouble(g3))/3;
average.setText(Double.toString(avgGrade));
}
}
/**
* Create and show the GUI.
*/
private static void runGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
SemesterAvg myGrades = new SemesterAvg();
}
main() method of SemesterAvg code
In the actionPerformed() method, the strings are read from the text
fields. To calculate the average grade, each string is parsed for a double
value (with parseDouble()). The avgGrade value was then converted to a
String with the Double class method toString().
Review: DivisibleBy3
Create a DivisibleBy3 application that prompts the user for an integer and then displays a message when
Check is clicked indicating whether the number is divisible by 3. The application interface should look similar
to the following after the user has typed a number and clicked Check:
288 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
JComboBox event
Combo Boxes
A combo box offers a user a way to select from a limited set of choices.
Combo boxes can offer choices without taking up much room on the inter-
face. The user simply clicks the combo box arrow to display additional
choices. The LatinPlantNames application allows the user to select a plant
name from a combo box:
The swing package includes the JComboBox class for creating combo
boxes:
Class JComboBox (javax.swing.JComboBox)
Methods
JComboBox(Object[] items)
creates a JComboBox object that contains the
items from the items array, which must be an
array of objects.
setSelectedIndex(int index)
makes the item at index index the selected
item.
getSelectedItem()
returns the String corresponding to the selected
JComboBox item.
setEditable(boolean)
allows text to be typed in the combo box when
true is the boolean argument.
addActionListener(Object)
adds an object that listens for the user to select
an item from this components list.
Handling an event from a JComboBox requires two lines of code that
are similar to:
JComboBox comboBox = (JComboBox)event.getSource();
String itemName = (String)comboBox.getSelectedItem();
The first statement determines the source of the action event and then the
second statement determines which item has been selected.
Chapter 11 GUIs and Event-Driven Programming 289
s
a
m
p
l
e
The LatinPlantNames application code includes a JComboBox object:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LatinPlantNames implements ActionListener {
JFrame frame;
JPanel contentPane;
JComboBox plantNames;
JLabel plantListPrompt, latinName;
public LatinPlantNames(){
/* Create and set up the frame */
frame = new JFrame("LatinPlantNames");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane with a BoxLayout and
empty borders */
contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.PAGE _ AXIS));
contentPane.setBorder(BorderFactory.createEmptyBorder
(10, 10, 10, 10));
/* Create a combo box and a descriptive label */
plantListPrompt = new JLabel("Select a plant name: ");
plantListPrompt.setAlignmentX(JLabel.LEFT _ ALIGNMENT);
contentPane.add(plantListPrompt);
String[] names = {"basil", "lavender", "parsley",
"peppermint", "saffron", "sage"};
plantNames = new JComboBox(names);
plantNames.setAlignmentX(JComboBox.LEFT _ ALIGNMENT);
plantNames.setSelectedIndex(0);
plantNames.addActionListener(this);
contentPane.add(plantNames);
/* Create and add a label that will display the
Latin names */
latinName = new JLabel("Ocimum");
latinName.setBorder(BorderFactory.createEmptyBorder
(20, 0, 0, 0));
contentPane.add(latinName);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
290 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
/**
* Handle a selection from the combo box
* pre: none
* post: The Latin name for the selected plant
* has been displayed.
*/
public void actionPerformed(ActionEvent event) {
JComboBox comboBox = (JComboBox)event.getSource();
String plantName = (String)comboBox.getSelectedItem();
if (plantName == "basil") {
latinName.setText("Ocimum");
} else if (plantName == "lavender") {
latinName.setText("Lavandula spica");
} else if (plantName == "parsley") {
latinName.setText("Apium");
} else if (plantName == "perppermint") {
latinName.setText("Mentha piperita");
} else if (plantName == "saffron") {
latinName.setText("Crocus");
} else if (plantName == "sage") {
latinName.setText("Salvia");
}
}
runGUI() and main() method of LatinPlantNames code
The LatinPlantNames application displays the following output after
sage has been selected:
Review: MetricConversion
Create a MetricConversion application that allows the user to select a type of conversion from a combo box
and then the corresponding formula is displayed in a label. To convert from the length measurement inches
to centimeters, the formula is 1 inch = 2.54 centimeters. The formula 1 foot = 0.3048 meters converts the dis-
tance measurement feet to meters. The volume measurement gallon is converted to liters with the fomula
1 gallon = 4.5461 liters. The formula 1 pound = 0.4536 kilograms converts the mass measurement pound to
kilograms. The application interface should look similar to the following after the user has selected feet to
meters:
Chapter 11 GUIs and Event-Driven Programming 291
s
a
m
p
l
e
Changing Colors
Swing components have methods for changing their colors. For example,
the content pane can be green, buttons can be magenta, combo boxes can
display text in pink. When making color choices, keep the end user in
mind because colors can give an application a fun and exciting look or
completely turn users away.
The java.awt package includes the Color class with numerous color
constant members. The following methods, in the Swing component
classes, can be used to change the background and foreground colors of
the components:
setBackground(Color.constant)
sets the background color of a component to
constant from the Color class.
setForeground(Color.constant)
sets the foreground color of a component to
constant from the Color class.
How the color change affects the component varies. For a JLabel, the
foreground color refers to the color of the text. For a JComboBox, the fore-
ground color refers to the color of the text in the list.
The ColorDemo application demonstrates the color possibilities for
components. The application GUI and the code, except for the runGUI()
and main() methods, follow:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ColorDemo implements ActionListener {
JFrame frame;
JPanel contentPane;
JTextField name;
JButton displayMessage;
JLabel textFieldPrompt, hello;
public ColorDemo(){
/* Create and set up the frame */
frame = new JFrame("ColorDemo");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane with a BoxLayout
and empty borders */
contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder
(10, 10, 10, 10));
contentPane.setBackground(Color.white);
contentPane.setLayout(new GridLayout(0, 2, 5, 10));
Color class
292 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
/* Create a text field and a descriptive label */
textFieldPrompt = new JLabel("Type your name: ");
textFieldPrompt.setForeground(Color.red);
contentPane.add(textFieldPrompt);
name = new JTextField(10);
name.setBackground(Color.pink);
name.setForeground(Color.darkGray);
contentPane.add(name);
/* Create a Display Message button */
displayMessage = new JButton("Display Message");
displayMessage.setBackground(Color.yellow);
displayMessage.setForeground(Color.blue);
displayMessage.addActionListener(this);
contentPane.add(displayMessage);
/* Create a label that will display a message */
hello = new JLabel(" ");
hello.setForeground(Color.green);
contentPane.add(hello);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
/**
* Handle a the button click
* pre: none
* post: A message has been displayed.
*/
public void actionPerformed(ActionEvent event) {
String text = name.getText();
hello.setText("Hello " + text);
}
runGUI() and main() method of ColorDemo code
Adding Images
Images can make an application more informative, easier to to use, and
fun. Labels and buttons are often used to display an image, but many
Swing components support images. Images that are GIF and JPG format
work best. Unless a different path is specified in the application code, the
image files must be in the same location as the compiled code.
The JLabel class includes a constructor and a method for displaying
images in a label:
Class JLabel (javax.swing.JLabel)
Constructor/Method
JLabel(ImageIcon pic)
creates a JLabel object containing pic.
setIcon(ImageIcon pic)
sets the JLabel to contain pic.
GIF, JPG
Chapter 11 GUIs and Event-Driven Programming 293
s
a
m
p
l
e
The JButton class includes a constructor and a method for displaying
images in a button:
Class JButton (javax.swing.JButton)
Constructor/Method
JButton(String str, ImageIcon pic)
creates a JButton object containing the text str
and the image pic.
JButton(ImageIcon pic)
creates a JButton object containing the image
pic.
setIcon(ImageIcon pic)
sets the JButton to contain pic.
The Roll application displays a die face. The user can click Roll Die to
roll the die and display the outcome of the roll. The application GUI and
the code, except for the runGUI() and main() methods, follow:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class Roll implements ActionListener {
JFrame frame;
JPanel contentPane;
JButton rollDie;
JLabel dieFace;
public Roll(){
/* Create and set up the frame */
frame = new JFrame("Roll");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane with a BoxLayout and
empty borders */
contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder
(10, 10, 10, 10));
contentPane.setBackground(Color.white);
contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.PAGE _ AXIS));
/* Create a label that shows a die face */
dieFace = new JLabel(new ImageIcon("die3.gif"));
dieFace.setAlignmentX(JLabel.CENTER _ ALIGNMENT);
dieFace.setBorder(BorderFactory.createEmptyBorder
(0, 0, 10, 0));
contentPane.add(dieFace);
294 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
/* Create a Roll Die button */
rollDie = new JButton("Roll Die");
rollDie.setAlignmentX(JButton.CENTER _ ALIGNMENT);
rollDie.addActionListener(this);
contentPane.add(rollDie);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
/**
* Handle a button click
* pre: none
* post: A die has been rolled. Matching image shown.
*/
public void actionPerformed(ActionEvent event) {
Random rand = new Random();
int newRoll;
newRoll = rand.nextInt(6) + 1;
if (newRoll == 1) {
dieFace.setIcon(new ImageIcon("die1.gif"));
} else if (newRoll == 2) {
dieFace.setIcon(new ImageIcon("die2.gif"));
} else if (newRoll == 3) {
dieFace.setIcon(new ImageIcon("die3.gif"));
} else if (newRoll == 4) {
dieFace.setIcon(new ImageIcon("die4.gif"));
} else if (newRoll == 5) {
dieFace.setIcon(new ImageIcon("die5.gif"));
} else if (newRoll== 6) {
dieFace.setIcon(new ImageIcon("die6.gif"));
}
}
An image must be an object of the ImageIcon class for use in a Swing
GUI. The ImageIcon class, from the java.swing package, has a constructor
that accepts a file name as an argument and then converts that file to an
ImageIcon object.
Review: Roll
Modify the Roll application to roll two dice. Include an image for each die. Change the colors of the com-
ponents to be more exciting, while still allowing the user to easily read the text on the button and to see the
die images. The die images are name die1.tif, die2.tif, die3.tif, die5.tif, and die6.tif and are supplied as data
files for this text.
Chapter 11 GUIs and Event-Driven Programming 295
s
a
m
p
l
e
Using Nested Classes to Handle Events
A GUI can quickly become complex, as a combination of buttons, text
fields, and other components that must handle events are added. When a
variety of components are on a single interface, separate actionPerformed()
methods should handle their events.
Up to this point, an instance of the controlling class (this) implemented
an actionPerformed() method. This single method was used to handle
events for every component on the GUI. This was sufficient for a simple
GUI. However, a GUI with more than one type of component responding
to an event should have multiple listeners. One way to implement multiple
listeners in a single application is to create each listener from a nested
class.
A nested class is a class within a class. A nested class is a member of the
class it is within. As a class member, it has access to all the other members
of the class, including private member variables and methods. A class
that contains a class member is called an outer class. The Semester Stats
application uses two nested classes to respond to events:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SemesterStats {
JFrame frame;
JPanel contentPane;
JLabel prompt1, prompt2, prompt3, stat;
JTextField grade1, grade2, grade3;
JButton avgButton, minButton, maxButton;
public SemesterStats(){
/* Create and set up the frame */
frame = new JFrame("Semester Stats");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create content pane with a GridLayout and empty borders */
contentPane = new JPanel();
contentPane.setLayout(new GridLayout(0, 2, 10, 5));
contentPane.setBorder(BorderFactory.createEmptyBorder
(10, 10, 10, 10));
/* Create and add a prompt and then a text field */
prompt1 = new JLabel("Enter the first grade: ");
contentPane.add(prompt1);
grade1 = new JTextField(10);
contentPane.add(grade1);
/* Create and add a second prompt and then a text field */
prompt2 = new JLabel("Enter the second grade: ");
contentPane.add(prompt2);
grade2 = new JTextField(10);
contentPane.add(grade2);
/* Create and add a third prompt and then a text field */
prompt3 = new JLabel("Enter the third grade: ");
contentPane.add(prompt3);
grade3 = new JTextField(10);
contentPane.add(grade3);
TIP A nested class is also
called an inner class.
outer class
296 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
/* Create and add button that will display the average grade */
avgButton = new JButton("Average");
avgButton.addActionListener(new AvgListener());
contentPane.add(avgButton);
/* Create and add button that will display the min grade */
minButton = new JButton("Min");
minButton.setActionCommand("Min");
minButton.addActionListener(new MinMaxListener());
contentPane.add(minButton);
/* Create and add button that will display the max grade */
maxButton = new JButton("Max");
maxButton.setActionCommand("Max");
maxButton.addActionListener(new MinMaxListener());
contentPane.add(maxButton);
/* Create and add a label that will display stats */
stat = new JLabel(" ");
stat.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
contentPane.add(stat);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
class AvgListener implements ActionListener {
/**
* Handle Average button click event
* pre: none
* post: The grade average has been calculated and displayed.
*/
public void actionPerformed(ActionEvent event) {
double avgGrade;
String g1 = grade1.getText();
String g2 = grade2.getText();
String g3 = grade3.getText();
avgGrade = (Double.parseDouble(g1) + Double.parseDouble(g2) +
Double.parseDouble(g3))/3;
stat.setText(Double.toString(avgGrade));
}
}
Chapter 11 GUIs and Event-Driven Programming 297
s
a
m
p
l
e
class MinMaxListener implements ActionListener {
/**
* Handles the Min and Max button click events
* pre: none
* post: The minimum or maximum grade has been
* determined and displayed.
*/
public void actionPerformed(ActionEvent event) {
String eventName = event.getActionCommand();
double minGrade = 999;
double maxGrade = 0;
double[] grades = new double[3];
grades[0] = Double.parseDouble(grade1.getText());
grades[1] = Double.parseDouble(grade2.getText());
grades[2] = Double.parseDouble(grade3.getText());
if (eventName.equals("Min")) {
for (int i = 0; i < 3; i++) {
if (minGrade > grades[i]) {
minGrade = grades[i];
}
}
stat.setText(Double.toString(minGrade));
} else if (eventName.equals("Max")) {
for (int i = 0; i < 3; i++) {
if (maxGrade < grades[i]) {
maxGrade = grades[i];
}
}
stat.setText(Double.toString(maxGrade));
}
}
}
/**
* Create and show the GUI.
*/
private static void runGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
SemesterStats myGrades = new SemesterStats();
}
public static void main(String[] args) {
/* Methods that create and show a GUI should be
run from an event-dispatching thread */
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
runGUI();
}
});
}
}
One class (AvgListener) was used to implement a listener for the Average
button and a second class (MinMaxListener) implements a listener for
the Min and Max buttons. These buttons were combined into one listener
because their algorithms closely match.
298 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The SemesterStats application displays output similar to:
Chapter 11 Case Study
In this case study, a Swing GUI will be created for an application that
plays a carnival game called Break-A-Plate. The Break-A-Plate game allows
a player to try to break all three plates. If all three plates are broken, a first
prize is awarded, otherwise, a consolation prize is awarded.
BreakAPlate Specification
The BreakAPlate application displays three unbroken plates at the start.
Clicking Play plays the game, displays broken plates, and displays the prize
won. If all three plates are broken, a tiger plush first prize is awarded. If
less than three plates are broken, a sticker consolation prize is awarded.
At the end of a game the Play button changes to Play Again. Clicking Play
Again displays a set of unbroken plates and the button changes back to Play
allowing the user to play repeatedly. The application ends when the user
closes the window.
The BreakAPlate game uses random numbers to determine if a player
has broken all three plates. When three 1s are generated by the random
number generator then the application displays three broken plates. If zero,
one, or two ones are generated, then the application displays two broken
plates indicating a loss.
The BreakAPlate interface should be a GUI that includes a label for dis-
playing the image of the plates, a button for allowing the user to play or
play again, and a label for displaying the the prize won. The BreakAPlate
GUI should look similar to the following before a game is played, after
a losing game has been played, and after a winning game has been
played:
Chapter 11 GUIs and Event-Driven Programming 299
s
a
m
p
l
e
The BreakAPlate algorithm:
1. When a game is played, generate three random numbers between
0 and 1.
2. If three ones are generated, display three broken plates and the
names of the first prize. Otherwise, display two broken plates and
the name of the consolation prize.
BreakAPlate Code Design
The BreakAPlate application simulates a game booth at a carnival. The
game can therefore be modeled with a GameBooth object. The GameBooth
class was created in Chapter 8 and contains the following methods:
Class GameBooth (Lawrenceville Press)
Constructor/Methods
GameBooth(int cost, String p1, String p2)
creates a GameBooth object that charges cost
amount to play, awards a first prize p1, and a
consolation prize p2. If there is no charge for
the game, or the charge is not a consideration,
then 0 should be the argument for cost.
start() simulates a a game that allows the player three
plays. If the player succeeds all three times,
then the name of the first prize is retuned.
Otherwise, the name of the consolation prize
is returned.
getCost() returns the cost of the game.
TIP Refer to Chapter 8 for the
GameBooth code.
300 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
The cost of the game is not a factor in this application, so 0 will be the
argument for the cost parameter in the constructor, and the getCost()
method will not be needed.
Based on the algorithm and the GameBooth class, the BreakAPlate
actionPerformed() method pseudocode looks similar to:
String eventName = event.getActionCommand();
String prize;
if (Play) {
prize = breakAPlate.start();
if (prize is tiger plush) {
display all broken plates;
} else if (prize is sticker)) {
display two broken plates
}
display prize won
change button to Play Again
} else if (Play Again) {
display unbroken plates
clear prize won text
change button to Play
BreakAPlate Implementation
The BreakAPlate implementation involves creating the BreakAPlate java
file and adding the GameBooth java file to the project.
The BreakAPlate application is implemented below:
/**
* BreakAPlate.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BreakAPlate implements ActionListener {
static final String FIRST _ PRIZE = "tiger plush";
static final String CONSOLATION _ PRIZE = "sticker";
JFrame frame;
JPanel contentPane;
JButton play;
JLabel plates, prizeWon;
GameBooth breakAPlate;
public BreakAPlate(){
/* initialize game booth and player */
breakAPlate = new GameBooth(0, FIRST _ PRIZE, CONSOLATION _ PRIZE);
/* Create and set up the frame */
frame = new JFrame("BreakAPlate");
frame.setDefaultCloseOperation(JFrame.EXIT _ ON _ CLOSE);
/* Create a content pane with a BoxLayout and empty borders */
contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
contentPane.setBackground(Color.white);
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE _ AXIS));
Chapter 11 GUIs and Event-Driven Programming 301
s
a
m
p
l
e
/* Create a label that shows the start of the game */
plates = new JLabel(new ImageIcon("plates.gif"));
plates.setAlignmentX(JLabel.CENTER _ ALIGNMENT);
plates.setBorder(BorderFactory.createEmptyBorder(10, 10, 20, 10));
contentPane.add(plates);
/* Create a Play button */
play = new JButton("Play");
play.setActionCommand("Play");
play.setAlignmentX(JButton.CENTER _ ALIGNMENT);
play.addActionListener(this);
contentPane.add(play);
/* Create a label that will show prizes won */
prizeWon = new JLabel(" ");
prizeWon.setAlignmentX(JLabel.CENTER _ ALIGNMENT);
prizeWon.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
contentPane.add(prizeWon);
/* Add content pane to frame */
frame.setContentPane(contentPane);
/* Size and then display the frame. */
frame.pack();
frame.setVisible(true);
}
/**
* Handle the button click
* pre: none
* post: The appropriate image and message are displayed.
*/
public void actionPerformed(ActionEvent event) {
String eventName = event.getActionCommand();
String prize;
if (eventName == "Play") {
prize = breakAPlate.start();
if (prize.equals(FIRST _ PRIZE)) {
plates.setIcon(new ImageIcon("plates _ all _ broken.gif"));
} else if (prize.equals(CONSOLATION _ PRIZE)) {
plates.setIcon(new ImageIcon("plates _ two _ broken.gif"));
}
prizeWon.setText("You win: " + prize);
play.setText("Play Again");
play.setActionCommand("Play Again");
} else if (eventName == "Play Again") {
plates.setIcon(new ImageIcon("plates.gif"));
prizeWon.setText(" ");
play.setText("Play");
play.setActionCommand("Play");
}
}
302 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
/**
* Create and show the GUI.
*/
private static void runGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
BreakAPlate carnivalGame = new BreakAPlate();
}
public static void main(String[] args) {
/* Methods that create and show a GUI should be
run from an event-dispatching thread */
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
runGUI();
}
});
}
}
Running the BreakAPlate application displays a GUI similar to:
When Play is clicked, the user either wins or loses. The output below
shows a losing game:
Chapter 11 GUIs and Event-Driven Programming 303
s
a
m
p
l
e
The application GUI below shows a winning game:
BreakAPlate Testing and Debugging
The application should be tested by playing several games, making sure
that the correct prize is named and that the buttons and images change
appropriately.
Review: BreakAPlate
Modify the BreakAPlate application to display a picture of the prize won rather than text naming the prize.
The tiger_plush.gif, sticker.gif, and placeholder.gif are supplied as data files for this text. The placeholder.gif
file is a white square that is the same size as the tiger_plush and sticker images. The placeholder.gif file
should be displayed in the label at the start of each game. The modified BreakAPlate interface should look
similar to the following after the user has played a winning game:
304 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
Chapter Summary
This chapter introduced graphical user interfaces that use the Swing
API. The Java swing package contains many component classes, including
JFrames, JPanels, JLabels, JButtons, JComboBoxes, and JTextFields.
Applications with a GUI are event-driven. The GUI must be run from
an event-dispatching thread. A GUI application responds to interactions
from the user called events. An event executes a method called an event
handler. A Swing event handler is also called an action event handler.
A frame is a container for content panels. A commonly used content
panel is the JPanel component. A JPanel can contain other components
such as labels and buttons. A label is a component that does not receive
events. A button is a commonly used component for accepting input from
the user.
Only components with a listener object can execute an event handler.
A listener executes the actionPerformed() event handler, passing it the
an ActionEvent object that contains the action command describing the
event.
The layout of components in a JPanel can be controlled with layout man-
ager and the use of borders and alignment. The FlowLayout, BoxLayout,
and GridLayout are the three managers covered in this chapter. The place-
ment of components within a layout can be controlled further with empty
borders for padding and using alignment.
The text field component allows a user to type information into the
interface. The information typed into a text field is a string. The Integer
and Double classes include class methods for converting information to
numeric data. The label component requires a string when setting the
text. The Integer and Double classes also provide the toString() method
for converting numeric data to a String.
Combo boxes allow the user to select from a limited set of choices. A
combo box does not take up much space and displays a list of choices when
its arrow button is clicked.
Most of the components include methods for setting the background
and foreground colors. Color can make an application easier to use and
more interesting, but should be selected with the user in mind.
GIF and JPG images can be included in an application GUI. A label or
a button is commonly used to display an image.
Nested classes are used to implement multiple event handlers. Nested
classes, like any other member of a class, have access to other members of
the class, including private variables and method members. A class that
contain a class member is called an outer class.
Chapter 11 GUIs and Event-Driven Programming 305
s
a
m
p
l
e
Vocabulary
Action command A string describing an event.
Alignment The placement of components within
a layout.
BoxLayout manager A layout manager that places
components one after the other in a column.
Button A GUI component that the user can click.
Combo box A GUI component that offers a user a
way to select from a limited set of choices.
Container A component that holds and displays
all the other components of a GUI.
Content frame A top-level container.
Event A user interaction with an applications
GUI.
Event-driven application An application that
responds to events.
Event handler A method that executes in response
to an event.
FlowLayout manager A layout manager that places
components one next to the other in a row.
Frame A GUI window that contains a border, title,
and maximize, minimize, and close buttons.
GridLayout manager A layout manager that places
components in a grid of rows and columns.
Label A GUI component that displays text or an
image and does not interact with the user.
Layout The arrangement of components.
Layout manager Used to specify the order of com-
ponents on a content pane.
Listener An object that listens for action events.
Nested class A class that is a member of another
class. A class within a class.
Outer class A class that contains a class member.
Text field A GUI component that allows a user to
enter information at run time.
Thread A process that runs sequentially from start
to finish.
306 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
Java
ActionListener The java.awt.event interface that
contains the actionListener() method.
actionPerformed() A method that is implemented
to respond to events. This method is the only method
in the ActionListener interface.
BorderFactory The java.lang class with class meth-
ods for creating a border object.
BoxLayout A javax.swing class for setting the layout
of a content pane.
Color The java.awt class that contains constants
for changing component colors.
Double A java.lang class for converting numbers
between numeric and text data.
GridLayout A java.awt class for setting the layout
of a content pane.
ImageIcon A java.swing class for converting
an image, such as a GIF or JPG, to an ImageIcon
object.
Integer A java.lang class for converting numbers
between numeric and text data.
java.awt The package containing the GridLayout
class and Color class constants.
java.awt.event The package containing the
ActionListener interface.
java.swing The package containing the Swing
API classes.
JButton A java.swing class for creating a button in
a GUI. The class includes methods for adding text
or images to the label.
JComboBox A java.swing class for creating a combo
box in a GUI.
JFrame A java.swing class for creating a window,
also called a frame, in a GUI.
JLabel The java.swing class for creating a label in
a GUI. The class includes methods for adding text
or images to the label.
JPanel The java.swing class for creating a content
panel for a frame. The class includes methods for
adding and removing components.
JTextField The java.swing class for creating a text
field.
FlowLayout A javax.swing class for setting the
layout of a content pane.
Swing API A part of the Java Foundation Classes
that contains numerous components for creating
GUIs.
this The keyword for indicating an object itself.
Chapter 11 GUIs and Event-Driven Programming 307
s
a
m
p
l
e
Critical Thinking
1. Explain the difference between an event-driven
application and a console-based application.
2. Explain how code is executed in an event-driven
application.
3. Can components be added directly to a frame?
Explain.
4. Can a label respond to events? Explain.
5. Why do you think a GUI needs to be run from
an event-dispatching thread?
6. What is the difference between a label and a
button?
7. a) What does this indicate when used as the
argument for the the addActionListener()
method?
b) What must the object listening for an event
contain?
8. List three ways to control the layout of a content
pane.
9. What type of borders are used to add padding
around components?
10. List three layout managers and explain how
each arranges the components on a content
pane.
11. Which class is used to return an object for the
setBorder() method?
12. Are borders for padding necessary when the
GridLayout manager is used? Explain.
13. What must first be done with numeric data
typed in a text field before it can be used in a
calculation?
14. What is the value of num1 in the last statement
below?
double num1;
Double num2 = new Double(3);
String num3 = "5";
num1 = num2.doubleValue() +
Double.valueOf(num3).doubleValue();
15. An application prompts a user to select a name
from a list of six names. Which is a better
component choice: a text field or a combo box?
Explain.
16. Would white text on a pink background be a
good color combination for a GUI? Why or why
not?
17. What image types are supported in a Swing
GUI?
18. Which components are often used to display an
image?
19. What must an image be converted to in order
to be displayed by a Swing component?
True/False
20. Determine if each of the following are true or
false. If false, explain why.
a) JFrame i s a cl ass i n t he j avax. swi ng
package.
b) A button click is an event handler.
c) Labels can be changed by the user.
d) A JFrame object uses a content pane to hold
GUI components.
e) The index value for the first component on
a content pane is 1.
f) The JLabel class constant LEADING indicates
right alignment.
g) A thread is a sequential process that runs
from start to finish.
h) Swing components use listeners to determine
if an event has occurred.
i) A class that uses a listener must implement
an ActionListener class.
j) An empty border indicates that there is no
space around a component.
k) The FlowLayout manager places components
one after the other in a column, with one
column per line.
l) All components on a GUI must have the
same alignment.
m) The class content PAGE_AXIS specifies that
components should be arranged in a vertical
line.
n) The JLabel setAlignmentX() method is used
to specify the horizontal alignment of the
components within the layout.
308 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
o) Code using the BoxLayout manager requires
an import java.awt.* statement.
p) Information is entered into a text field at run
time.
q) A text field can only accept numeric data.
r) The JLabel foreground color refers to the text
color.
s) A Swing GUI can have only one listener.
t) A nested class has access to the private vari-
able members of the outer class.
Chapter 11 GUIs and Event-Driven Programming 309
s
a
m
p
l
e
Exercises
Exercise 1 LocalBankGUI
Create LocalBankGUI application that implements a GUI for the Local Bank case study in Chapter 9.
Exercise 2 TicTacToeGUI
Create a TicTacToeGUI application that allows two players to play a computerized tic-tac-toe game.
Refer to the TicTacToe application presented in Chapter 9. The TTT class code will need to be modified
for the GUI version of the application. Use a button for each box in the tic-tac-toe board.
Exercise 3 PhotoAlbum
Create a PhotoAlbum application that displays a new picture each time Next is clicked. Use the
grayangel.jpg, scorpionfish.jpg, sponges.jpg, and starfish.jpg files supplied as data files for this text.
The application should allow the user to continously cycle through the images.
Exercise 4 Clacker
In the game Clacker, the numbers 1 through 12 are initially displayed. The player throws two dice and
may cover the number representing the total or the two numbers on the dice. For example, for a throw
of 3 and 5, the player may cover the 3 and the 5 or just the 8. Play continues until all the numbers are
covered. The goal is to cover all the numbers in the fewest rolls.
Create a Clacker application that displays 12 buttons numbered 1 through 12. Each of these buttons
can be clicked to cover it. A covered button displays nothing. Another button labeled Roll can be
clicked to roll the dice. Include labels to display the appropriate die images for each roll. Another label
displays the number of rolls taken. A New Game button can be clicked to clear the labels and uncover
the buttons for a new game.
Exercise 5 LifeGUI
Create a LifeGUI application that is based on the Life application created in Chapter 10, Exercise 14.
The 20 x 20 grid should be buttons that initially display all 0s. To select the live cells for the first day,
the user clicks the buttons in the positions of live cells. When clicked, a button changes from display-
ing a 0 to displaying a X. A Next button below the grid can be clicked repeatedly to display the next
generations until the user quits or there are no more live cells.
310 Chapter 11 GUIs and Event-Driven Programming
s
a
m
p
l
e
Chapter 12 Files and Exception Handling 311
s
a
m
p
l
e
Files are used by many applications for storing and retrieving data. In
this chapter, sequential file access, including object serialization will be
discussed. Exception handling will also be explained.
What is a File?
Up to this point, the applications created in this text have stored data
in the computers memory. However, storage in memory is available only
when the computer is on and an application is running. A file is a collec-
tion of related data stored on a persistent medium such as a hard disk or
a CD. Persistent simply means lasting.
Files often store data used by an application. Files are also used to store
the data generated by an application. In either case, a file is separate from
the application accessing it and can be read from and written to by more
than one application. Most applications require access to one or more files
on disk.
The File Classes
The File class, part of the java.io package, is used for creating an object
that represents a file. A File object can be used to create a new file, test
for the existence of a file, and delete a file. Some of the File class methods
include:
Class File (java.io)
Constructor/Methods
File(String f) creates a File object that refers to the file f.
createNewFile()
creates a new file using the file name specified
in the constructor if the file does not already
exist. Returns true if the file is created, false
otherwise. This method throws an IOException
exception if the file cannot be created.
delete() permanently deletes the file represented by the
File object. Returns true if the file is deleted,
false otherwise.
exists() Returns true if the file represented by the File
object exists, false otherwise.
Chapter 12
Files and Exception Handling
persistent
java.io
312 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
The application below checks for the existence of a file:
import java.io.*;
public class TestFiles {
public static void main(String[] args) {
File textFile = new File("c:\\temp\\supplies.txt");
if (textFile.exists()) {
System.out.println("File already exists.");
} else {
System.out.println("File does not exist.");
}
}
}
The name of a file is specified as a String. If a path is included in the
file name, escape sequences (\\) must be used to separate the drive, folder,
and file names.
Review: MyFile part 1 of 2
Create a MyFile application that prompts the user for the name of a file and then displays a message that
indicates whether the files exists or not. Note that if the user types in a full path, any single backslashes (\)
will need to be replaced with an escape sequence(\\) in order to create a new File object.
Handling Exceptions
An exception is an error affecting program execution. If an exception is
not taken care of, or handled, the application abruptly terminates. Although
many types of exceptions may still require program termination, an excep-
tion handler can allow an application to terminate gracefully by providing
the user with an informative error message.
An exception handler is a block of code that performs an action when an
exception occurs. The try-catch-finally statement can be used to write
an exception handler. It takes the form:
try {
<statements>
} catch (exception err _ code) {
<statements>
} additional catch clauses
} finally (exception err _ code) {
<statements>
The try statements are the statements that could possibly generate an
exception. The catch clause waits for the exception matching the exception
parameter and then executes its code. If more than one type of exception is
possible from the statements in the try clause, then a separate catch should
be written for each type of exception. The finally clause is optional and
executes its statements regardless of what happens in the try-catch por-
tion of the error handler.
exception
exception handler
try-catch-finally
Chapter 12 Files and Exception Handling 313
s
a
m
p
l
e
An exception handler is required when calling certain methods.
For example, the createNewFile() method in the File class generates an
IOException exception when the specified file name cannot be used to cre-
ate a file. The createNewFile() method includes code to throw, or generate,
an exception object if it cannot complete its task.
The modified TestFiles application checks for the existence of a file
before creating a new one:
import java.io.*;
public class TestFiles {
public static void main(String[] args) {
File textFile = new File("c:\\supplies.txt");
if (textFile.exists()) {
System.out.println("File already exists.");
} else {
try {
textFile.createNewFile();
System.out.println("New file created.");
} catch (IOException e) {
System.out.println("File could not be created.");
System.err.println("IOException: " + e.getMessage());
}
}
}
}
An exception, such as IOException, is an object of the Throwable class.
Throwable objects have a getMessage() member that returns a String
containing information about the exception. The err stream is used for
displaying error messages on the screen.
Review: MyFile part 2 of 2
Create a MyFile application that creates a file named zzz.txt and then displays a message indicating that the
file has been created. The application should prompt the user to either keep or delete the file. If the file is
deleted, a message should notify the user when the file has been successfully deleted.
The File Streams
A file must be associated with a stream in order to perform operations
such as reading the contents, writing over existing contents, and adding to
the existing contents. A stream processes characters, and in Java, streams
are implemented with classes.
The file stream keeps track of the file position, which is the point where
reading or writing last occurred. File streams are used to perform sequential
file access, with all the reading and writing performed one character after
another or one line after another.
The Exception Stack
When an exception is thrown,
the current block of code is
first checked for an exception
handler. Next, the calling
met hod is checked for a
handler, and so on until the
Java interpreter is reached.
sequential file access
file position
throw
err stream
TIP The Scanner class requires
an input stream.
IOException
314 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
A stream can be thought of as a sequence of characters. For example,
a file containing a list of names and scores may look like the following
when viewed in a word processor:
Drew 84
Tia 92
However, when thinking about file operations, the file should be visual-
ized as a stream of data:
The carriage return character (Cr) followed by a line feed character (Lf) is
called a line terminator. A 1 is the end of file.
The FileReader and BufferedReader
Classes
The FileReader and BufferedReader classes, both from the java.io pack-
age, are used together to read the contents of an existing file. The FileReader
class is used to create an input file stream. Next, the BufferedReader class
is used to read text from the stream. The following is a summary of the
FileReader and BufferedReader classes:
Class FileReader (java.io)
Constructor/Method
FileReader(File fileName)
creates an input file stream for the File object. This
constructor throws a FileNotFoundException
exception if the file does not exist.
close() closes the input file stream. This method throws
an IOException exception if the file cannot be
closed.
Class BufferedReader (java.io)
Constructor/Methods
BufferedReader(Reader stream)
creates a buffered-input stream from stream.
Reader is the FileReader superclass.
read() reads a single character from the input stream.
This method throws an IOException exception
if the stream cannot be read.
readLine() reads a line of text from the input stream. This
method throws an IOException exception if the
stream cannot be read.
close() closes the input file stream. This method throws
an IOException exception if the stream cannot
be closed.
The application on the next page reads an existing file line-by-line to
show the contents of the file:
Reading Characters
The read() method returns an
int, which corresponds to a
Unicode value. In Unicode, a
space corresponds to 32, a tab
to 9, carriage return to 13, and
line feed to 10.
Data Streams
A stream applies to data input/
output in general. For example,
memory, information sent to
a printer, and data sent and
received from an Internet site
can all be streamed.
input file stream
line terminator, end of file
TIP A buffer stores a large
number of characters from
the stream so that more than
one character at a time can be
read, such as in a readLine().
FileNotFoundException
Chapter 12 Files and Exception Handling 315
s
a
m
p
l
e
import java.util.Scanner;
import java.io.*;
public class ReadFile {
public static void main(String[] args) {
File textFile = new File("wonder.txt");
FileReader in;
BufferedReader readFile;
String lineOfText;
try {
in = new FileReader(textFile);
readFile = new BufferedReader(in);
while ((lineOfText = readFile.readLine()) != null ) {
System.out.println(lineOfText);
}
readFile.close();
in.close();
} catch (FileNotFoundException e) {
System.out.println("File does not exist or could
not be found.");
System.err.println("FileNotFoundException: "
+ e.getMessage());
} catch (IOException e) {
System.out.println("Problem reading file.");
System.err.println("IOException: " + e.getMessage());
}
}
The ReadFile application reads and displays the file contents within
a try-catch statement because both the FileReader and BufferedReader
constructors and methods throw exceptions if there is a problem reading
the file. A try can have multiple catch statements. The catch statements are
in the order that they may occur. For example, the FileNotFoundException
is handled first because the FileReader object is created first in the try
statement.
The close() methods are used to close the FileReader and BufferedReader
streams. It is important that the streams be closed in the reverse order that
they were opened.
The ReadFile application displays the following output when run:
Review: Assignment
Create a Assignment application that reads and then displays the contents of a file containing instructions for
this assignment. Use Notepad or some other word processor to create the file. Be sure that the file is saved as
a Text file (TXT). The Assignment application will need to include the correct path to the location of the file.
If a path is not specified, the file must be placed in the same folder as the Assignment executable file.
316 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Processing Numeric Data
A file on disk is a set of characters, even when the file contains numeric
data, such as test scores. An application written to process numeric data
from a file must convert the data after it is read. The Double and Integer
classes include class methods for converting a string to a primitive data
type:
Class Double (java.lang.Double)
Method
parseDouble(String text)
returns the double value in the String text.
Class Integer (java.lang.Integer)
Method
parseInteger(String text)
returns the int value in the String text.
The AvgScore application reads tests scores that are stored one score
per line in a text file and then reports the average:
import java.io.*;
public class AvgScore {
public static void main(String[] args) {
File dataFile = new File("scores.dat");
FileReader in;
BufferedReader readFile;
String score;
double avgScore;
double totalScores = 0;
int numScores = 0;
try {
in = new FileReader(dataFile);
readFile = new BufferedReader(in);
while ((score = readFile.readLine()) != null ) {
numScores += 1;
System.out.println(score);
totalScores += Double.parseDouble(score);
}
avgScore = totalScores / numScores;
System.out.println("Average = " + avgScore);
readFile.close();
in.close();
} catch (FileNotFoundException e) {
System.out.println("File does not exist or could
not be found.");
System.err.println("FileNotFoundException: "
+ e.getMessage());
} catch (IOException e) {
System.out.println("Problem reading file.");
System.err.println("IOException: " + e.getMessage());
}
}
}
DAT Files
Text files that contain numeric
data often have the file name
extension .dat, also referred
to as a DAT file.
Chapter 12 Files and Exception Handling 317
s
a
m
p
l
e
The application produces the output:
Review: Stats part 1 of 2
Create a Stats application that reads names and scores from a data file named test1.dat, supplied with this
text. The file contains a student name on one line followed by the students test score on the next line. The
Stats application should read and display each name and score. After all the scores have been displayed, the
lowest score, highest score, and average score should be displayed.
The FileWriter and BufferedWriter
Classes
The FileWriter and BufferedWriter classes, both from the java.io pack-
age, are used together to write data to a file. The FileWriter class is used
to create an output file stream. A BufferedWriter class object is then used to
send text to the stream. Some of the FileWriter and BufferedWriter classes
methods include:
Class FileWriter (java.io)
Constructor/Method
FileWriter(File fileName, boolean append)
creates an input file stream for the File object. If
append is true, then data written to the file will
be added after existing data, otherwise the file
will be overwritten. This constructor throws
an IOException exception if the file cannot be
created or opened.
close() closes the output file stream. This method
throws an IOException exception if the file
cannot be closed.
When a FileWriter object is created, the file referenced by the File object
is automatically overwritten unless the FileWriter object is set to append. In
either case, if the file does not yet exist, a new one will be created. Caution
must be used so that a file is not inadvertently overwritten.
output file stream
318 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Class BufferedWriter (java.io)
Constructor/Methods
BufferedWriter(Writer stream)
creates a buffered-writer stream from stream.
Writer is the FileWriter superclass.
newLine() writes a newline character to the output stream.
This method throws an IOException exception
if the stream cannot be written to.
write(String str)
writes the string str to the output stream. This
method throws an IOException exception if the
stream cannot be written to.
write(char c) writes the character c to the output stream. This
method throws an IOException exception if the
stream cannot be written to.
close() closes the output file stream. This method
throws an IOException exception if the stream
cannot be closed.
The CreateDataFile application prompts the user for names and scores
and then writes them to a new file:
import java.io.*;
import java.util.Scanner;
public class CreateDataFile {
public static void main(String[] args) {
File dataFile = new File("StuScores.dat");
FileWriter out;
BufferedWriter writeFile;
Scanner input = new Scanner(System.in);
double score;
String name;
try {
out = new FileWriter(dataFile);
writeFile = new BufferedWriter(out);
for (int i = 0; i < 5; i++) {
System.out.print(:Enter student name: ");
name = input.next();
System.out.print("Enter test score: ");
score = input.nextDouble();
writeFile.write(name);
writeFile.newLine();
writeFile.write(String.valueOf(score));
writeFile.newLine();
}
writeFile.close();
out.close();
System.out.println("Data written to file.");
} catch (IOException e) {
System.out.println("Problem writing to file.");
System.err.println("IOException: " + e.getMessage());
}
}
}
Note that the application will overwrite the StuScores.dat file each time
that it is run. The CreateDataFile application displays output similar to
that shown on the next page:
Chapter 12 Files and Exception Handling 319
s
a
m
p
l
e
Review: Stats part 2 of 2
Modify the Stats application to allow the user to enter the names and grades of the students. The user should
be prompted for the name of the file to create and for the number of student grades that will be entered.
After the data has been entered and the written to a file, the file should be read and the lowest, highest, and
average score displayed.
Object Serialization
A file can also be used to store object data. Writing objects to a file is
called object serialization. In this process, class information about an object
is written out to a stream. If a class uses another class, this information is
also written out, and so on. When information about an object is retrieved
from a file, it is called object deserialization.
Object serialization and deserialization is performed with object out-
put and input streams. The FileOutputStream and ObjectOutputStream
classes, both from the java.io package, are used together to write objects
to a file. The FileInputStream and ObjectInputStream classes, also from
the java.io package, are used together to read objects from a file. Some of
the methods from the classes for writing and reading objects include:
Class FileOutputStream (java.io)
Constructor/Method
FileOutputStream(File fileName, boolean append)
creates an output file stream for the File object.
If append is true, then data written to the file
will be added after existing data, otherwise
the file will be overwritten or created if the
file does not exist. This method throws a
FileNotFoundException exception if the file
cannot be opened or created.
close() closes the output file stream. This method
throws an IOException exception if the file
cannot be closed.
320 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
In addition to methods for writing objects to the output stream, the
ObjectOutputStream class also contains method for writing primitive
data types.
Class ObjectOutputStream (java.io)
Constructor/Method
ObjectOutputStream(FileOutputStream stream)
creates an object stream from stream.
writeObject(Object obj)
writes object information to the output stream.
This method throws an IOException exception
if there are problems with the class or if the
stream cannot be written to.
writeInt(int num)
writes an int to the output stream. This method
throws an IOException exception if the stream
cannot be written to.
writeDouble(double num)
writes a double to the output stream. This
method throws an IOException exception if
the stream cannot be written to.
close() closes the output stream. This method throws
an IOException exception if the stream cannot
be closed.
Objects are read from a FileInputStream stream object:
Class FileInputStream (java.io)
Constructor/Method
FileInputStream(File fileName)
creates an input file stream for the File object.
This method throws a FileNotFoundException
exception if the file cannot be read.
close() closes the input file stream. This method throws
an IOException exception if the file cannot be
closed.
The ObjectInputStream class contains method for reading both objects
and primitive data types.
Class ObjectInputStream (java.io)
Constructor/Method
ObjectInputStream(FileInputStream stream)
creates an object stream from stream. This con-
structor throws an IOException exception if the
stream cannot be read.
readObject() reads an object from the input stream. This
method throws exceptions IOException and
ClassNotFoundException if the the stream can-
not be read or a class cannot be deserialized.
readInt() reads an int from the input stream. This method
throws an IOException exception if the file can-
not be read.
Chapter 12 Files and Exception Handling 321
s
a
m
p
l
e
readDouble() reads a double from the input stream. This
method throws an IOException exception if the
file cannot be read.
close() closes the input stream. This method throws
an IOException exception if the file cannot be
closed.
The ObjectWriteRead application demonstrates writing and reading
objects from a file:
import java.io.*;
public class ObjectWriteRead {
public static void main(String[] args) {
File stuFile = new File("students.dat");
try {
/* write objects */
FileOutputStream out = new FileOutputStream(stuFile);
ObjectOutputStream writeStu = new ObjectOutputStream(out);
writeStu.writeObject(new Student("Drew", 87));
writeStu.writeObject(new Student("Tia", 92));
writeStu.close();
System.out.println("Data written to file.");
/* read objects */
FileInputStream in = new FileInputStream(stuFile);
ObjectInputStream readStu = new ObjectInputStream(in);
Student stu1 = (Student)readStu.readObject();
Student stu2 = (Student)readStu.readObject();
readStu.close();
System.out.println(stu1);
System.out.println (stu2);
} catch (FileNotFoundException e) {
System.out.println("File could not be found.");
System.err.println("FileNotFoundException: "
+ e.getMessage());
} catch (IOException e) {
System.out.println("Problem with input/output.");
System.err.println("IOException: " + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("Class could not be used to
cast object.");
System.err.println("ClassNotFoundException: "
+ e.getMessage());
}
}
}
The ObjectWriteRead application writes two Student objects to the
students.dat file. The Student class is shown on the next page:
322 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
import java.io.*;
public class Student implements Serializable {
private String stuName;
private double stuGrade;
/**
* constructor
* pre: none
* post: A Student object has been created.
* Student data has been initialized with parameters.
*/
public Student(String name, double grade) {
stuName = name;
stuGrade = grade;
}
/**
* Creates a string representing the student object
* pre: none
* post: A string representing the student object
* has been returned.
*/
public String toString() {
String stuString;
stuString = stuName + " grade: " + stuGrade;
return(stuString);
}
}
If the objects of a class are to be written to a file, the class must imple-
ment the Serializable interface. This interface is part of the java.io package
and contains no methods to implement. It simply allows information about
an instance of the class to be written out.
Note that reading an object from a file requires casting. The readObject()
method reads Object data from the file. It is up to the programmer to cast
the object to the appropriate type.
The ObjectWriteRead application catches several exceptions. First, a
FileNotFoundException occurs when there is a problem creating a File
object. IOException is a more general exception and occurs for various
input/output problems. If IOException were first in the catch clauses,
the other more specific exceptions would not be caught and the user
would not be able to read their descriptive error messages. Finally, the
ClassNotFoundException occurs if the class for an object written to the
file cannot be found.
Review: Roster
Create a Roster application that prompts the user for the name of the file to store student names and then
prompts the user for the number of students in a class. The application should then prompt the user for
the first and last name of each student and write this data to a file. After all the data is written to a file, the
application display the class roster with one name after the other in a list. Create a StuName class that has
member variables firstName and lastName and a toString() member method.
Serializable interface
Chapter 12 Files and Exception Handling 323
s
a
m
p
l
e
Chapter 12 Case Study
In this case study, a LocalBank2 application will be created. LocalBank2
is the Chapter 10 case study modified to read and write account informa-
tion from a file.
LocalBank2 Specification
The LocalBank2 application has the same specification as LocalBank.
It allows accounts to be opened, modified, and closed. Each account
has a unique account number, which is required for all transactions.
Transactions include deposits and withdrawals. An account balance can
also be checked.
The LocalBank2 interface will not change from LocalBank. It will pro-
vide a menu of options:
The LocalBank2 algorithm will not change from the LocalBank applica-
tion algorithm.
324 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
LocalBank2 Code Design
The LocalBank2 application will be modeled with a Bank object, Account
objects, and Customer objects, just as LocalBank. However, the Bank object
will store and retrieve accounts from a file. To do this, the Bank construc-
tor should create a file stream for the File object specified when the Bank
object is instantiated. The constructor should also load accounts from the
file stream into an ArrayList. An updateAccounts() method will need to
be added to the Bank class so that any account changes can be written
back to the file.
Because account objects will be read from and written to a file, the
Account class and any classes it uses must implement the Serializable
interface. This includes the Customer class.
The LocalBank2 client code must be modified to create a File object that
stores the account information. Before ending the LocalBank application,
the updateAccounts() method is called to write account information back
to the file. The pseudocode for the LocalBank2 client code follows:
File accountsFile = new File("LBAccounts.dat");
Bank easySave = new Bank(accountsFile);
do {
prompt user for transaction type
if (add account) {
easySave.addAccount();
} else if (not Quit) {
prompt user for account ID;
if (deposit) {
prompt user for deposit amount
easySave.transaction(make deposit, acctID, amt);
} else if (withdrawal) {
prompt user for withdrawal amount
easySave.transaction(make withdrawal, acctID, amt);
} else if (check balance) {
easySave.checkBalance(acctID);
} else if (remove account) {
easySave.deleteAccount(acctID);
}
}
} while (not quit);
easySave.updateAccounts(accountsFile);
LocalBank Implementation
The LocaBank2 application is shown below:
/**
* LocalBank2 client code.
*/
import java.io.*;
import java.util.Scanner;
public class LocalBank {
public static void main(String[] args) {
File accountsFile = new File("LBAccounts.dat");
Bank easySave = new Bank(accountsFile);
Chapter 12 Files and Exception Handling 325
s
a
m
p
l
e
Scanner input = new Scanner(System.in);
String action, acctID;
Double amt;
/* display menu of choices */
do {
System.out.println("\nDeposit\\Withdrawal\\Check balance");
System.out.println("Add an account\\Remove an account");
System.out.println("Quit\n");
System.out.print("Enter choice: ");
action = input.next();
if (action.equalsIgnoreCase("A")) {
easySave.addAccount();
} else if (!action.equalsIgnoreCase("Q")) {
System.out.print("Enter account ID: ");
acctID = input.next();
if (action.equalsIgnoreCase("D")) {
System.out.print("Enter deposit amount: ");
amt = input.nextDouble();
easySave.transaction(1, acctID, amt);
} else if (action.equalsIgnoreCase("W")) {
System.out.print("Enter withdrawal amount: ");
amt = input.nextDouble();
easySave.transaction(2, acctID, amt);
} else if (action.equalsIgnoreCase("C")) {
easySave.checkBalance(acctID);
} else if (action.equalsIgnoreCase("R")) {
easySave.deleteAccount(acctID);
}
}
} while (!action.equalsIgnoreCase("Q"));
easySave.updateAccounts(accountsFile); //write accounts to file
}
}
The Bank class is shown below. The accounts are expected to be loaded
from a file. Additionally, the number of accounts is also kept in the file.
This number is the first data item in the file. It is read first and then used
to determine how many accounts to read from the file. Throughout the
class, the number of accounts is updated when a new account is added and
when an account is deleted. When updateAccounts() is called, the number
of accounts is written to the file first, followed by the accounts:
/**
* Bank class.
*/
import java.util.ArrayList;
import java.io.*;
import java.util.Scanner;
public class Bank {
private ArrayList accounts;
private int numAccts;
326 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
/**
* constructor
* pre: none
* post: accounts have been loaded from acctFile.
*/
public Bank(File acctsFile) {
accounts = new ArrayList();
Account acct;
/* Create a new file for accounts if one does not exist */
if (!acctsFile.exists()) {
try {
acctsFile.createNewFile();
System.out.println("There are no existing accounts.");
} catch (IOException e) {
System.out.println("File could not be created.");
System.err.println("IOException: " + e.getMessage());
}
numAccts = 0;
} else { /* load existing accounts */
try {
FileInputStream in = new FileInputStream(acctsFile);
ObjectInputStream readAccts = new ObjectInputStream(in);
numAccts = (int)readAccts.readInt();
if (numAccts == 0) {
System.out.println("There are no existing accounts.");
} else {
for (int i = 0; i < numAccts; i++) {
acct = (Account)readAccts.readObject();
accounts.add(acct);
}
}
readAccts.close();
} catch (FileNotFoundException e) {
System.out.println("File could not be found.");
System.err.println("FileNotFoundException: " + e.getMessage());
} catch (IOException e) {
System.out.println("Problem with input/output.");
System.err.println("IOException: " + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("Class could not be used to cast object.");
System.err.println("ClassNotFoundException: " + e.getMessage());
}
}
}
/**
* Adds a new account to the bank accounts.
* pre: none
* post: An account has been added to the bank's accounts.
*/
public void addAccount() {
Account newAcct;
double bal;
String fName, lName;
Scanner input = new Scanner(System.in);
System.out.print("First name: ");
fName = input.nextLine();
System.out.print("Last name: ");
lName = input.nextLine();
System.out.print("Beginning balance: ");
bal = input.nextDouble();
Chapter 12 Files and Exception Handling 327
s
a
m
p
l
e
newAcct = new Account(bal, fName, lName); //create account object
accounts.add(newAcct); //add account to bank accounts
numAccts += 1; //increment number of accounts
System.out.println("Account created. Account ID is: " + newAcct.getID());
}
/**
* Deletes an existing account.
* pre: none
* post: An existing account has been deleted.
*/
public void deleteAccount(String acctID) {
int acctIndex;
Account acctToMatch;
acctToMatch = new Account(acctID);
acctIndex = accounts.indexOf(acctToMatch); //retrieve location of account
if (acctIndex > -1) {
accounts.remove(acctIndex); //remove account
System.out.println("Account removed.");
numAccts -= 1; //decrement number of accounts
} else {
System.out.println("Account does not exist.");
}
}
The Account class need only be modified to implement the Serializable
class:
/**
* Account class.
*/
import java.io.*;
import java.text.NumberFormat;
public class Account implements Serializable {
rest of Account class (refer to Chapter 10 case study)
The Customer class need only be modified to implement the Serializable
class:
/**
* Customer class.
*/
import java.io.*;
public class Customer implements Serializable {
rest of Customer class (refer to Chapter 10 case study)
328 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Running the LocalBank2 application displays the same output as the
LocalBank application:
LocalBank2 Testing and Debugging
The LocalBank2 application should be tested to be sure that it works
appropriately when no file exists, when a file with no accounts exists, and
when a file with accounts exists.
Review: LocalBank2
Modify the Bank class to keep track of accounts with low balances. A low balance is an account with less
than $20.00. The number of low balance accounts should be stored after the number of accounts, but before
the account objects in the account file. Have the number of low balance accounts displayed when a Bank
object is created and again when the updateAccounts() method is called.
Chapter 12 Files and Exception Handling 329
s
a
m
p
l
e
Chapter Summary
This chapter discussed files and exception handling. A file is a data
stored on a persistent medium such as a hard disk or CD. In Java, a File
object is associated with a file name. A File object can be used to create or
delete a file.
An exception is an error affecting program execution. An exception
handler is a block of code that performs an action when an exception
occurs. This chapter introduced the try-catch-finally statement for writ-
ing exception handlers.
A file must be associated with a stream in order to read and write to the
file. A file stream processes characters and is used to perform sequential
file access. The FileReader, BufferedReader, FileWriter, and BufferWriter
classes are used to read and write to a file.
An application written to process numeric data from a file must convert
the file data from a strings to numerics. The Double and Integer classes
contain methods for converting numeric characters in a string to an int
or a double.
Objects can be written to a file in a process called object serialization.
Reading objects from a file is called object deserialization. Serialization and
deserialization are performed with an object stream. The FileOutputStream,
ObjectOutputStream, FileInputStream, and ObjectInputStream classes are
used to write and read objects to a file. The ObjectOutputStream and
ObjectInputStream classes can also be used to write and read primitve
data to a file.
330 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Vocabulary
ClassNotFoundException An exception thrown
if a stream cannot be read or a class cannot be
deserialized.
End of file A 1 in the file stream.
err stream The stream used for displaying error
messages to the user.
Exception An error affecting program execution.
Exception handler A block of code that performs
an action when an exception occurs.
File A collection of related data stored on a per-
sistent medium.
FileNotFoundException An exception thrown
when a file does not exist.
File position The point at which reading or writing
in the stream last occurred.
Handle Take care of.
Input file stream A file stream for reading a file.
IOException An exception thrown when a file
cannot be created, or when there is a general input/
output problem.
Line terminator A carriage return followed by a
line feed in the file stream.
Object deserialization The process used to read
objects from a file.
Object serialization The process used to write
objects to a file.
Output file stream A file stream for writing to a
file.
Persistent Lasting.
Sequential file access Reading and writing one
character after another.
Stream The construct used for processi ng
characters.
Throw Generate.
Java
BufferedReader A java.io class used for creating
a buffered file stream for reading a file.
BufferedWriter A java.io class used for creating a
buffered file stream for writing to a file.
Double A java.lang class for converting numeric
text in a string to a double.
File The java.io class used for creating an object
that refers to a file.
FileInputStream A java.io class used for creating
an object input stream.
FileOutputStream A java.io class used for creating
an object output stream.
FileReader The java.io class used for creating a file
stream for reading a file.
FileWriter The java.io class used for creating a file
stream for writing to a file.
Integer A java.lang class for converting numeric
text in a string to an int.
try-catch-finally Statement used to write an excep-
tion handler.
ObjectInputStream A java.io class used for creating
an object for reading objects from a file.
ObjectOutputStream A java.io class used for creat-
ing an object for writing objects to a file.
Chapter 12 Files and Exception Handling 331
s
a
m
p
l
e
Critical Thinking
1. Can data in memory be called a file? Explain.
2. Write the import statement required to access
the File Class in an application.
3. Identify the error in the following statement:
File textFile = new File("c:\inventory.txt");
4. a) Which statement is used to write an excep-
tion handler?
b) Write an exception handler to handle an
IOException if a specified file name cannot
be used to create a file. The exception han-
dler should display appropriate messages to
the user.
5. a) What is the name of the stream for display-
ing error messages.
b) Where are these messages displayed?
6. a) What does the file stream keep track of?
b) What characters together make up a line
terminator?
7. What two classes are used together to write data
to a file?
8. Write a statement to convert account balances
that have been read from a text file to a double
value and add them to totalBalance.
9. Explain the difference between object serializa-
tion and object deserialization.
10. What interface must be implemented if objects
of a class are to be written to a file?
11. Describe two situations where an IOException
exception could be thrown, and write an exam-
ple exception handler for each situation to out-
put an appropriate message if the exception
occurs.
True/False
12. Determine if each of the following are true or
false. If false, explain why.
a) An exception always results in program
termination.
b) Sequential file access reads and writes data
one character after another or one line after
another.
c) Z-1 is the end of file.
d) A file on disk is a set of numbers ranging
from 0 to 9.
e) Numeric data in a file must be converted to
a primitive data type before it can be pro-
cessed numerically.
f) A FileNotFoundException exception is
thrown if a file cannot be closed.
g) The output file stream is a file stream for
writing to the screen.
h) Reading an object from a file requires
casting.
332 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Exercises
Exercise 1 WordCount
Create a WordCount application that displays the number of words and the average word length in a
text file named source.txt. Consider a word to be any sequence of letters terminated by nonletters. For
example, forty-nine is two words.
Exercise 2 WordStats
a) Create a WordStats application that lists all the unique words in a file and how many
times they occurred. WordStats should ignore capitalization. The application should
provide a listing similar to:
WORD OCCURENCES
the 57
and 12
zoo 3
b) Modify the WordStats application to list the words in alphabetical order. This can be
done by either using the sorting algorithm presented in Chapter 10, Exercise 11 or by
keeping the words in order as they are read.
Exercise 3 TestProcessor
Test results for a multiple choice test can be stored in a text file as follows:
Line 1: The correct answers, one character per answer
Line 2: Name of the first student (length <= 30 chars)
Line 3: Answers for the student in line 2
The remaining lines: student names and answers on separate lines
For example:
BADED
Smithgall
BADDD
DeSalvo
CAEED
Darji
BADED
Create a TestProcessor application that processes the test results file for any number of students. The
application should provide statistics similar to:
Smithgall 80%
DeSalvo 60%
Darji 100%
Chapter 12 Files and Exception Handling 333
s
a
m
p
l
e
Exercise 4 MadLib
A Mad-Lib story is a story where nouns and verbs in a paragraph are randomly replaced with other
nouns and verbs, usually with humorous results. Create a MadLib application that displays a Mad-Lib
story. The application will require three files:
story.txt which contains a story with # signs as noun placeholders, and % signs as
verb placeholders. For example:
Bugsy Kludge is a # with our company.
His job is to % all of the #s.
verbs.txt which contains verbs, one per line. For example:
run
display
eat
nouns.txt which contains nouns, one per line. For example:
banana
soprano
elephant
vegetable
Application output should display the story with apporpriate replacements made. A possible output
would produce a MadLib similar to:
Bugsy Kludge is a vegetable with our company.
His job is to display all of the elephants.
Exercise 5 MergeFiles
The idea of merging two or more files is an important one in programming. One approach is to merge
the ordered data of two files into a third file, keeping the data in order.
Create a MergeFiles application that merges the integers ordered from low to high in two files into a
third file, keeping the order from low to high. For example, two files of integers could contain:
File 1: 12 23 34 45 56 67 69 123 133
File 2: 4 5 10 20 35 44 100 130 150 160 180
The application should not use an array to temporarily store the numbers, but should merge the two
files by taking one element at a time from each. After MergeFiles has been run, the third file should
contain:
4 5 10 12 20 23 34 35 44 45 56 67 69 100 123 130 133 150 160 180
Exercise 6 MergeLarge
The algorithm used implemented in Exercise 5 is sometimes used as part of a sorting algorithm with
data that is too large to be stored in memory at once. For example, to sort a large file large.dat that is
twice as large as will fit in memory, half can be read into an array, the array sorted, and then written
to a file numbers1.dat. Next, the second half of large.dat can be read into the array, sorted, and then
written to numbers2.dat. Finally, the two files can be merged in order back into large.dat. Create a
MergeLarge application that implements this algorithm. Test the application with a file that contains
30 integers sorted from low to high.
334 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Exercise 7 HTMLViewer
The early success of the Web is largely due to the simplicity of HTML (HyperText Markup Language),
for designing a Web page. HTML documents are text documents containing content and tags that
describe the format of the content. An HTML document could look similar to:
JUNE BUGS<p>June bugs RAM in megabytes of fleshy fruit,<br>downsize fine fat
figs<br>chip away at melon bits.<br>They monitor windows for open screens,<br>seeking
felicity in electricity.<br>Built-in memory warns of websites<br>hiding spiders
with sly designs.<br>Scrolling the scene of leaves and trees,<br>they network the
neighborhood in flashy green jackets,<br>each bug a browser, scanner, looter-
<br>not even knowing the word "computer."<p>by Avis Harley<p><hr>
Tags are enclosed in angle brackets, < >. The tag <br> means to start a new line. The tag <p> means to
start a new paragraph (a blank line). The tag <hr> means to draw a horizontal rule. When these tags
are interpreted, the HTML document above is displayed as:
JUNE BUGS
June bugs RAM in megabytes of fleshy fruit,
downsize fine fat figs
chip away at melon bits.
They monitor windows for open screens,
seeking felicity in electricity.
Built-in memory warns of websites
hiding spiders with sly designs.
Scrolling the scene of leaves and trees,
they network the neighborhood in flashy green jackets,
each bug a browser, scanner, looter-
not even knowing the word "computer."
by Avis Harley
------------------------------------------------
a) HTML documents are interpreted by browser software. Create an HTMLViewer appli-
cation that interprets an HTML file to display the Web content as intended, similar to
the way a browser decides how to display an HTML document.
b) Modify the HTMLViewer application to allow the user to specify the display line width.
For example, a width of 35 should display the HTML document as:
JUNE BUGS
June bugs RAM in megabytes of
fleshy fruit,
downsize fine fat figs
chip away at melon bits.
They monitor windows for open
screens,
seeking felicity in electricity.
Built-in memory warns of websites
hiding spiders with sly designs.
Scrolling the scene of leaves and
trees,
they network the neighborhood in
flashy green jackets,
each bug a browser, scanner,
looter-
not even knowing the word
"computer."
by Avis Harley
-----------------------------------
...
Chapter 12 Files and Exception Handling 335
s
a
m
p
l
e
Exercise 8 CarRecall
Modify the CarRecall application created in Chapter 6, Exercise 4 to load the defective car model
numbers from a file.
Exercise 9 WordGuess
Modify the WordGuess case study from Chapter 6 to use a word from a file as the secret word. The file
should contain a list of words, with one word per line. The WordGuess application should determine
which word to use, by generating a random number that corresponds to one of the words in the file.
Exercise 10 FindAndReplace
Create a FindAndReplace application that prompts the user for a file name, a search word or phrase,
and a replacement word or phrase. After entering the replacement word or phrase, FindAndReplace
finds all occurrences of the search word or phrase in a file and replaces them with the specified replace-
ment word or phrase.
Exercise 11 ApplicationDoc
Create an ApplicationDoc application that prompts the user for the file name of a Java source code file
(the file name extension should be java) and then copies all the documentation comments (/** */) to
a separate file.
Exercise 12 MySavings
Modify the MySavings application from Chapter 8, Exercise 1 to store and load the PiggyBank object
from a file.
Exercise 13 Adder
Modify the Adder application from Chapter 8, Exercise 8 to keep track of player scores in a file. The
application should prompt the player for his or her name and then create a file based on the player
name. For example, if the players name is Jo, then a file named JoScores.txt should be created. The
application should write the players score to their file at the end of the game and then display the
players previous scores.
Exercise 14 CountVowels
Modify the CountVowels application created in Chapter 6, Exercise 20 to count the number of vowels
in a text file. The application should prompt the user for the file name.
336 Chapter 12 Files and Exception Handling
s
a
m
p
l
e
Exercise 15 Coder
Modify the Coder application created in Chapter 10, Exercise 10 to encode the text in one file and write
it to a new file.
Exercise 16 CourseGrades
Modify the CourseGrades application created in Chapter 10, Exercise 12 to write the GradeBook object
to a file.
Exercise 17 Life
Modify the Life application created in Chapter 10, Exercise 14 to retrieve the initial life grid from a
file.
Exercise 18 Inventory
Modify the Inventory application created in Chapter 10, Exercise 16 to write the inventory items to a
file.
Chapter 13 Recursion and Advanced Algorithms 337
s
a
m
p
l
e
Algorithms for searching and sorting data will be covered in this
chapter. Recursion will be used in the implementation of some of these
algorithms.
Selection Sort
Sorting is the process of putting items in a designated order, either from
low to high or high to low. The selection sort algorithm starts by finding
the lowest item in a list and swapping it with the first. Next, the lowest
item among items 2 through the last is found and swapped with item 2,
and then the lowest item among items 3 through the last is swapped with
item 3. This process is continued until the last item is reached, at which
point all the items are sorted.
The selection sort algorithm compares an element to the items in the
array after the element. This algorithm can be implemented with nested
for loops. The outer loop controls which element to compare and the inner
for loop iterates through the array after the element (the subarray). The
selection sort pseudocode for sorting an array of items from low to high
appears like:
for (arrayIndex = 0 to numItems-1)
for (subarrayIndex = arrayIndex to numItems-1)
if (items[subarrayIndex] < items[arrayIndex]) {
swap items[arrayIndex] and items[arrayIndex]
}
}
}
The Sorts class on the next page implements a selectionSort() method:
Chapter 13
Recursion and Advanced Algorithms
338 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
public class Sorts {
/**
* Sorts an array of data from low to high
* pre: none
* post: items has been sorted from low to high
*/
public static void selectionSort(int[] items) {
for (int index=0; index<items.length; index++) {
for (int subIndex=index; subIndex<items.length; subIndex++) {
if (items[subIndex] < items[index]) {
int temp = items[index];
items[index] = items[subIndex];
items[subIndex] = temp;
}
}
}
}
}
The TestSorts application generates an array of integers and then calls
selectionSort() to sort the array elements:
import java.util.Scanner;
import java.util.Random;
public class TestSorts {
public static void displayArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println("\n");
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numItems;
int[] test;
Random rand = new Random();
System.out.print("Enter number of elements: ");
numItems = input.nextInt();
/* populate array with random integers */
test = new int[numItems];
for (int i = 0; i < test.length; i++) {
test[i] = rand.nextInt(100);
}
System.out.println("Unsorted:");
displayArray(test);
Sorts.selectionSort(test);
System.out.println("Sorted:");
displayArray(test);
}
}
Chapter 13 Recursion and Advanced Algorithms 339
s
a
m
p
l
e
The TestSorts application produces output similar to:
Sorting Objects
Relational operators, such as > and <, cannot be used to compare objects.
Objects use methods of their class to determine if one object is greater
than, less than, or equal to another. The equals() method in a class is used
to determine equality. For determining order, the compareTo() method is
used.
Objects that are to be sorted must have a class that implements the
Comparable interface. The String, Double, and Integer clases implement
the Comparable interface. The Circle class in Chapter 9 also implements
the Comparable interface.
An interface cannot be used to instantiate a class. However, an interface
can be used as a data type. An interface data type can reference any class
that implements it. This polymorphic behavior makes it possible to imple-
ment a generic sort that works with any list of objects that implement the
Comparable interface.
The Sorts class has been modified to include an overloaded SelectionSort()
method, which has a Comparable array parameter:
/**
* Sorts an array of objects from low to high
* pre: none
* post: Objects have been sorted from low to high
*/
public static void selectionSort(Comparable[] items) {
for (int index = 0; index < items.length; index++) {
for (int subIndex=index; subIndex<items.length; subIndex++) {
if (items[subIndex].compareTo(items[index]) < 0) {
Comparable temp = items[index];
items[index] = items[subIndex];
items[subIndex] = temp;
}
}
}
}
The TestSorts application, on the next page, has been modified to sort
an array of Circle objects:
polymorphism
Comparable interface
equals(), compareTo()
340 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
import java.util.Scanner;
import java.util.Random;
public class TestSorts {
public static void displayArray(Circle[] array) {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i] + " ");
}
System.out.println("\n");
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numObjects;
Circle[] test;
Random rand = new Random();
System.out.print("Enter number of objects: ");
numObjects = input.nextInt();
input.close();
/* populate array with Circle objects of varying radii */
test = new Circle[numObjects];
for (int i = 0; i < test.length; i++) {
test[i] = new Circle(rand.nextInt(10));
}
System.out.println("Unsorted:");
displayArray(test);
Sorts.selectionSort(test);
System.out.println("Sorted:");
displayArray(test);
}
}
The TestSorts application produces output similar to:
Chapter 13 Recursion and Advanced Algorithms 341
s
a
m
p
l
e
Review: ArrayListSort
Create an ArrayListSort application that implements a selection sort on an ArrayList object. Test the sort with
an ArrayList containing Double objects.
Insertion Sort
More efficient than the selection sort algorithm is the insertion sort
algorithm. An insertion sort starts by sorting the first two items in a list.
This sort is performed by shifting the first item into the second spot if
the second item belongs in the first spot. Next, the third item is properly
inserted within the first three items by again shifting items into their
appropriate position to make room for the moved item. This process is
repeated for the remaining elements.
The insertion sort is illustrated below with an array containing four
elements. Step 1 shows the original list, which contains items 40, 10, 30,
and 20. Step 2 shows that 40 is shifted to make room for the second item,
10. Next, 30 compared to the value in the previous position (40), 40 is
shifted into position 3, 30 is then compared to the value in the previous
position (10), and then 30 is placed at position 2. This process repeats for
the remaining items.
Based on the algorithm, the insertion sort pseudocode for an array of
integers is:
for (index = 1 To array.length - 1) {
temp = array[index]
previousIndex = index - 1
while (array[previousIndex] > temp && previousIndex > 0) {
shift array[previousIndex] up one element
previousIndex = previousIndex - 1
}
if (array[previousIndex] > temp) {
swap the two elements
} else {
insert element at appropriate location
}
}
342 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
The Sorts class has been modified to include an insertionSort()
method:
/**
* Sorts an array of integer from low to high
* pre: none
* post: Integers have been sorted from low to high
*/
public static void insertionSort(int[] items) {
int temp, previousIndex;
for (int index = 1; index < items.length; index++) {
temp = items[index];
previousIndex = index - 1;
while ((items[previousIndex] > temp) && (previousIndex > 0)) {
items[previousIndex + 1] = items[previousIndex];
previousIndex -= 1; //decrease index to compare current
} //item with next previous item
if (items[previousIndex] > temp) {
/* shift item in first element up into next element */
items[previousIndex + 1] = items[previousIndex];
/* place current item at index 0 (first element) */
items[previousIndex] = temp;
} else {
/* place current item at index ahead of previous item */
items[previousIndex + 1] = temp;
}
}
}
The TestSorts application has been modified to use the insertionSort()
method to sort an array of integers:
import java.util.Scanner;
import java.util.Random;
public class TestSorts {
public static void displayArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println("\n");
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numItems;
int[] test;
Random rand = new Random();
System.out.print("Enter number of elements: ");
numItems = input.nextInt();
/* populate array with random integers */
test = new int[numItems];
for (int i = 0; i < test.length; i++) {
test[i] = rand.nextInt(100);
}
System.out.println("Unsorted:");
displayArray(test);
Sorts.insertionSort(test);
Chapter 13 Recursion and Advanced Algorithms 343
s
a
m
p
l
e
System.out.println("Sorted:");
displayArray(test);
}
}
The TestSorts application produces output similar to:
Review: ObjectsInsertionSort
Create an ObjectsInsertionSort application that implements an insertion sort on an array of objects. Test the
sort on an array of String objects.
Recursion
A method can call itself. This process is called recursion and the calls
are referred to as recursive calls. The RecursiveDemo application contains
a method that calls itself:
public class RecursiveDemo {
public static void showRecursion(int num) {
System.out.println("Entering method. num = " + num);
if (num > 1) {
showRecursion(num - 1);
}
System.out.println("Leaving method. num = " + num);
}
public static void main(String[] args) {
showRecursion(2);
}
}
The call showRecursion(2) from the main() method is the initial call. In
the showRecursion() method, a call is made to itself passing num - 1. When
showRecursion is called with num equal to 1, the if is skipped and the
remaining statement in the method is executed. At this point the stack of
calls made before num was 1 are executed in the reverse order they were
made, with each call executing the statement in the method after the
recursive call (after the if).
The RecursiveDemo produces the output shown on the next page:
recursive call
344 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
Recursion is a programming technique that can be used whenever a
problem can be solved by solving one or more smaller versions of the same
problem and combining the results. The recursive calls solve the smaller
problems.
One problem that has a recursive solution is raising a number to a power.
For example, 2
4
can be thought of as:
2
4
= 2 * 2
3
which can be thought of as
2
3
= 2 * 2
2
which can be thought of as
2
2
= 2 * 2
1
which can be thought of as
2
1
= 2 * 2
0
which can be thought of as
1
In each case, the power problem is reduced to a smaller power problem.
A more general solution is:
x
n
= x * x
n1
However, carefully analyzing this solution shows that there is no stopping
point. For example, 2
3
would be 2 * 2
2
, which would return 2 * 2
1
, which
returns 2 * 2
0
, which returns 2 * 2
1
, and so on. This solution would cause
infinite recursion. To prevent this, a recursive solution must have a base
case that requires no recursion. For this solution, when the power is 0, 1
should be returned.
The intPower() method in the Power application implements a recursive
solution for calculating an int raised to an int power to return an int (as
opposed to Math.pow(), which returns a double):
public class Power {
/**
* Returns num to the power power.
* pre: num and power are not 0.
* post: num to the power power has been returned.
*/
public static int intPower(int num, int power) {
int result;
if (power == 0) {
result = 1;
} else {
result = num * intPower(num, power-1);
}
return(result);
}
public static void main(String[] args) {
int x = intPower(2, 5);
System.out.println(x);
}
}
The Power application produces the output:
infinite recursion
base case
Chapter 13 Recursion and Advanced Algorithms 345
s
a
m
p
l
e
Review: RecursiveFactorial
Create a RecursiveFactorial application that returns the factorial of an integer. The factorial of a number is
the product of all positive integers from 1 to the number. For example, 5! = 5*4*3*2*1. Computing 5! could be
thought of as 5*4! or more generally, n*(n1)!. By definition, 0! is equal to 1. Compare your recursive solution
to the nonrecursive solution created in the Factorial Review completed in Chapter 6.
Mergesort
The selection sort is simple, but inefficient, especially for large arrays.
Imagine using the selection sort process by hand for a pile of 1000 index
cards. Searching through the cards for the lowest item would take a long
time, but more importantly, after each search the remaining cards must
be searched again! Each card ends up being examined about 500 times.
The mergesort algorithm takes a divide-and-conquer approach to sort-
ing. Imagine the 1000 cards being divided into two piles of 500. Each pile
could then be sorted (a simpler problem) and the two sorted piles could
be combined (merged) into a single ordered pile. To further simplify the
sorting, each subpile could be divided and sorted, and so on. This algo-
rithm is best implemented recursively.
The mergesort pseudocode is:
if there are items remaining {
mergesort the left half of the items
mergesort the right half of the items
merge the two halves into a completely sorted list
}
The mergesort subtasks are recursive calls to mergeSort() and a call to
merge(). The mergesort() method will need arguments indicating which
portion of the array is to be sorted. Similarly, merge() implements the
merging of two halves and needs arguments indicating which portion of
the array is to be merged.
The mergesort() method is defined as:
/**
* Sorts items[start..end]
* pre: start > 0, end > 0
* post: items[start..end] is sorted low to high
*/
public static void mergesort(int[] items, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
mergesort(items, start, mid);
mergesort(items, mid + 1, end);
merge(items, start, mid, end);
}
}
The stopping condition for the recursive function is determined by
comparing start and end. The middle of the array is calculated using
integer division, which automatically truncates the decimal portion of the
quotient.
TIP Measuring an algorithms
efficiency is discussed later in
this chapter.
346 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
The merge() method uses a temporary array to store items moved from
two sorted portions of the items array. The elements are moved so that the
temporary array is sorted. To illustrate the merge() algorithm, suppose at
entry to merge() the array looks like:
The array is sorted from start to mid and from mid+1 to end. The merge()
method starts by examining the first element of each sorted portion, start
and mid+1, as indicated by pos1 and pos2:
Since items[pos1] < items[pos2], the element items[pos1] is moved to the
new array, and pos1 is incremented:
In this case, items[pos1] > items[pos2], so the the element items[pos2] is
moved to the new array and pos2 incremented:
This process is repeated until all items have been moved. Since it is likely
that one array portion will be exhausted before the other, merge() tests for
this case and just moves items from the remaining list. Finally, merge()
copies the merged items in the temporary array to the original array.
The Sorts class has been modified to include a mergesort() method.
Note that the merge() method is private because it is a helper method:
Chapter 13 Recursion and Advanced Algorithms 347
s
a
m
p
l
e
/**
* Merges two sorted portion of items array
* pre: items[start..mid] is sorted. items[mid+1..end] sorted.
* start <= mid <= end
* post: items[start..end] is sorted.
*/
private static void merge(int[] items, int start,
int mid, int end) {
int[] temp = new int[items.length];
int pos1 = start;
int pos2 = mid + 1;
int spot = start;
while (!(pos1 > mid && pos2 > end)) {
if ((pos1 > mid) ||
((pos2 <= end) && (items[pos2] < items[pos1]))) {
temp[spot] = items[pos2];
pos2 += 1;
} else {
temp[spot] = items[pos1];
pos1 += 1;
}
spot += 1;
}
/* copy values from temp back to items */
for (int i = start; i <= end; i++) {
items[i] = temp[i];
}
}
/**
* Sorts items[start..end]
* pre: start > 0, end > 0
* post: items[start..end] is sorted low to high
*/
public static void mergesort(int[] items, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;
mergesort(items, start, mid);
mergesort(items, mid + 1, end);
merge(items, start, mid, end);
}
}
The if in the merge() method says that if the pos1 (left) subarray is
exhausted, or if the pos2 (right) subarray is not exhausted and the pos2
element is less than the pos1 element, then move an item from the pos2
subarray to the temp array, otherwise move an item from the pos1 subar-
ray. This process continues until both subarrays are exhausted.
348 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
The TestSorts application has been modified to use the mergesort()
method to sort an array of integers:
import java.util.Scanner;
import java.util.Random;
public class TestSorts {
public static void displayArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println("\n");
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numItems;
int[] test;
Random rand = new Random();
System.out.print("Enter number of elements: ");
numItems = input.nextInt();
/* populate array with random integers */
test = new int[numItems];
for (int i = 0; i < test.length; i++) {
test[i] = rand.nextInt(100);
}
System.out.println("Unsorted:");
displayArray(test);
Sorts.mergesort(test, 0, test.length - 1);
System.out.println("Sorted:");
displayArray(test);
}
}
The TestSorts application produces output similar to:
Review: ObjectsMergesort
Create an ObjectsMergesort application that implements a mergesort on an array of objects. Test the sort on
an array of String objects.
Chapter 13 Recursion and Advanced Algorithms 349
s
a
m
p
l
e
Binary Search
Arrays are sorted in order to perform a more efficient search. A binary
search is used with a sorted list of items to quickly find the location of
a value. Like the mergesort algorithm, the binary search algorithm also
takes a divide-and-conquer approach. It works by examining the middle
item of an array sorted from low to high, and determining if this is the
item sought, or if the item sought is above or below this middle item. If
the item sought is below the middle item, then a binary search is applied
to the lower half of the array; if above the middle item, a binary search is
applied to the upper half of the array, and so on.
For example, a binary search for the value 5 in a list of items 1, 2, 3, 4, 5,
6, and 7 could be visualized as:
The binary search algorithm is very efficient. For example, an array of
100 elements checks no more than 8 elements in a search, and in an array
of one million items no more than 20 items are checked. If a list of the
entire worlds population were to be searched using this algorithm, less
than 40 checks are made to find any one person.
The binary search algorithm can be implemented recursively. The
pseudocode for a recursive solution appears like:
if (goal == items[mid]) {
return(mid)
} else if (goal < items[mid]) {
return(binarySearch(lowerhalf)
} else {
return(binarySearch(upperhalf)
}
The Searches class on the next page implements a binary search:
TIP The linear search algorithm
was introduced in Chapter 10.
A linear search, also called a
sequential search, is much less
efficient than a binary search.
However, a linear search does
not require a sorted list.
350 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
public class Searches{
/**
* Searches items array for goal
* pre: items is sorted from low to high
* post: Position of goal has been returned,
* or -1 has been returned if goal not found.
*/
public static int binarySearch(int[] items, int start,
int end, int goal) {
if (start > end) {
return(-1);
} else {
int mid = (start + end) / 2;
if (goal == items[mid]) {
return(mid);
} else if (goal < items[mid]) {
return(binarySearch(items, start, mid-1, goal));
} else {
return(binarySearch(items, mid+1, end, goal));
}
}
}
}
The TestSorts application has been modified to sort an array of integers
and then prompt the user for a number to search for:
import java.util.Scanner;
import java.util.Random;
public class TestSorts {
public static void displayArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println("\n");
}
public static void sortIntArray() {
Scanner input = new Scanner(System.in);
int numItems, searchNum, location;
int[] test;
Random rand = new Random();
System.out.print("Enter number of elements: ");
numItems = input.nextInt();
/* populate and sort array */
test = new int[numItems];
for (int i = 0; i < test.length; i++) {
test[i] = rand.nextInt(100);
}
Sorts.mergesort(test, 0, test.length - 1);
System.out.println("Sorted:");
displayArray(test);
Chapter 13 Recursion and Advanced Algorithms 351
s
a
m
p
l
e
/* search for number in sorted array */
System.out.print("Enter a number to search for: ");
searchNum = input.nextInt();
while (searchNum != -1){
location = Searches.binarySearch(test, 0,
test.length-1, searchNum);
System.out.println("Number at position: " + location);
System.out.print("Enter a number to search for: ");
searchNum = input.nextInt();
}
}
public static void main(String[] args) {
sortIntArray();
}
}
The modified TestSorts application displays output similar to:
Review: SearchLocations
Create a SearchLocations application that displays the positions examined during a binary search. The
application output should look similar to:
352 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
Review: ObjectsBinarySearch
Create an ObjectsBinarySearch application that implements a binary search on an array of objects. Test the
search on an array of String objects.
Review: BinarySearch2
Create a BinarySearch2 application that implements a nonrecursive binary search. The binary search algo-
rithm can be implemented without recursion by doing the following:
Enclose the method body with a do-while loop
Replace the recursive calls with appropriate assignments to the values of start or
end.
Depth-First Searching
Many programs generate and search through a series of possibilities,
such as:
different paths through a maze
different possible ways of making change
different possible plays in a game
different schedules for a student in a school
different pixels reachable from an initial pixel
All these tasks can be solved through the recursive technique called depth-
first searching. The depth-first searching algorithm works by searching from
a given starting position, processing that position, and then (recursively)
searching from all adjacent positions.
Depth-first searching can be illustrated in a DetectColonies application
that allows a researcher to determine the number and size of distinct
colonies of bacteria on a microscope slide. The slide has been converted to
digital format, where a * represents a cell that is part of a colony, and a -
represents the background color of the slide. A slide file has the format:
First line: length of slide
Second line: width of slide
Remaining lines: slide data.
For example, a slide file could look similar to:
7
9
---------
---*--*--
--***-**-
***---*--
**-**----
---****--
---*--*--
Chapter 13 Recursion and Advanced Algorithms 353
s
a
m
p
l
e
Cells are considered to be part of the same colony if they touch hori-
zontally or vertically. The example slide contains three colonies. Counting
rows and columns starting from zero, one colony has a cell at (1, 3) and
contains 9 elements. Another colony has four elements with a cell at (1,
6), and the third has eight elements with a cell at (4, 3). Note that the first
and third colonies are considered separate because they touch across a
diagonal but not horizontally or vertically.
The DetectColonies application analyzes the slide and displays the fol-
lowing output:
A depth-first search is appropriate here because once a colony cell is
detected, all the possible directions for connected cells must be searched.
If a connected cell is a colony cell, then all the possible directions for that
cell must be searched, and so on. The basic idea is that, given a starting
cell at (row, col) in a colony, the total number of connected cells in that
colony can be found as:
1 for the starting cell
+ count of connected cells starting with (row+1, col)
+ count of connected cells starting with (row1, col)
+ count of connected cells starting with (row, col+1)
+ count of connected cells starting with (row, col1)
The latter four lines are recursive calls. To find the starting cells, each cell
in the slide is tested with a nested for loop.
When implementing a depth-first search algorithm, code must be
included to avoid infinite recursion. For example, a starting cell of (1, 3)
generates a recursive call with cell (2, 3), which generates a call with (1, 3)
again, which generates a call with (2, 3), and so on. For this application, a
cell will be changed to the background color once it has been examined.
This makes counting colonies a destructive algorithm.
The DetectColonies application can be modeled with a Slide class. The
constructor will load the slide data into variable member slideData, which
is a two-dimensional array appropriate for modeling the slide. Method
members displaySlide() and displayColonies() will display the slide and
determine the colonies. Member constants COLONY and NON _ COLONY will
represent * and -.
The displayColonies() method checks each cell of the entire slide, and
whenever a colony cell is encountered, displayColonies() determines the
colony size and displays data about the colony. To determine the size,
displayColonies() calls a private member method collectCells(), which
changes a cell to the background once it is counted.
The Slide class is implemented on the next page:
354 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
import java.io.*;
public class Slide {
private char COLONY = '*', NON _ COLONY = '-';
private char[][] slideData;
/**
* constructor
* pre: Slide file contains valid slide data in the format:
* first line: lenght of slide
* second line: width of slide
* remaining lines: slide data
* post: Slide data has been loaded from slide file.
*/
public Slide(String s) {
try {
File slideFile = new File(s);
FileReader in = new FileReader(slideFile);
BufferedReader readSlide = new BufferedReader(in);
int length = Integer.parseInt(readSlide.readLine());
int width = Integer.parseInt(readSlide.readLine());
slideData = new char[length][width];
for (int row = 0; row < length; row++) {
for (int col = 0; col < width; col++) {
slideData[row][col] = (char)readSlide.read();
}
readSlide.readLine(); //read past end-of-line
}
readSlide.close();
in.close();
} catch (FileNotFoundException e) {
System.out.println("File does not exist or could not
be found.");
System.err.println("FileNotFoundException: "
+ e.getMessage());
} catch (IOException e) {
System.out.println("Problem reading file.");
System.err.println("IOException: " + e.getMessage());
}
}
/**
* Determines a colony size
* pre: none
* post: All colony cells adjoining and including
* cell (Row, Col) have been changed to NON _ COLONY,
* and count of these cells is returned.
*/
private int collectCells(int row, int col) {
if ((row < 0) || (row >= slideData.length) ||
(col < 0) || (col >= slideData[0].length)
|| (slideData[row][col] != COLONY)) {
return(0);
} else {
slideData[row][col] = NON _ COLONY;
return(1+
collectCells(row+1, col)+
collectCells(row-1, col)+
collectCells(row, col+1)+
collectCells(row, col-1));
}
}
Chapter 13 Recursion and Advanced Algorithms 355
s
a
m
p
l
e
/**
* Analyzes a slide for colonies and displays colony data
* pre: none
* post: Colony data has been displayed.
*/
public void displayColonies() {
char[][] temp;
int count;
for (int row = 0; row < slideData.length - 1; row++) {
for (int col = 0; col < slideData[0].length; col++) {
if (slideData[row][col] == COLONY) {
count = collectCells(row, col);
System.out.println("Colony at (" + row + "," + col
+ ") with size " + count);
}
}
}
}
/**
* Displays a slide.
* pre: none
* post: Slide data has been displayed.
*/
public void displaySlide() {
for (int row = 0; row < slideData.length; row++) {
for (int col = 0; col < slideData[0].length; col++) {
System.out.print(slideData[row][col]);
}
System.out.println();
}
}
}
The depth-first search algorithm is implemented in the helper method
collectCells(). The first if statement checks to see that the current posi-
tion is on the slide and contains a colony cell. This eliminates the need to
check before each recursive call. As good programming style, it is better
to check data at the start of the recursive function rather than before each
call.
The DetectColonies application is relatively simple:
public class DetectColonies {
public static void main(String[] args) {
Slide culture = new Slide("slide.dat");
culture.displaySlide();
culture.displayColonies();
}
}
356 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
The DetectColonies application displays output similar to:
Review: DetectColonies part 1 of 3
How must the DetectColonies application be modified if the definition of a colony allowed the colony to be
connected across diagonals? What colonies would be reported by DetectColonies for the sample slide?
Review: DetectColonies part 2 of 3
Modify the DetectColonies application to display the slide colonies from largest to smallest.
Review: DetectColonies part 3 of 3
What slide will be output by the second culture.displaySlide() statement if DetectColonies contained the
statements below? Explain.
public static void main(String[] args) {
Slide culture = new Slide("slide.dat");
culture.displaySlide();
culture.displayColonies();
culture.displaySlide();
}
Algorithm Analysis
Algorithm analysis includes measuring how efficiently an algorithm
performs its task. A more efficient algorithm has a shorter running time.
Running time is related to the number of statements executed to implement
an algorithm. It can be estimated by calculating statement executions.
Running time estimations are usually based on a worst-case set of data.
For example, an array that is already sorted or nearly sorted may require
fewer statement executions than an array of data that is in reverse sorted
order. Since the original state of the data is usually unknown, the worst
case should be assumed.
As a first analysis, consider the selection sort algorithm, which uses
nested for loops to sort items. If the sort is thought of in simplified terms,
with each for statement containing a single statement, for an array of n
items, n * n statements are executed. The selection sort is therefore said
to have a running time of n
2
.
TIP Theoretical running times
can be writ ten in Big Oh
notation, which is a theoretical
measure of an algorithms
efficiency.
Chapter 13 Recursion and Advanced Algorithms 357
s
a
m
p
l
e
The insertion sort algorithm seems more efficient because a while loop
is used within a for loop. This could allow for a faster sort in some cases,
but in the worst case, the insertion sort algorithm executes n statements *
n1 statements for a running time of about n
2
.
The mergesort is a more complicated algorithm, but a divide and conquer
approach can be much more efficient than a linear approach. Because this
algorithm divides the array and each subarray in half until the base case
of one element is reached, there are Log
2
n calls to mergesort() and then n
calls to merge. The mergesort algorithm is said to have running time of
n Log
2
n.
The binary search also implements a divide and conquer approach.
However, the elements are already ordered. The algorithm is simply
performing a search. Because this algorithm divides the array and each
subarray in half until the base case of one element is reached, there are
Log
2
n calls to binarySearch(). Therefore, the algorithm is said to have a
running time of Log
2
n.
Chapter Summary
Sorting is the process of putting items in a designated order, either from
low to high or high to low. The selection sort, insertion sort, and mergesort
algorithms were presented in this chapter. The merge sort algorithm takes
a divide-and-conquer approach to sorting. It is implemented recursively
and is much faster than the selection and insertion sorts.
Objects cannot be compared with relational operators. Therefore, lists of
objects are sorted by implementing an algorithm that uses the Comparable
interface. Interfaces can be used as data types, which allows a generic
implementation of an algorithm that sorts objects. Objects that are to be
sorted must have a class that implements the Comparable interface.
A method can call itself in a process called recursion. Recursion is a
programming technique that can be used whenever a problem can be
solved by solving one or more smaller versions of the same problem and
combining the results. To prevent infinite recursion, a base case that
requires no recursion must be part of the recursive solution.
A binary search algorithm can be used to find an element in a sorted
array. Binary search is implemented recursively and is very efficient. The
depth-first searching algorithm can be used to search through a series
of possibilities. When implementing depth-first searching, code must be
included to avoid infinite recursion.
Algorithm analysis includes how efficiently an algorithm performs its
task. A more efficient algorithm has a shorter running time.
358 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
Vocabulary
Binary search A searching algorithm that recursively
checks the middle of a sorted list for the item being
searched for.
Base case The part of a recursive solution that
requires no recursion.
Depth-first search A searching algorithm that
recursively checks a starting position, processes that
position, and then searches adjacent positions.
Infinite recursion A recursive solution which has
no base case.
Mergesort A sorting algorithm that recursively
divides a list into halves, sorting those halves,
and then merging the lists so that the items are in
order.
Insertion sort A sorting algorithm that repeat-
edly inserts an item into the appropriate position
of a subarray until the subarray has no items left
to insert.
Recursion The process in which a method calls
itself. A programming technique that can be used
whenever a problem can be solved by solving one
or more smaller versions of the same problem and
combining the results.
Recursive call A call to a method from within the
same method.
Selection sort A sorting algorithm that repeatedly
selects the lowest item in a subarray of an array and
moves it to the position just before the subarray until
the subarray has no items left to search.
Java
Comparable A java.lang interface that is required
to be implemented by a class if their objects are to
be sorted. Comparable can also be used as a data
type.
Chapter 13 Recursion and Advanced Algorithms 359
s
a
m
p
l
e
Critical Thinking
1. For the list 4, 6, 2, 10, 9, show how the numbers
are ordered after each loop iteration of the
algorithms:
a) selection sort
b) insertion sort
2. What must be done to a list of items in order to
use a binary search to find a specific item?
3. Use the recursive method below to answer the
questions:
public void ct(int n) {
System.out.println("Starting " + n);
if (n > 0) {
ct(n/3);
System.out.println("Middle " + n);
}
}
a) What output is generated when ct(13) is
called?
b) What output is generated when ct(3) is
called?
c) What output is generated when ct(0) is
called?
4. Use the recursive method below to answer the
questions:
public void ct(int n) {
System.out.println(n);
if (n > 0) {
if (n % 2 == 1) {
ct(n/3);
} else {
ct(n/2);
}
}
}
a) What output is generated when ct (13) is
called?
b) What output is generated when ct(14) is
called?
c) What output is generated when ct(15) is
called?
5. Use the recursive method below to answer the
questions:
public void ct(int n) {
if (n > 0) {
ct(n/10);
System.out.println(n % 10);
}
}
a) What output is generated when ct (13) is
called?
b) What output is generated when ct(124) is
called?
c) What output is generated when ct(21785) is
called?
d) What in general does this method do?
6. Use the recursive method below to answer the
questions:
public void whatzItDo() {
Scanner input = new Scanner(System.in);
String letter = input.next();
if (!letter.equals(".")) {
whatzItDo();
System.out.print(letter);
}
}
a) What output is generated when the user
enters T, E, S, T, . ?
b) What in general does this method do?
7. A sorting algorithm is said to be stable if two
items in the original array that have the same
key value (the value to be sorted on) maintain
their relative position in the sorted version. For
example, assume an array with the following
data:
Ann Jon Mel Tom Kim
20 19 18 19 22
When the array is sorted by age, a stable sort
would guarantee that Jon would stay ahead of
Tom in the sorted array, as in:
Kim Ann Jon Tom Mel
22 20 19 19 18
and not:
Kim Ann Tom Jon Mel
22 20 19 19 18
Which of the sorts presented in this chapter
(selection, mergesort) is stable? For each which
is not stable, give an example of data to illustrate
this.
360 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
True/False
8. Determine if each of the following are true or
false. If false, explain why.
a) Sorting always puts items in order from low
to high.
b) One measure of the efficiency of a sorting
algorithm is the speed at which it can com-
plete a sort.
c) The selection sort algorithm is more efficient
than the insertion sort.
d) A method can call itself.
e) The merge sort algorithm is more efficient
than the selection sort algorithm for large
arrays.
f) A binary search is used to sort a list of
items.
g) A binary search starts by examining the last
item in an array.
h) The more statements required to complete a
task, the more efficient the algorithm.
i) An interface can be used as a data type.
j) A recursive solution that has no base case
results in infinite recursion.
k) An insertion sort recursively divides a list
into halves, sorting those halves, and then
merging the lists in order.
Chapter 13 Recursion and Advanced Algorithms 361
s
a
m
p
l
e
Exercises
Exercise 1 Friends
Create a Friends database application that maintains a file of Friend objects that contain names, tele-
phone numbers, and email addresses. The Friends application should load Friend records from a file
and then allow the user to add new friends, delete friends, display a list of all friends by either first
name or last name, and search for a friend. The application should display a menu similar to:
Exercise 2 TernarySearch
Modify the Searches class to include a ternarySearch() method. A ternary search, similar to a binary
search, divides an array into three pieces rather than two. A ternary search finds the points that divide
the array into three roughly equal pieces, and then uses these points to determine where the goal
should be searched for.
Exercise 3 InterpolationSearch
Modify the Searches class to include an interpolationSearch() method. An interpolation search is a
variation of the binary search. The idea is to look in a likely spot, not necessarily the middle of the
array. For example, if the value sought is 967 in an array that holds items ranging from 3 to 1022, it
would be intelligent to look nearly at the end of the array. Mathematically, because 967 is about 95% of
the way from 3 to 1022, the position to start searching at is a position 95% of the way down the array.
For example, if the array holds 500 elements, the first position to examined is 475 (95% of the way from
1 to 500). The search then proceeds to a portion of the array (either 1..474 or 476..500) depending upon
whether 967 is greater or less than the 475th element.
Exercise 4 NumDigits
Create a NumDigits application that includes a recursive method numDigits() that returns the number
of digits in its integer parameter. Numbers 9 through 9 have one digit; numbers 99 to 10 and 10 to
99 have two digits, and so on. (Hint: the number of digits of a number n is one more than the number
of digits in n/10.)
362 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
Exercise 5 DetectColonies2
Create a DetectColonies2 application that is based on DetectColonies presented in this chapter. This
application gives improved colony results because slides are now digitized to report color. For example,
a slide file could look similar to:
6
8
00550000
00050000
00005500
01200000
01111000
00000030
The digits 1 through 9 represent various colors. The digit 0 represents black (background color).
The DetectColonies2 application should display a listing of the size, location, and color value of each
colony on the slide. A colony is defined as a connected (horizontally or vertically) sequence of cells
holding the same color value. For the above slide, the application should report:
Color Size Location
5 3 1, 3
5 2 3, 5
1 5 4, 2
2 1 4, 3
3 1 6, 7
Exercise 6 Knapsack
A well-known problem in computer science is called the knapsack problem. A variation is as follows:
Given a collection of weights of (possibly) different integral values, is it possible to
place some of the weights in a knapsack so as to fill it to some exact total weight?
For example, if the weights are 3, 5, 6, and 9, then it is possible for such totals as 3, 8,
11, 14, 17, etc. to be made exactly, but 2, 4, 22, etc. are not possible.
Create a Knapsack application that solves this problem. The fillKnapsack() method handles the first
weight, and then recursively handles the remaining weights with an isPossible() helper method.
fillKnapsack() and isPossible() have the following declarations:
/* Returns true if there exists a subset of the items in
* weights[start..weights.length] that sum to goal.
* pre: items in weights[start..weights.length] > 0
* post: true has been returned if there exists a subset
* of items in weights[start..weights.length] that sum to goal.
*/
fillKnapsack(int[] weights, int goal, int start)
Chapter 13 Recursion and Advanced Algorithms 363
s
a
m
p
l
e
/* Returns true if there exists a subset of the items in
* weights that sum to goal.
* pre: items in weights > 0
* post: true has been returned if there exists a subset
* of items in weight that sum to goal.
*/
isPossible(int[] weights, int goal)
The fillKnapsack algorithm determines if the goal can be found in all of the items not including the
first, or if it can be found by including the first in the subset. The pseudocode is:
if (simple case) {
handle simple cases
} else {
if (fillKnapsack(weights, goal, start+1)) {
return(true);
} else if (fillKnapsack(weights, goal-weights[start], start+1)) {
return(true);
} else {
return(false);
}
}
Note that the simple cases will need to be determined and handled properly.
Exercise 7 Maze
A maze can be defined in a file using X characters to represent walls, space characters to represent paths,
and a $ character to represent the goal. For example, a file containing a maze could look similar to:
8
10
XXXXXXXXXX
X X
XX XXX XXX
XX X X
XXXX X X X
X X XXX
X XXXX $X
XXXXXXXXXX
The starting point is assumed to be location (1, 1) and the maze is assumed to have a border. Create a
Maze application that displays the sequence of positions in a path from the start to the goal, or indicate
if no path is available. For example, for the maze above, the application should report:
Path: (1,1) (1,2) (1,3) (1,4) (1,5) (1,6)
(2,6) (3,6) (4,6) (5,6) (6,6) (6,7) (6,8)
364 Chapter 13 Recursion and Advanced Algorithms
s
a
m
p
l
e
Exercise 8 MyBoggle
The game of Boggle is played on a square board with random letters. The object is to find words
formed on the board by contiguous sequences of letters. Letters are considered to be touching if they
are horizontally, vertically, or diagonally adjacent. For example, the board:
Q W E R T
A S D F G
Z X C V B
Y U A O P
G H J K L
contains the words WAS, WAXY, JOB, and others, but not the word BOX. Words can contain duplicate
letters, but a single letter on the board may not appear twice in a single word, for example POP is not
contained on this board.
Create a MyBoggle application that displays a board of random letters, and allows the user to enter
words found on the board. The application should report if the word entered by the user is indeed on
the board.
Hint: Search the board for the first letter of the word entered, and then recursively search around the
found letter for the remaining letters of the word.
Chapter 14 Data Structures 365
s
a
m
p
l
e
Data structures are discussed in this chapter. Stacks, queues, and
linked lists are covered.
The Stack Data Structure
A data structure organizes data. The stack data structure can contain
many data items just as an array can. Additionally, it has a set of operations
that can be performed on the data.
A stack structure has a top. For example, the stack shown below holds
three integers. The value 11 is the top item in the stack:
There are two standard operations that can be performed on the items
in a stack, and only the top item of a stack can be processed. The pop
operation removes the top item. For example, when a pop is executed on
the stack above, the top value, 11, is removed:
The next item, 34, is now at the top of the stack, and is the only item that
can be accessed.
Another operation is the push operation, which adds an item to the top
of the stack. For example, if the value 27 is pushed onto the stack, the stack
becomes:
Chapter 14
Data Structures
top
pop
push
366 Chapter 14 Data Structures
s
a
m
p
l
e
Other stack operations include the isEmpty query, which returns true
when there are no items in the stack, and false otherwise. The size opera-
tion determines the number of items in a stack. A stack can be emptied
with the makeEmpty operation.
Since the stack is designed so that the last item pushed on is the first
item to be popped, it is sometimes referred to as a last-in-first-out (LIFO)
data structure. There are a number of applications of stacks, particularly in
writing compiler software. For example, each of the following is generally
performed using a stack:
Matching of braces, { and }. In Java, a close brace, }, always goes
with the last open brace, {.
Matching else with if: An else always goes with the last if.
Matching of parentheses in an expression: A closing parenthesis
always goes with the last open parenthesis.
Recursion: After completion of a recursive call, control returns
to the last call that was executed. In fact, recursion is sometimes
replaced with a stack.
The Stack Class
A data structure has a specific set of operations that can be performed
on the data it stores. Therefore, a class is often used to implement the data
structure.
The StackDemo application uses a stack:
public class StackDemo {
public static void main(String[] args) {
Stack s = new Stack(10);
System.out.println("Adding 10 and 13 to stack.");
s.push(10);
s.push(13);
System.out.println("Top of stack: " + s.top());
System.out.println("Items in stack: " + s.size());
System.out.println("Removing top item.");
s.pop();
System.out.println("Top of stack: " + s.top());
System.out.println("Items in stack: " + s.size());
System.out.println("Adding a new item.");
s.push(40);
System.out.println("Top of stack: " + s.top());
System.out.println("Items in stack: " + s.size());
}
}
LIFO
isEmpty
size
makeEmpty
Chapter 14 Data Structures 367
s
a
m
p
l
e
The StackDemo produces the output:
The Stack class below is a very simple stack implementation that stores
data in an array:
public class Stack {
private int[] data;
private int top;
/**
* constructor
* pre: none
* post: An empty stack that can hold up to maxItems
* has been created.
*/
public Stack(int maxItems) {
data = new int[maxItems];
top = -1; //no items in the array
}
/**
* Returns the top item without removing it from the stack.
* pre: Stack contains at least one item.
* post: The top item has been returned while leaving it
* on the stack.
*/
public int top() {
return(data[top]);
}
/**
* Removes the top item from the stack and returns it.
* pre: Stack contains at least one item.
* post: The top item of the stack has been removed
* and returned.
*/
public int pop() {
top -= 1;
return(data[top + 1]);
}
368 Chapter 14 Data Structures
s
a
m
p
l
e
/**
* Adds an item to the top of the stack if there is room.
* pre: none
* post: A new item has been added to the top of the stack.
*/
public void push(int num) {
if (top < data.length - 1) {
top += 1;
data[top] = num;
}
}
/**
* Determines if there are items on the stack.
* pre: none
* post: true returned if there are items on the stack,
* false returned otherwise.
*/
public boolean isEmpty() {
if (top == -1) {
return(true);
} else {
return(false);
}
}
/**
* Returns the number of items in the stack.
* pre: none
* post: The number of items in the stack is returned.
*/
public int size() {
if (isEmpty()) {
return(0);
} else {
return(top + 1);
}
}
/**
* Empties the stack.
* pre: none
* post: There are no items in the stack.
*/
public void makeEmpty() {
top = -1;
}
}
The Stack class implements a stack for int values. A generic implemen-
tation would use objects. This implementation is completed in the Stack2
review.
Review: Stack2
Create a Stack2 class that implements a stack data structure for data type Object. Since Object is the super-
class of other objects, a Stack2 object can store objects from any class. Write appropriate client code to test
the Stack2 class.
Chapter 14 Data Structures 369
s
a
m
p
l
e
Review: Stack3
The Stack class is limited because the stack size cannot change from its initial size. Create a Stack3 class
that implements a stack data structure using an ArrayList. Write appropriate client code to test the Stack3
class.
The Queue Data Structure
A queue is a data structure similar to a stack in that it holds a number
of data items. However, one end of the queue is referred to as the rear and
the other end the front. For example, the queue shown below holds three
items:
All insertions are made at the rear and all removals are made at the
front.
There are two standard operations that can be performed on a queue.
The dequeue operation removes an item from the front. For example, when
a dequeue is executed on the queue above, the value at the front, 12, is
removed from the queue:
The enqueue operation adds an item to the rear of the queue. For example,
if the value 27 is enqueued, the queue becomes:
Other queue operations include the front operation, which returns the
front item without removing it from the queue. The isEmpty query returns
true when there are no items in the queue, and false otherwise. The size
operation determines the number of items in a queue. A queue can be
emptied with the makeEmpty operation.
A queue is analogous to a line at a ticket counter where first come,
first served, and is sometimes referred to as a first in first out (FIFO) data
structure. There are a number of real-world situations that can be repre-
sented as a queue structure. For example:
rear, front
dequeue
enqueue
FIFO
370 Chapter 14 Data Structures
s
a
m
p
l
e
Lines at a toll booth or bank teller
Waiting lists for tickets on planes
Pages of data queued up for a printer
Performing breadth-first-searching where all items near the start-
ing position are examined before looking at those farther away.
The Queue Class
The QueueDemo application uses a queue:
public class QueueDemo {
public static void main(String[] args) {
Queue q = new Queue(10);
System.out.println("Adding 10 and 13 to queue.");
q.enqueue(10);
q.enqueue(13);
System.out.println("Front of queue: " + q.front());
System.out.println("Items in queue: " + q.size());
System.out.println("Dequeueing front item.");
q.dequeue();
System.out.println("Front of queue: " + q.front());
System.out.println("Items in queue: " + q.size());
System.out.println("Queueing a new item.");
q.enqueue(40);
System.out.println("Front of queue: " + q.front());
System.out.println("Items in queue: " + q.size());
}
}
The QueueDemo produces the output:
The Queue class below is a very simple queue implementation that
stores data in an array:
public class Queue {
private int[] data;
private int front, rear, maxSize;
Chapter 14 Data Structures 371
s
a
m
p
l
e
/**
* constructor
* pre: none
* post: An empty queue that can hold up to maxItems
* has been created.
*/
public Queue(int maxItems) {
data = new int[maxItems];
front = -1; //no items in the array
rear = -1;
maxSize = maxItems;
}
/**
* Returns the front item without removing it from
* the queue.
* pre: Queue contains at least one item.
* post: The front item has been returned while leaving
* it in the queue.
*/
public int front() {
return(data[front]);
}
/**
* Removes the front item from the queue and returns it.
* pre: Queue contains at least one item.
* post: The front item of the queue has been removed
* and returned.
*/
public int dequeue() {
front = (front + 1) % maxSize;
return(data[front - 1]);
}
/**
* Adds an item to the queue if there is room.
* pre: none
* post: A new item has been added to the queue.
*/
public void enqueue(int num) {
if (isEmpty()) { //first item queued
rear = 0;
front = 0;
data[rear] = num;
} else {
rear = (rear + 1) % maxSize;
data[rear] = num;
}
}
372 Chapter 14 Data Structures
s
a
m
p
l
e
/**
* Determines if there are items on the queue.
* pre: none
* post: true returned if there are items on the queue,
* false returned otherwise.
*/
public boolean isEmpty() {
if (front == -1 && rear == -1) {
return(true);
} else {
return(false);
}
}
/**
* Returns the number of items in the queue.
* pre: none
* post: The number of items in the queue is returned.
*/
public int size() {
if (isEmpty()) {
return(0);
} else {
return(rear - front + 1);
}
}
/**
* Empties the queue.
* pre: none
* post: There are no items in the queue.
*/
public void makeEmpty() {
front = -1;
rear = -1;
}
}
Because the queue is limited to the number of items it can store, the
front and rear pointers must cycle through the spots available in the
array. Therefore, the front and rear values are calculated using modular
arithmetic (%).
The Queue class implements a queue for int values. A generic imple-
mentation would use objects. This implementation is left as a review.
Review: Queue2
Create a Queue2 class that implements a queue data structure for data type Object. Since Object is the super-
class of other objects, a Queue2 object can store objects from any class. Write appropriate client code to test
the Object2 class.
Review: Queue3
The Queue class is limited because the queue size cannot change from its initial size. Create a Queue3 class
that implements a queue data structure using an ArrayList. Write appropriate client code to test the class.
Chapter 14 Data Structures 373
s
a
m
p
l
e
The Linked List Data Structure
Another way of storing lists of data in memory requires each item to
store information that indicates where the next item is stored. The addi-
tional information is a reference, or pointer, to a data location. This kind
of list data structure is called a linked list, and can be illustrated like:
The first item in a linked list is called the head. The last item points to
null and is called the tail. Each element of a linked list is called a node.
There are three nodes in the list above.
Because each item in a linked list must contain data and a pointer, an
item is best modeled with a class. Therefore, a linked list is a list of objects.
The objects in a linked list are organized because they point to each other.
There is no need to place them in a structure, such as an array, for orga-
nization. This mean that linked links are not restricted by the size of an
array.
There are two standard operations that can be performed on a linked
list. The addAtFront operation adds a new node to the front of the list. When
a new node is added to the front of a linked list, it is simply designated
the head and its pointer is set to the current head. For example, if Raj was
the head, adding a new item means that the new object is now the head
and its pointer points to the Raj object:
The remove operation removes an item from the linked list. Removing
an item from a linked list means that the pointer of the previous item is
changed to point to the item after the one to be removed. For example,
removing Raj from the list below means that the object is no longer refer-
enced by another object in the list:
Linked lists are useful for maintaining dynamic lists because the num-
ber of items in a linked list can shrink and grow as needed.
TIP Objects stored in memory
are stored in dynamic memory.
Dynamic memory is allocated
from an area called the heap,
which is used during program
execution.
head, tail
node
addAtFront
remove
374 Chapter 14 Data Structures
s
a
m
p
l
e
The LinkedList Class
The LinkedListDemo application uses a linked link:
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addAtFront("Sachar");
list.addAtFront("Osborne");
list.addAtFront("Suess");
System.out.println(list);
list.remove("Suess");
list.remove("Sachar");
list.remove("Osborne");
System.out.println(list);
}
}
The LinkedListDemo produces the output:
The LinkedList class below contains a nested class. A nested class is a
class within a class. A nested class is a member of the class it is within. As
a class member, it has access to all the other members of the class, includ-
ing private member variables and methods. A class that contains a class
member is called an outer class. The Node class is a nested class because
its members should only be accessed by a LinkedList object:
public class LinkedList {
private Node head;
/**
* constructor
* pre: none
* post: A linked list with a null item has been created.
*/
public LinkedList() {
head = null;
}
/**
* Adds a node to the linked list.
* pre: none
* post: The linked list has a new node at the head.
*/
public void addAtFront(String str) {
Node newNode = new Node(str);
newNode.setNext(head);
head = newNode;
}
outer class
nested class
Chapter 14 Data Structures 375
s
a
m
p
l
e
/**
* Deletes a node in the linked list.
* pre: none
* post: The first node containing str has been deleted.
*/
public void remove(String str) {
Node current = head;
Node previous = head;
if (current.getData().equals(str)) {
head = current.getNext();
} else {
while (current.getNext() != null) {
previous = current;
current = current.getNext();
if (current.getData().equals(str)) {
previous.setNext(current.getNext());
}
}
}
}
/**
* Creates a string that lists the nodes of the
* linked list.
* pre: none
* post: The linked list has been written to a string.
*/
public String toString() {
Node current = head;
String listString;
if (current != null) {
listString = current.getData() + "\n";
while (current.getNext() != null) {
current = current.getNext();
listString += current.getData() + "\n";
}
return(listString);
} else {
return("There are no items in list.");
}
}
private class Node {
private String data;
private Node next;
/**
* constructor
* pre: none
* post: A node has been created.
*/
public Node(String newData) {
data = newData;
next = null;
}
TIP Nested classes were also
introduced in Chapter 11.
376 Chapter 14 Data Structures
s
a
m
p
l
e
/**
* The node pointed to by next is returned
* pre: none
* post: A node has been returned.
*/
public Node getNext() {
return(next);
}
/**
* The node pointed to by next is changed to newNode
* pre: none
* post: next points to newNode.
*/
public void setNext(Node newNode) {
next = newNode;
}
/**
* The node pointed to by next is returned
* pre: none
* post: A node has been returned.
*/
public String getData() {
return(data);
}
}
}
Review: LinkedList part 1 of 3
Modify the LinkedList class to include a member function size() that returns the number of items in the
list.
Review: LinkedList part 2 of 3
Modify the LinkedList class to include a member function addAtEnd() that adds a new item to the end of
the linked list.
Review: LinkedList part 3 of 3
Modify the LinkedList class to include a member function makeEmpty() that removes all the items in the
list
Chapter 14 Data Structures 377
s
a
m
p
l
e
Chapter Summary
The stack, queue, and linked list data structures were introduced in this
chapter. Each data structure organizes data and can be used to perform a
set of operations on that data.
The stack data structure is also called a LIFO structure because the
last item in the first item out. A stack has a top. Operations that can be
performed on a stack include pop, push, isEmpty, size, and makeEmpty.
The queue data structure is also called a FIFO structure because the
first item in is the first item out. A queue has a front and rear. Operations
that can be performed on a queue include enqueue, dequeue, isEmpty,
size, and makeEmpty.
The linked list data structure is a list of objects that point to each other.
The linked list does not have the size limitations of a data structure imple-
mented using an array. A linked list has a head and a tail. Each item in a
linked list is called a node. Operations that can be performed on a linked
list include addAtFront and remove.
Vocabulary
addAtFront A linked list operation where an item
is added to the front of the list.
Dequeue A queue operation that removes the item
at the front of the queue.
Enqueue A queue operation that adds an item to
the rear of the queue.
FIFO First In First Out. A queue data structure.
Front The start of a queue.
Head The first node in a linked list.
isEmpty A stack or queue operation that returns
true when there are no items in the data structure
and false otherwise.
LIFO Last In First Out. A stack data structure.
Linked list A data structure that has a head and
tail and contains nodes that point to each other.
Nested class A class that is a member of another
class. A class within a class.
Node A linked list element. A node contains the
item and a pointer to the next node.
Outer class A class that contains a class member.
Pop A stack operation where the top item is
removed.
Push A stack operation where a new item is
added.
Queue A data structure that has a front and rear
and organizes data so that the first item in is the
first item out.
Rear The end of a queue.
Remove A linked list operation where an item is
removed from the list.
Size A stack or queue operation that returns the
number of items in the data structure.
Stack A data structure that has a top and organizes
data so that the last item in is the first item out.
Tail The last node in a linked list. The tail points
to null.
Top The last item pushed onto a stack.
378 Chapter 14 Data Structures
s
a
m
p
l
e
Critical Thinking
1. Explain the similarities between an array and
a stack.
2. Describe how a programmer might use a stack
when writing compiler software.
3. What output is generated by the following state-
ments if s is a Stack object?
Stack s = new Stack(10);
s.push(5);
s.push(8);
int x = s.pop();
s.push(x);
s.push(12);
s.push(13);
int y = s.pop();
System.out.println(x + " " + y);
y = s.pop();
x = s.top();
System.out.println(x + " " + y);
4. Consider the hot plate problem: In a busy res-
taurant, fresh salad plates are brought out and
added to the existing pile of plates. This means
that, even though there may be plates that were
washed long ago, the customer is frequently
stuck with a warm plate for salad. Explain how
this is analogous to a stack.
5. What output is generated by the following state-
ments if q is a Queue object?
Queue q = new Queue(10);
q.enqueue(5);
q.enqueue(8);
int x = q.dequeue();
q.enqueue(x);
q.enqueue(12);
q.enqueue(13);
int y = q.dequeue();
System.out.println(x + " " + y);
y = q.dequeue();
x = q.front();
System.out.println(x + " " + y);
6. Explain the difference between a FIFO and a
LIFO data structure.
7. List two real-world situations that could be rep-
resented as a queue structure other than those
listed in the chapter.
True/False
8. Determine if each of the following are true or
false. If false, explain why.
a) A stack data structure has a front and a
rear.
b) A stack can be emptied.
c) In a stack, top refers to the first item pushed
onto a stack.
d) The isEmpty operation returns an int
value.
e) A queue can hold more than one data item.
f) In a queue, all removals are made at the
rear.
g) The enqueue operation adds an item to the
front of the queue.
h) The first item in a linked list is called the
head.
i) A node refers to an item in a stack.
j) The number of items in a stack or queue can
be determined with the length operation.
k) In a linked list, the tail points to null.
Chapter 14 Data Structures 379
s
a
m
p
l
e
Exercises
Exercise 1 StackList
The Stack class implemented a stack using an array. A stack can also be implemented using a linked
list. Create a StackList class that implements a stack using a linked list that can store Object data. The
StackList class should implement the standard stack operations. Note that the standard linked list opera-
tions will not be implemented when the linked list is implementing a stack. What are the advantages
or disadvantages of using a linked list rather than an array?
Exercise 2 ReverseList
Create a ReverseList application that uses a stack to reverse a set of integers entered by the user. The
user should be prompted to enter up to 10 numbers or to terminate the list of numbers by entering 999.
Application output should look similar to:
Exercise 3 ParenChecker
To analyze an expression with parentheses, the computer must be able to determine which left paren-
thesis any given right parenthesis matches.
a) Create a ParenChecker application that prompts the user to enter an expression with
parentheses, and then displays a list of the positions of pairs of parentheses. The
application should store the positions of the left parentheses on a stack when they are
found. Application output should look similar to:
b) Modify the ParenChecker application to detect the two errors below and display
appropriate error messages:
1. Attempt to pop an empty stack.
2. Stack not empty at the end of the program.
380 Chapter 14 Data Structures
s
a
m
p
l
e
Exercise 4 QueueList
The Queue class implemented a queue using an array. A queue can also be implemented using a linked
list. Create a QueueList class that implements a queue using a linked list that can store Object data.
The QueueList class should implement the standard queue operations. Note that the standard linked
list operations will not be implemented when the linked list is implementing a queue. What are the
advantages or disadvantages of using a linked list rather than an array?
Exercise 5 Stats
a) Create a Stats interface that declares methods sum(), min(), and max(). The member
methods should return an int value that represents the sum of the items in a list, the
minimum value in a list, and the maximum value in a list.
b) Create a LinkedList class that implements the Stats interface and stores int values.
Write client code that tests the modified class.
Exercise 6 DoublyLinkedList
The nodes in a doubly-linked list point to the next and previous nodes, and can be thought of as:
The node of the doubly-linked list may be represented as:
private class Node {
private String data;
private Node next;
private Node prev;
rest of class
The previous field of the head is set to null.
a) What advantages does this structure offer? What disadvantages?
b) Compare the doubly-linked list with the singly linked list implemented in this chapter.
When would you choose to use one rather than the other?
c) Create a DoublyLinkedList class. Include member methods addAtFront(), addAtEnd(),
remove(), and displayList() and displayReverseList().
Appendix A Unicode 381
s
a
m
p
l
e
Appendix A
Unicode
Every letter of an alphabet (Latin, Japanese, Cherokee, and so on) and
symbols of every culture (=, @, , and so on) have been given a repre-
sentation in a digital code called Unicode. Unicode uses a set of sixteen
1s and 0s to form a 16-bit binary code for each symbol. For example, the
uppercase letter V is Unicode 00000000 01010110, which can be thought
of as the base 10 number 86 (8610). Lowercase v has a separate code of
00000000 01110110, or 11810. Below is a table of some Unicode symbols and
their corresponding decimal and binary equivalents.
382 Appendix A Unicode
s
a
m
p
l
e
Index 383
Index
Symbols
! 112
!= 105
63
% 83
%= 86
&& 112
* 78, 81, 83
*= 86
+ 83, 138
toString() 187
++ 135
+= 86
-- 135
. 80, 81
.class extension 62
.java extension 62
/ 83
/** */ 62, 164
/* */ 62
// 62
/= 86
< 105
<!--comment--> 46
<= 105
<a> 48
<applet> 44
<body> 37
<br> 46, 334
<h1> 46
<h2> 46
<h3> 46
<h4> 46
<h5> 46
<h6> 46
<head> 37
<hr> 46, 334
<html> 37
<img> 48
<li> 46
<object> 44
<ol> 47
<p> 46, 334
<script> 38
<table> 48
<title> 37
<ul> 46
= 78, 86
== 105
comparing objects 186
> 105
>= 105
[] 239, 248
\ 63
\ 63
\\ 63, 312
\n 63
\t 63
{ } 61
|| 112
83
= 86
3GL 5
4GL 5
802.11 network 8
A
abs(), Math class 113
abstract class 222
abstract data type 80
abstract keyword 222
abstract method 222
Abstract Windows Toolkit 280
accessibility 44
accessor method 182
access level, method 159
access modifier 159
acos(), Math class 130
ActionListener interface 280
action command 279
ActiveX 44
add(), ArrayList class 252
add(), JPanel class 276
addActionListener(), JButton 278
addActionListener(), JComboBox
288
addActionListener(), JTextField 285
addAtFront, linked list 373
addition 83
address 10
address bus 2
algorithm 66
design 66
stable 359
algorithm analysis 356
algortihm analysis 246
alignment, Swing API 282
ALU 2
Amaya 35
AMD 2
anchor tag 48
And 112
evaluation 113
antivirus software 21
appending data to a file 317
applets 41, 43
adding color 43
drawing shapes 43
parameters 44
placing in an HTML document
44
appletviewer 42
application, terminating gracefully
312
applications software 2
argument 63, 160
object 161
passed by value 161
primitive data type 161
ArithmeticException 89
Arithmetic Logic Unit 2
array 239
algorithm 242
characters 244
data structure 239
dynamic 252
element 239
initializing 240
length 240
offset indexes 243
parameter 241, 248
reference data type 242
traversing 240
two-dimensional 247
ArrayIndexOutOfBoundsException
240, 241
384 Index
ArrayList, data structure analysis
252
ArrayList class 252
array element 239
accessing 240
assigning a new value 240
artificial intelligence 5
ASCII 10
asin(), Math class 130
assembly language 5
assignment 78, 86
array element 240
constant 87
variable 78
atan(), Math class 130
attributes 46
auxiliary storage 12
awt 280
B
backslash character in a string 63
backslash for escape sequence 63
backup copy 21
backup tools 4
bahavior of an object 179
bandwidth 7
base 10 logarithm 128
base class 214
Basic 5
Big Oh notation 246, 252, 356
binary files 11
binary number system 9
binary search 152, 349
binary search algorithm analysis
357
BIOS 2
bit 9
blog 15
Bluetooth 4
boolean 79, 106
Boolean class 253
Boolean expression 105, 131
evaluation 113
Boolean logic 17
border, Swing API 281
boundary value 168
BoxLayout manager, Swing API 282
breadth-first-searching 370
breakpoint 136
break statement 109
broadcast radio 7
buffer 314
BufferedReader(), BufferedReader
class 314
BufferedReader class 314
BufferedWriter(), BufferedWriter
class 318
BufferedWriter class 317, 318
bug 136
built-in data types 79
bus 2, 7
bus topology 7
button, Swing API 278
for displaying an image 292
byte 9, 79
bytecode 62
converting to machine code 62
Byte class 253
C
C 5
C++ 6, 62
cable modem 14
cache 2
calling a method 159
carpal tunnel syndrome 19
carriage return character 314
case clause 109
case sensitivity, identifiers 88
casting, see type casting 85
CD-R 12
CD-RW/DVD drive 1
cellular radio 7
Central Processing Unit 2
chaos theory 154
char 79, 244
array 244
Character class 253
charAt(), String class 244
char array, initializing 245
Childrens Online Privacy
Protection Act of 1998 18
circuit boards 1
citations 18
class 59
abstract 222
base 214
body 180
constructor 182
declaration 180
derived 214
designing 180
extending 213
inner 188, 295
naming 181
nested 188, 295, 374
outer 295, 374
variables 180, 184
wrapper 253
writing 180
class, objects to be written to a file
322
ClassCastException 186
classes using classes 187
ClassNotFoundException 322
class method 159, 184
client/server network 7
client code 180
close() 81
close(), BufferedReader class 314
close(), BufferedWriter class 318
close(), FileInputStream class 320
close(), FileOutputStream class 319
close(), FileReader class 314
close(), FileWriter class 317
close(), ObjectInputStream class
321
close(), ObjectOutputStream class
320
coaxial cable 7
COBOL 5
code convention
variable identier 77
code conventions 65
collection 252
collections framework 252
colors, Swing API 291
combo box, Swing API 288
comments 46, 61, 62
block 62
documentation 62, 164
for debugging 137
inline 108
method 164
multiline 62
postcondition documentation
164
precondition documentation
164
single line 62
Communications Privacy Act of
1986 22
communications satellites 7
Comparable interface 225, 339
compareTo(), Comparable interface
225
compareTo(), Double class 254
compareTo(), Integer class 253
compareTo(), String class 140
compareTo(), when sorting 339
compareToIgnoreCase(), String
class 140
compiler 5, 62
just-in-time 62
method overloading 162
compiling source code 62
compound interest 103
compression program 11
computers
desktop 1
handhelds 5
notebook 4
wearable 5
wrist-top 5
computer vision syndrome 19
concatenation 138
toString() 187
conditional control structure 105,
109
constant 87
constructor 180, 183
subclass 215
writing 183
Index 385
container, Swing 275
content frame, Swing 275
controlling class 61
Swing application 278
control bus 2
conventional modem 14
conversion, numeric 84
cookie 18
copyright 20
copyright infringement 21
cos(), Math class 130
counter 133
counting values 133
CPU 2
crackers 21
createNewFile(), File class 311
cross-platform connectivity 5
D
data
boundary values 168
passing to a method 160
processing 81
processing from a le 316
reading from a le 314
reading objects from a le 319
testing a method 168
writing objects to a le 319
writing to a le 317
data structure
array 239
ArrayList 252
data structures 365
linked list 373
queue 369
stack 365
data structure analysis
ArrayList 252
data type 77
abstract 80
interface 339
primitive 79
debugger 136
debugging 111, 136
commenting out statements 137
debugger 136
variable trace 136
with println() 137
Debug Window 136
decision structure 105, 109
declaration
array 239
class 180, 214
method 159
two-dimensional array 248
variable 77
decrement operator 135
Default package name 61
delete(), File class 311
depth-first searching 352
dequeue, queue 369
derived class 214
desktop computer 1
device driver 4
digital camera 1
digital signature 15
Digital Subscriber Line 14
disk defragmentation 4
disk drive 1
divide-and-conquer 152, 345, 349
division 83
integer 83
modulus 83
real 83
type casting 85
do-while 131
documentation
comments 62
external 62
package 80
postcondition comments 164
precondition comments 164
documentation comments 164
Double 254
double 79
doubleValue(), Double class 254
Double class 285
downloading 17
DSL 14
DVD drive 13
dynamic array 252
dynamic lists 373
dynamic memory 373
E
e, natural logarithm 128
E-FOIA 18
e-mail 15
address 15
attachments 21
composition 16
etiquette 16
protocol 16
EBCDIC 10
ECPA 18
Electronic Communications Privacy
Act of 1986 18, 21
Electronic Freedom of Information
Act of 1996 18
electronic mail 15
element
array 239
ArrayList 252
ArrayList, adding 252
ArrayList, nding 252
ArrayList, removing 252
employee monitoring 19
encapsulation 59, 179, 182
encryption 19
endsWith(), String class 140
end of file 314
enqueue, queue 369
environment 3
distributed 3
multiprocessing 3
multitasking 3
multiuser 3
environmental concerns 19
equals() 186
equals(), String class 140
equals(), use by ArrayList 252
equals() versus == 186
equalsIgnoreCase(), String class
140
equal sign 78
ergonomics 19
error 62, 89
exception handling 312
logic 89
roundoff 106
run time 89, 240
semantic 89
syntax 62, 88, 132
err stream 313
escape sequence 63, 312
Ethernet 7
ethical implications of computer
use 19
ethical responsibilities, IT
professional 22
ethical responsibilities of an IT
professional 22
Euclids Algorithm 153
Eudora 15
event 275
event-driven application 275
event handler 275
exabyte 13
exception 81, 89, 312
array 240
handling 89
exception handler 312
execution
program 62
exists(), File class 311
exp(), Math class 128
expansion boards 1
expectations vii
exponent 10
exponentiation 113
extends keyword 214
extension 11
extranet 13
F
factorial 136
Fair Credit Reporting Act of 1970
20
false 79
fiber optic cable 7
386 Index
file 11, 311
creating 317
HTML 37, 334
processing numeric data 316
reading 314
stream 313
writing to 317
File(), File class 311
FileInputStream(), FileInputStream
class 320
FileInputStream class 319, 320
FileNotFoundException 315, 322
FileOutputStream(),
FileOutputStream class 319
FileOutputStream class 319
FileReader(), FileReader class 314
FileReader class 314
files
organizing 181
FileWriter(), FileWriter class 317
FileWriter class 317
File class 311
file organization 61
file position 313
file size 11
final 87
Financial Privacy Act of 1978 20
Firefox 35
firewall 13
FireWire port 12
flag 134
float 79
floating point 79
floating point numbers 10
comparing 106
Float class 253
flowchart 66
flowchart symbols 67
FlowLayout manager, Swing API
281
folders 11
format() method 64
formatting output 64
Fortran 5
for statement 240
array iteration, traversing 241
nested 248
frame, Swing 275
front, queue 369
functional decomposition 180
Fundamental Theorem of
Arithmetic 150
G
game
Adder 212, 335
BirthdayGame 90
Bowling 211
Break-A-Plate 298
Carnival 191
DiceRolls 242
Dice Roll 210
Game of 21 211
GuessingGame 126, 151, 178
Life 271, 336
Mad-Lib story 333
Mankala 272
Mastermind 268
Maze 363
MyBoggle 364
Nim 210
Penny Pitch 270
Rock Paper Scissors 114, 196
TicTacToe 248
WordGuess 141, 335
generic collection classes 254
get(), ArrayList 252
getActionCommand(), JButton 278
getContentPane(), JFrame 276
getMessage(), Throwable class 313
getSelectedItem(), JComboBox 288
getText(), JTextField 285
GIF 48, 292
gigabytes 10
gigahertz 2
graphical user interface 3, 275
greatest common divisor 153
GridLayout manager, Swing API
282, 284
GUI 3, 275
Gutenburg, Johann 59
Gutenburg Press 59
H
hackers 21
hailstone numbers 154
HAN 6
handheld computers 5
handwriting recognition software
4
hard-coded data 243
hardware 1
has-a relationship 187
head, linked list 373
heading tags 46
heap 373
helper method 182
hexadecimal 9, 50
histogram 268
Home Area Network 6
horizontal rule tag 46
Hotmail 15
HTML 35, 334
alignment 51
attributes 46
background color 50
comments 46
documents 36, 37
document tags 37
elements 36
hyperlinks 47
images 47
lists 46
style sheets 49
tables 47
tags 36, 45
text color 50
validating 37
HTML 4 45
HTTP 16
hub 8
hyperlink 48
hypertext 35
HyperText Markup Language 35
I
identifier 77
choosing 88
identity theft 20
if-else if statement 108
if-else statement 106
nested 107
if statement 105
IllegalArgumentException 161
IMAP 16
immutable 139
import, package 60
import statement 81
increment operator 135
index 138
index, array element 239
indexOf(), ArrayList 252
indexOf(), String class 140
infinite loop 132
infinite recursion 344
information age 19
information hiding 179, 182
infrared signals 7
inherit 186
inheritance 59, 213
initializing an array 240
initializing an object 80
ink jet printer 1
inline comments 108
inner class 188, 295
input, getting from user 81
input, getting from user in a GUI
285
InputMismatchException 81, 89, 95
input devices 1
input file stream 314
input stream 81
input validation loop 149
insertion sort 341
insertion sort algorithm analysis
357
instance 179
instance methods 184
instance variables 184
instantiation 80
instant messaging 15
int 79
Integer 253
Index 387
Integer class 285
integrated circuits 2
Integrated Services Digital Network
14
Intel 2
interface 225
as data type 339
Comparable 339
console 275
graphical 275
implementing 225
implementing multiple 227
text-based 275
interface, as variable type 339
interface, object 181
Internet 13
history of 13
Internet Acceptable Use Policy 19
Internet Explorer 15, 35
Internet filtering software 19
Internet privacy issues 18
Internet services 15
Internet Service Provider 14
interpolation search 361
interpreter 6
Java VM 62
interpreting bytecode 62
intranet 13
intValue(), Integer class 253
IOException 322
IP address 18
is-a relationship 213
ISDN 14
isEmpty, queue 369
isEmpty, stack 366
IT 22
Itanium 2
iteration 131
IT Careers 22
J
Java 6
enabling 41
java.awt 284, 291
java.awt.event 280
java.io 311, 314, 317, 319
java.lang 63, 79, 80, 113, 225, 254
java.lang.Double 254, 285, 316
java.lang.Integer 253, 285, 316
java.lang.Math 113, 128
java.lang.Object 186
java.text 86
java.util 80
java.util.ArrayList 252
java.util.Random 110, 138
java.util.Scanner 81, 110, 138, 140,
244
JavaScript 38, 40
javax.swing 275
javax.swing.Frame 276, 277, 278, 292
javax.swing.JPanel 276
javax.swing.JTextField 285
Java applets 41
adding color 43
drawing shapes 43
parameters 44
placing in an HTML document
44
Java application 61
Java Foundation Classes 275
Java Runtime Environment 80
Java Virtual Machine 41, 62
Jaz drives 12
JButton(), JButton class 278, 293
JButton class 293
JComboBox(), JComboBox 288
JComboBox class 288
JCreator 41
JFrame class 276
JIT 62
JLabel(), JLabel class 277
JLabel class 276
JPanel class 276
JPG 48, 292
JRE 80, 191
JTextField 285
JTextField(), JTextField class 285
just-in-time compiler 62
K
K 11
Kbps 14
keyboard 1, 81
keyword 88
kilobytes 11
knapsack problem 362
L
label, Swing API 276
for displaying an image 292
LAN 6
laser printer 1
lastIndexOf(), String class 140
layout, Swing API 281
layout manager, Swing API 281
leased/dedicated lines 14
length(), String class 138
length, array 240
library 60
Life 271
with GUI 309
Linear Congruential Method 110
linear search 246, 349
linear search, algorithm analysis
246
line feed character 314
line terminator 314
link 48
linked list 373
Linux 2
list, linked 373
listener, Swing API 279
Listserv 16
Local-Area Network 6
local scope 160
log(), Math class 128
log10(), Math class 128
logical topology 8
logic error 89, 132
logistic equation 154
long 79
Long class 253
loop, controlling iterations 134
loop control variable 135
loop structure 131
lowercase, converting strings 138
M
machine code 62
machine language 5
MACS 1
Mac OSX Tiger 275
Mac OS X Tiger 2
magnetic technology 13
mailing list server 16
main() method 61, 62, 157
mainframe 3
main memory 2
Majordomo 16
makeEmpty, queue 369
malicious code 21
MAN 6
mantissa 10
Mastermind 268
Math class 113, 128, 130
maze 363
Mbps 14
median, determining 268
megabytes 10
megahertz 2
member, accessing 80
members, class 180
memory, dynamic 373
memory-resident 4
memory keys 1
mergesort 345
mergesort algorithm analysis 357
message, passing 193
method 157
abstract 222
accessor 182
array parameter 241
body 159
calling 159
class 159, 184
declaration 159, 162
documentation 164
helper 182
instance 184
modier 182
naming 160
overloading 162
overriding 186
parameters 160
388 Index
returning a value 163
testing 167
test data 168
writing 159
methods
behavior of object 179
Metropolitan Area Network 6
microphone 1
Microsoft Internet Explorer 15
Microsoft Windows 275
microwaves 7
MLA 17
MLA Handbook for Writers of
Research Papers, Fourth
Edition 17
mobile computing devices 4
modem 14
modifier method 182
modular 193
modulus division 83
monitor 1
motherboard 1
mouse 1
MP3 players 5
multimedia 36
multiplication 83
multiprocessing 3
multitasking 3
multithreading 3
multiuser OS 3
Mylar 12
N
native format 11
natural logarithm 128
necklace problem 153
nested class 188, 295, 374
nested statements 107
netiquette 9
Netscape 35
networked environment 7
networks 6
benets 6
size classications 6
network architecture 7
network interface card 6
network operating system 7
NET Act 18
new 80, 239, 248
newLine(), BufferedWriter class 318
newline character 63
next(), Scanner class 81
nextBoolean(), Scanner class 81
nextDouble(), Random class 110
nextDouble(), Scanner class 81
nextInt(), Random class 110
nextInt(), Scanner class 81
node 7
node, linked list 373
Not 112
notebook computer 4
No Electronic Theft Act of 1997 20
null 139, 240
NullPointerException 139
number
converting type 84
whole 77
number systems 9
numeric expression 83
O
object 59, 80, 179
argument 161
object, to be written to a file 322
object-oriented development 191
object-oriented programming 6, 59
ObjectInputStream 319
ObjectInputStream(),
ObjectInputStream class 320
ObjectInputStream class 320
ObjectOutputStream 319
ObjectOutputStream(),
ObjectOutputStream class 320
ObjectOutputStream class 320
objects, sorting 339
Object class 185, 213
object deserialization 319
Object parameter 186
object serialization 319
offset array index 243
online profiling 18
OOP 6, 59
Opera 35
operand 83
operating systems 2
operations, order of 84
operator 83
relational 105
operators, built-in 83
operator precedence 84
Opteron 2
optical technology 12
Or 112
evaluation 113
order of operations 113
out 63
outer class 295, 374
Outlook 15
Outlook Express 15
output, formatting 64
output devices 1
output file stream 317
output stream 63
overflow 132
overflow error 10
overloading, methods 162
overriding
methods 214
overriding a method 186
overwriting a file 317
P
pack(), JFrame 276
package 60
documentation 80
naming 61, 81
package statement 61
paradigm
object-oriented 213
parallel processing 3
parameter
array, two-dimensional 248
Object 186
parameters 44
array 241
constructor 183
method 160
pass by value 161
parentheses 84
parseDouble(), Double class 285,
316
parseInteger(), Integer class 285,
316
Pascal 5
passing an array 242
passing data to a method 160
pass by value 161
PC 1
PDAs 5
peer-to-peer network 7
Pentium 2
peripheral devices 1
persistent data 311
persistent media 11
petabyte 13
phishing 22
PI, Math class 113
piracy 21
pixel 281
pixels 42
pixel tags 18
platform 3
platform-dependent languages 62
platform independence 59, 62
PNG 48
polymorphism 59, 217
polymorphism, interfaces 339
pop, stack 365
POP3 16
ports 1
Bluetooth 1
FireWire 1
parallel 1
serial 1
USB 1
post 164
postcondition, method
documentation 164
postfix 135
pow(), Math class 113
pre 164
Index 389
precondition, method
documentation 164
prefix 135
primary memory 2
prime factors 150
prime number 150
primitive data type 79
argument 161
primitve data type
array element 242
print() method 63
printer 1
println()
debugging 137
toString() 187
println() method 63
privacy 20
Privacy Act of 1974 20
privacy policy 18
private keyword 182, 215
procedural abstraction 157
programming language
rst generation 5
second generation 5
program specification 59
modeling 213
program specification, modeling
191
prompt 82
prompt, in a GUI 285
pseudocode 66
pseudorandom 110
public 159
public keyword 159
public static void main(String[]
args) 61
push, stack 365
Q
queue 369
quotation mark 63
in a string 63
quotient 83
R
RAM 2
Random Access Memory 2
Random class 110
random numbers 110
random walk 155
range, determining 268
read(), BufferedReader class 314
readDouble(), ObjectInputStream
class 321
reading numeric and string data 82
reading objects 319
readInt(), ObjectInputStream class
320
readLine(), BufferedReader class
314
readObject(), ObjectInputStream
class 320
Read Only Memory 2
real-time clock 2
real-time OS 3
real numbers 10
rear, queue 369
recursion 343
recursive algorithm, binary search
349
recursive algorithm, depth-first
search 352
recursive algorithm, mergesort 345
recycling 19
reference data type
array 242
interface 339
object 80
object parameters 161
polymorphism 217
String 139
relational operator 105
remove(), ArrayList 252
remove(), JPanel 276
remove, linked list 373
replaceAll(), String class 138
replaceFirst(), String class 138
reserved words 88
return statement 163
reusability 60
code 191
ring topology 8
ROM 2
rounding 84
rounding double to int 85
roundoff error 11, 106
router 8, 14
run-time error 89
array 240
running a program 62
running time 356
S
Safari 35
Safety and Freedom through
Encryption Act of 1999 19
scanner 1
Scanner object, closing 82
scope 135
scope, local in a method 160
scripts 38, 40
SDK 42
search, binary 349
search, depth-first 352
search, interpolation 361
search, linear 349
search, sequential 349
search, ternary 361
searching an array 246
Search class 246
search engines 16
secondary memory 2
seed, for random numbers 111
selection sort 270, 337
selection sort algorithm analysis
356
semantic error 89
semicolon 62
sentinel 134
sequential file access 313
sequential search 349
Serializable interface 322
server 7
setActionCommand(), JButton 278
setBackground(), Swing API 291
setContentPane(), JFrame 276
setDefaultCloseOperation(), JFrame
276
setDefaultLookAndFeelDecorated()
, JFrame 276
setEditable(), JComboBox 288
setForeground(), Swing API 291
setIcon(), JButton class 293
setSelectedIndex(), JComboBox 288
setText(), JLabel 277
setVisible(), JFrame 276
short 79
short-circuit evaluation 113
Short class 253
simple interest 103
sin(), Math class 130
size(), ArrayList 252
size, queue 369
size, stack 366
smartphones 5
social implications of computer
use 19
software development 157, 191
solid state technology 13
sorting, numbers 337
sorting objects 339
sorts 337
sound cards 1
source code 62
spam 16
spec 59
spyware 18
SQL 5
sqrt(), Math class 113
square root 113
SRAM 2
stack 365
startsWith(), String class 140
star topology 8
statement 61
state of an object 179
static 159
static method 184
Static Random Access Memory 2
static variables 184
step-wise refinement 157
Step command 136
storage, file 311
storage devices 12
390 Index
storage media
care of 13
stream 313
input 81
string 63
formatting 64
strings 79
comparing 140
creating 138
joining 138
String class 79, 138
student expectations vii
style sheets 49
class 50
embedded 49
linked 50
rules 50
stylus 4
subclass 214, 217
subclasses 185
subject tree 17
substring(), String class 138
subtraction 83
summing values 133
Suns Java Software Development
Kit 42
superclass 185, 217
Object class 213
supercomputer 3
super keyword 215
Swing API 275
switch statement 109
syntax error 62, 88, 132
System.in 81
System class 63
system reliability 22
system restore 4
T
tablet PC 4
tab character 63
tail, linked list 373
tan(), Math class 130
TCP/IP 14
telecommunications 14
terabyte 13
ternary search 361
text field, GUI 285
this keyword 189, 279
thread 278
Throwable class 313
Tim Berners-Lee 36
toCharArray(), String class 244
toDegrees(), Math class 130
toLowerCase(), String class 138
top, stack 365
top-down design 157
top-down development 157
topology 7
toRadians(), Math class 130
toString() 186
toString(), Double 285
toString(), Integer 285
toUpperCase(), String class 138
transmission media 7
traversing
array 240
ArrayList 254
trim(), String class 138
Trojan horse 21
true 79
truncate
modulus division 83
toward 0 84
truth table 112
try-catch-finally statement 312
twisted-pair wiring 7
two-dimensional array 247
accessing elements 248
type casting 84, 245
generic collection classes 254
object 186
objects 254
U
ultra-portable devices 12
underscore (_) 87
Unicode 10, 79, 244, 314, 381
Unicode Standard 140
Unix 2
uppercase, converting strings 138
USB 12
utility program 4
V
variable 77
class 180, 184
initializing in a class 183
instance 184
in println() 78
member 181
state of object 179
variable trace 136
video adapters 1
virtual 62
Virtual Machine 62
virus 21
visibility 159, 182
subclasses 215
Visual Basic .NET 6, 62
visual organizer 66
VM 62
void 159
W
W3C 36
WAI 44
WAN 6
Watch window 136
wearable computers 5
Web 15
website 35
website citations 17
Web Accessibility Initiative 44
web beacons 18
web browser 15
web browsers 35
web bugs 18
web directory 17
while 131
whole number 77
Wi-Fi 8
Wide-Area Network 6
Windows 2
Windows media player 44
Windows XP environment 3
WinZip 11
wireless access point 8
Wireless Fidelity 8
wireless networks 8, 14
wireless transmission media 7
words 10
World Wide Web 15, 35
World Wide Web Consortium 36
worm 21
wrapper classes 253
wrist-top computers 5
write(), BufferedWriter class 318
writeDouble(), ObjectOutputStream
class 320
writeInt(), ObjectOutputStream
class 320
writeObject(), ObjectOutputStream
class 320
writing data to a file 319
WWW 35
www.sun.com 80
Y
Yahoo! 15
Z
Zip drives 12
A Guide to Programming in Java emphasizes the development of good problem-solving and programming
skills in a clear, easy-to-understand format, continuing the tradition of the Lawrenceville Press series of
programming texts. To date, more than two million students have learned computing using a Lawrenceville
Press text. A Guide to Programming in Java has been developed for the AP Computer Science curriculum
and is an excellent text for an introductory programming course.
Features of A Guide to Programming in Java:
AP COMPUTER SCIENCE CURRICULUM Content matches the College Boards AP Computer
Science topic outline and Java subset.
JAVA 2 PLATFORM STANDARD EDITION 5 Supports the Java 2 Platform Standard Edition 5
and is backwards-compatible with previous editions.
OBJECT-ORIENTED DEVELOPMENT APPROACH Object-oriented programming is introduced
from the very start of the text.
PROGRAMMING CONCEPTS An emphasis is placed on fundamental concepts including
variables, conditional control structures, loops, strings, methods, classes, arrays, and les.
PROGRAMMING TECHNIQUES Solutions are designed using algorithms and Java code
conventions are modelled throughout the text.
DEMONSTRATION APPLICATIONS Each chapter includes many demonstration applications
that illustrate both the source code and generated output.
REVIEWS AND EXERCISES After a new concept is discussed, review problems provide an
opportunity for students to apply the concepts to creating an application. At the end of each
chapter are numerous hands-on exercises of varying difculty, appropriate for students with a
wide range of abilities.
CASE STUDIES A case study is presented at the end of most chapters. The case study illustrates
a complex application using good programming methodology of specication, design, coding,
testing, and debugging.
TEACHING APPROACH The text is written for a variety of Java compilers. It is also written
for different student learning styles and effectively uses screen shots of source code, generated
output, and nished projects to strengthen understanding.
CRITICAL THINKING A variety of written-response questions that provoke critical thinking
are provided at the end of each chapter.
GUI AND EVENT-DRIVEN PROGRAMMING The Swing Java package is introduced for creating
GUI event-driven applications.
APPLETS AND WEB PROGRAMMING Applets and web programming are introduced.
This text is available in hardcover and softcover editions.
ISBN 1-58003-072-6
~<(sl&s!=adahce< Hardcover