Chapter 8 Exercises Solution Building Java Programs 4th Edition
Building Java Programs, 4th Edition
Self-Check Solutions
NOTE: Answers to self-check problems are posted publicly on our web site and are accessible to students. This means that self-check problems generally should not be assigned as graded homework, because the students can easily find solutions for all of them. If you want to assign BJP end-of-chapter problems as homework, please consider using our Exercises or Programming Projects, the solutions to which are not publicly posted (but are available to instructors only by request).
- Chapter 1
- Chapter 2
- Chapter 3
- Supplement 3G
- Chapter 4
- Chapter 5
- Chapter 6
- Chapter 7
- Chapter 8
- Chapter 9
- Chapter 10
- Chapter 11
- Chapter 12
- Chapter 13
- Chapter 14
- Chapter 15
- Chapter 16
- Chapter 17
- Chapter 18
- Chapter 19
Chapter 1
- Computers use binary numbers because it's easier to build electronic devices reliably if they only have to distinguish between two electric states.
-
- 6 = 110
- 44 = 101100
- 72 = 1001000
- 131 = 10000011
-
- 100 = 4
- 1011 = 11
- 101010 = 42
- 1001110 = 78
-
- Make the cookie batter:
- Mix the dry ingredients.
- Cream the butter and sugar.
- Beat in the eggs.
- Stir in the dry ingredients.
- Bake the cookies:
- Set the oven for the appropriate temperature.
- Set the timer.
- Place the cookies into the oven.
- Allow the cookies to bake.
- Add frosting and sprinkles:
- Mix the ingredients for the frosting.
- Spread frosting and sprinkles onto the cookies.
- Make the cookie batter:
-
MyProgram.java
is a source code file typed by the programmer, andMyProgram.class
is a compiled executable class file that is run by the computer. - The legal identifiers shown are
println
,AnnualSalary
,ABC
,sum_of_data
,_average
, andB4
. - d.
System.out.println("Hello, world!");
-
Output of statements:
"Quotes" Slashes \// How '"confounding' "\" it is!
-
Output of statements:
name age height Archie 17 5'9" Betty 17 5'6" Jughead 16 6'
-
Output of statements:
Shaq is 7'1 The string "" is an empty message. \'""
-
Output of statements:
a b c \\ ' """ C: in he downward spiral
-
Output of statements:
Dear "DoubleSlash" magazine, Your publication confuses me. Is it a \\ slash or a //// slash? Sincerely, Susan "Suzy" Smith
-
println
statements to produce desired output:System.out.println("\"Several slashes are sometimes seen,\""); System.out.println("said Sally. \"I've said so.\" See?"); System.out.println("\\ / \\\\ // \\\\\\ ///");
-
println
statements to produce desired output:System.out.println("This is a test of your"); System.out.println("knowledge of \"quotes\" used"); System.out.println("in 'string literals.'"); System.out.println(); System.out.println("You're bound to \"get it right\""); System.out.println("if you read the section on"); System.out.println("''quotes.''");
-
println
statement to produce desired output:System.out.println("/ \\ // \\\\ /// \\\\\\");
-
Equivalent code without
System.out.print
statements:System.out.println("Twas brillig and the "); System.out.println(" slithy toves did gyre and"); System.out.println("gimble"); System.out.println(); System.out.println("in the wabe.");
-
Output of
Commentary
program:some lines of code have // characters on them which means lines can also have /* and */ characters of comment.
-
Mistakes in
MyProgram
program:- line 1: The keyword
class
is missing. - line 3: A semicolon is missing.
- line 4: The word
Println
should not be capitalized.
- line 1: The keyword
-
Mistakes in
SecretMessage
program:- line 2: The keyword
void
is missing. - line 2: The word
string
should be capitalized. - line 4: A closing
"
mark is missing. - line 5: A closing
}
brace is missing.
- line 2: The keyword
-
Mistakes in
FamousSpeech
program:- line 1: A
{
brace is missing. - line 2: The word
args
is missing. - line 8: The comment on lines 8-10 accidentally comments out lines 9-10 of the program. Using
//
comments would fix the problem. - line 11: A closing right parenthesis
)
is missing.
- line 1: A
- b.
public static void example() {
-
Output of
Tricky
program:This is message1. This is message2. This is message1. Done with message2. Done with main.
-
Output of
Strange
program:Inside first method Inside third method Inside first method Inside second method Inside first method Inside second method Inside first method Inside third method Inside first method Inside second method Inside first method
-
Output of
Strange2
program:Inside first method Inside first method Inside second method Inside first method Inside third method Inside second method Inside first method Inside first method Inside second method Inside first method Inside third method
-
Output of
Strange3
program:Inside second method Inside first method Inside first method Inside second method Inside first method Inside third method Inside first method Inside second method Inside first method
-
Output of
Confusing
program:I am method 1. I am method 1. I am method 2. I am method 3. I am method 1. I am method 1. I am method 2. I am method 1. I am method 2. I am method 3. I am method 1.
-
Output of
Confusing2
program:I am method 1. I am method 1. I am method 1. I am method 2. I am method 3. I am method 1. I am method 2. I am method 1. I am method 1. I am method 2. I am method 3.
-
Output of
Confusing3
program:I am method 1. I am method 2. I am method 1. I am method 1. I am method 2. I am method 3. I am method 1. I am method 1. I am method 2.
-
Mistakes in
LotsOfErrors
program:- line 1: The class name should be
LotsOfErrors
(no space). - line 2: The word
void
should appear afterstatic
. - line 2:
String
should beString[]
. - line 3:
System.println
should beSystem.out.println
. - line 3:
"Hello, world!)
should be"Hello, world!")
. - line 4: There should be a semicolon after
message()
. - line 7: There should be a
()
after message. - line 8:
System.out println
should beSystem.out.println
. - line 8:
cannot";
should becannot");
. - line 9: The phrase
"errors"
cannot appear inside aString
.'errors'
or\"errors\"
would work. - line 11: There should be a closing
}
brace.
- line 1: The class name should be
-
Mistakes in
Example
program:- Syntax error: The program would not compile because its class name (
Demonstration
) would not match its file name (Example.java
). - Different program output: The program would not run because Java would be unable to find the
main
method. - Different program output: There would now be a blank line between the two printed messages.
- Syntax error: The program would not compile because the
main
method would be calling a method (displayRule
) that no longer existed. - No effect: The program would still compile successfully and produce the same output.
- Different program output: The output would now have no line break between "The first rule" and "of Java Club is," in its output.
- Syntax error: The program would not compile because its class name (
-
Reformatted version of
GiveAdvice
program:// Suzy Student, Fall 2048 // This program prints a message about proper formatting // of Java programs. public class GiveAdvice { public static void main(String[] args) { System.out.println("Programs can be easy or"); System.out.println("difficult to read, depending"); System.out.println("upon their format."); System.out.println(); System.out.println("Everyone, including yourself,"); System.out.println("will be happier if you choose"); System.out.println("to format your programs."); } }
-
Reformatted version of
Messy
program:// Suzy Student, Fall 2048 // This program prints a cautionary message about messy formatting // of Java programs. public class Messy { public static void main(String[] args) { message(); System.out.println(); message(); } public static void message() { System.out.println("I really wish that"); System.out.println("I had formatted my source"); System.out.println("code correctly!"); } }
Chapter 2
- Legal
int
literals:22
,-1
, and-6875309
- d.
11
-
Results of
int
expressions:-
8
-
11
-
6
-
4
-
33
-
-16
-
6.4
-
6
-
30
-
1
-
7
-
5
-
2
-
18
-
3
-
4
-
4
-
15
-
8
-
1
-
-
Results of
double
expressions:-
9.0
-
9.6
-
2.2
-
6.0
-
6.0
-
8.0
-
1.25
-
3.0
-
3.0
-
3.0
-
5.0
-
6.4
-
37.0
-
8.5
-
9.6
-
4.0
-
4.8
-
-
Results of
String
expressions:-
11
-
"2 + 2 34"
-
"2 2 + 3 4"
-
"7 2 + 2"
-
"2 + 2 7"
-
"(2 + 2) 7"
-
"hello 34 8"
-
- c.
double grade = 4.0;
-
int age; String gender; double height; int weight;
-
String year; int numberOfCourses; double gpa;
- Last digit:
number % 10
-
Mistakes in
Oops2
program:- line 4: There should be a
+
betweenis
andx
. - line 4: Variable
x
has not yet been given any value. - line 6: Variable
x
is being redeclared. The wordint
should be omitted. - line 6: Variable
x
is being given a value of the wrong type (double
). - line 7: The
+ x
should be outside the quotes. - line 10: The word
int
should be omitted. - line 11: The word
and
should be surrounded by quotes.
- line 4: There should be a
-
- Second-to-last digit:
(number % 100) / 10
or(number / 10) % 10
- Third-to-last digit:
(number % 1000) / 100
or(number / 100) % 10
- Second-to-last digit:
- d.
10
-
Values of
a
,b
, andc
after the code:a: 6 b: 9 c: 16
-
Values of
first
andsecond
after the code:first: 19 second: 8
The code swaps the values of the variablesfirst
andsecond
. -
Rewritten shortened version of the code:
int first = 8, second = 19; first += second; second = first - second; first -= second;
-
Values of
i
,j
, andk
after the code:i: 4 j: 2 k: 1
-
Output of code:
46 36 23 13
-
Expression to compute
y
while using*
only four times:double y = x * (x * (x * (x * 12.3 - 9.1) + 19.3) - 4.6) + 34.2;
-
Version of
ComputePay
program that uses variables to avoid redundant expressions:public class ComputePay { public static void main(String[] args) { // Calculate my pay at work, based on how many hours I worked each day int totalHours = 4 + 5 + 8 + 4; double salary = 8.75; double pay = totalHours * salary; double taxRate = 0.20; double taxesOwed = pay * taxRate; System.out.println("My total hours worked:"); System.out.println(totalHours); System.out.println("My hourly salary:"); System.out.println("$" + salary); System.out.println("My total pay:"); System.out.println(pay); System.out.println("My taxes owed:"); System.out.println(taxesOwed); } }
-
// This program computes the total amount owed for a meal, // assuming 8% tax and a 15% tip. public class Receipt { public static void main(String[] args) { int subtotal = 38 + 40 + 30; System.out.println("Subtotal:"); System.out.println(subtotal); double tax = subtotal * .08; System.out.println("Tax:"); System.out.println(tax); double tip = subtotal * .15; System.out.println("Tip:"); System.out.println(tip); double total = subtotal + tax + tip; System.out.println("Total:"); System.out.println(total); } }
-
public class Count2 { public static void main(String[] args) { for (int i = 1; i <= 4; i++) { System.out.println("2 times " + i + " = " + (2 * i)); } } }
-
-
2 * count
-
15 * count - 11
-
-10 * count + 40
-
4 * count - 11
-
-3 * count + 100
-
-
for (int i = 1; i <= 6; i++) { // your code here System.out.println(18 * i - 22); }
-
Output of
oddStuff
method:4 2
-
Output of loop:
24 1 22 2 19 3 15 4 10 5
-
Output of loop:
+---+ \ / / \ \ / / \ \ / / \ +---+
-
Output of loop:
How many lines How many lines How many lines are printed?
-
Output of loop:
T-minus 5, 4, 3, 2, 1, Blastoff!
-
Output of loops:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50
-
Output of loops:
* *** ***** ******* ********* *********** ************* *************** ***************** *******************
-
Output of loops:
****!****!****! ****!****!****!
-
Output of loops:
************! ************!
-
Output of loops:
*!*!*!*! *!*!*!*! *!*!*!*! *!*!*!*! *!*!*!*! *!*!*!*!
-
Mistakes in
BadNews
program:- The loop prints every third number, not every odd number. The statement
count = count + 2
on line 8 should be moved into the loop header instead ofcount++
. - line 12: The variable
count
is no longer defined (its scope is limited to thefor
loop). It should be declared before the loop begins rather than inside the loop's header. - line 12: Too large a value is printed for the final odd number;
count
should be printed, notcount + 2
. - line 20: It is illegal to try to assign a new value to a constant such as
MAX_ODD
. One way to fix this would be to write two methods: one to print the odds up to 21 and a second to print the odds up to 11. (Admittedly, this solution is redundant. A better solution to this kind of problem involves parameter passing, which will be demonstrated in later chapters.)
- The loop prints every third number, not every odd number. The statement
-
Output of
Strange
program:The result is: 55
-
-
2 * line + 2 * SIZE
-
4 * line + (3 * SIZE)
-
-line + (2 * SIZE + 3)
-
-
Table for output:
line \
!
/
1 0 22 0 2 2 18 2 3 4 14 4 4 6 10 6 5 8 6 8 6 10 2 10 - expression for
\
and/
:2 * line - 2
- expression for
!
:-4 * line + 26
- expression for
-
Table for output:
line \
!
/
1 0 14 0 2 2 10 2 3 4 6 4 4 6 2 6 - expression for
\
and/
:2 * line - 2
- expression for
!
:-4 * line + 18
- generalized for constant:
-4 * line + (4 * SIZE + 2)
- expression for
Chapter 3
- e.
public static void example(int x, int y) {
-
MysteryNums
output:15 42 10 25
-
Mistakes in
Oops3
program:- line 5: cannot use variable
y
without declaring and initializing it - line 5: cannot declare the type of
y
in the method call - line 6: cannot call
printer
without the correct number of parameters (2, in this case) - line 7: cannot call
printer
by passing the correct type of parameters (double
, in this case) - line 8: cannot refer to the variable
z
: it is in scope insideprinter
, notmain
- line 11: must provide a type for
x
- line 11: must provide a variable name for the second parameter
- line 12: must refer to the parameters using the exact same spelling
- line 13: cannot refer to variables in
main
that were not passed intoprinter
as a parameter
- line 5: cannot use variable
-
Output of
Odds
program:1 3 5 1 3 5 7 9 11 13 15 1 3 5 7 9 11 13 15 17 19 21 23 25
-
Output of
Weird
program:1 2 3 4 5 1 2 3 4 5 6 7 1 2 3 4 number = 8
-
Output of
MysteryNumbers
program:three times two = 6 1 times three = 28 1 times 1 = 42 three times 1 = 2 1 times eight = 20
-
Output of
MysteryWho
program:whom and who like it it and him like whom whom and him like him stu and boo like who her and him like who
-
Output of
MysteryTouch
program:touch your eye to your head touch your head to your eye touch your shoulders to your elbow touch your eyes and ears to your eyes and ears touch your toes to your Toes touch your shoulders to your knees toes
-
Output of
MysterySoda
program:say coke not pepsi or pop say soda not soda or pepsi say pepsi not koolaid or pop say say not pepsi or pepsi
-
public static void printStrings(String s, int n) { for (int i = 1; i <= n; i++) { System.out.print(s); } System.out.println(); }
-
System.out.println
is an overloaded method. - The
Temperature
program changes the value of itstempc
parameter on line 11, but this doesn't affect the variabletempc
inmain
. The (incorrect) output is:Body temp in C is: 0.0
-
results of
Math
expressions:-
1.6
-
2
-
36.0
-
64.0
-
10.0
-
116.0
-
7
-
5
-
-5
-
8.0
-
11.0
-
102.0
-
17.0
-
20.0
-
13.0
-
14.0
-
-
Output of
MysteryReturn
program:3 0 1 2 4 4 3 5 2 4 8 1 5 9 4
-
double grade = 2.7; Math.round(grade); // grade = 2.7 grade = Math.round(grade); // grade = 3.0 double min = Math.min(grade, Math.floor(2.9)); // min = 2.0 double x = Math.pow(2, 4); // x = 16.0 x = Math.sqrt(64); // x = 8.0 int count = 25; Math.sqrt(count); // count = 25 count = (int) Math.sqrt(count); // count = 5 int a = Math.abs(Math.min(-1, -3)); // a = 3
-
public static int min(int n1, int n2, int n3) { return Math.min(n1, Math.min(n2, n3)); }
-
public static int countQuarters(int cents) { return cents % 100 / 25; }
-
Kirk My name is James James Kirk Kirk, Kames T. T. is for Tiberius
-
results of
String
expressions:-
13
-
'a'
-
'G'
-
2
-
"GANDALF THE GRAY"
-
-1
-
"o Baggins"
-
"dalf the GR"
-
"Goondoolf the GRAY"
-
"Gandalf the GRAY"
-
"strange1"
-
-
results of
String
expressions:-
6
-
19
-
"q.e.d."
-
"ARCTURAN MEGADONKEY"
-
"E."
-
"egad"
-
4
-
1
-
13
-
-1
-
"Arcturan Megadonkeys"
-
"b"
-
"Cyber"
-
"mega Corp"
-
-
String quote = "Four score and seven years ago"; String expr1 = quote.substring(5, 10).toUpperCase(); // "SCORE" String expr2 = quote.toLowerCase().substring(0, 4) + quote.substring(20, 26); // "four years"
-
Hello there. 1+2 is 3 and 1.5 squared is 2.25!
There are 10 tokens:-
Hello
: (String
) -
there.
: (String
) -
1+2
: (String
) -
is
: (String
) -
3
: (int
,double
,String
) -
and
: (String
) -
1.5
: (double
,String
) -
squared
: (String
) -
is
: (String
) -
2.25!
: (String
)
-
-
-
34.50
: The code will run successfully and the variable money will store the value34.5
. -
6
: The code will run successfully and the variable money will store the value6.0
. -
$25.00
: The code will crash with an exception. -
million
: The code will crash with an exception. -
100*5
: The code will crash with an exception. -
600x000
: The code will crash with an exception. -
none
: The code will crash with an exception. -
645
: The code will run successfully and the variable money will store the value645.0
.
-
-
Scanner console = new Scanner(System.in); System.out.print("Type an integer: "); int number = console.nextInt(); System.out.println(number + " times 2 = " + (number * 2));
-
import java.util.*; public class SumNumbers { public static void main(String[] args) { Scanner console = new Scanner(System.in); System.out.print("low? "); int low = console.nextInt(); System.out.print("high? "); int high = console.nextInt(); int sum = 0; for (int i = low; i <= high; i++) { sum += i; } System.out.println("sum = " + sum); } }
-
Scanner console = new Scanner(System.in); System.out.print("What is your phrase? "); String phrase = console.nextLine(); System.out.print("How many times should I repeat it? "); int times = console.nextInt(); for (int i = 1; i <= times; i++) { System.out.println(phrase); }
Supplement 3G
-
Correct syntax to draw a rectangle:
b.g.drawRect(10, 20, 50, 30);
-
Mistakes in the code:
- On the second line, the call to
drawLine
should be made on theGraphics
objectg
, not on theDrawingPanel
itself. - On the second line, the order of the parameters is incorrect.
The following is the corrected code:
DrawingPanel panel = new DrawingPanel(200, 200); Graphics g = panel.getGraphics(); g.drawLine(50, 86, 20, 35);
- On the second line, the call to
-
The black rectangle is being drawn second, so it's covering up the white inner circle. The following code fixes the problem:
DrawingPanel panel = new DrawingPanel(200, 100); Graphics g = panel.getGraphics(); g.setColor(Color.BLACK); g.fillRect(10, 10, 50, 50); g.setColor(Color.WHITE); g.fillOval(10, 10, 50, 50);
-
The problem is that the parameters for the drawRect and drawLine methods have different meanings. In
drawRect
, the parameters are (x, y, width, height); indrawLine
, they are (x1, y1, x2, y2). To fix the problem, the third and fourth parameters passed todrawRect
should be changed to 40 and 20 so that the rectangle's bottom-left corner will be at (50, 40). The following code fixes the problem:DrawingPanel panel = new DrawingPanel(200, 100); Graphics g = panel.getGraphics(); g.drawRect(10, 20, 40, 20); g.drawLine(10, 20, 50, 40);
-
The
Draw7
program draws a series of progressively smaller black circles, each with its right and bottom edges touching the right and bottom corners of the window. Its output looks like this:
Chapter 4
-
English statements translated into logical tests:
-
z % 2 == 1
-
z <= Math.sqrt(y)
-
y > 0
-
x % 2 != y % 2
-
y % z == 0
-
z != 0
-
Math.abs(y) > Math.abs(z)
-
(x >= 0) == (z < 0)
-
y % 10 == y
-
z >= 0
-
x % 2 == 0
-
Math.abs(x - y) < Math.abs(z - y)
-
-
Results of relational expressions:
-
true
-
false
-
true
-
false
-
true
-
false
-
false
-
true
-
true
-
-
Correct syntax for
e.if
statement:if (x == y) {
-
Mistakes in
Oops4
program:- line 5:
if
statement should use()
parentheses, not{}
brackets - line 5:
=
should be==
- line 5:
smaller
is out of scope here - line 10:
void
should beint
- line 13:
=>
should be>=
(or better yet, noif
test is needed) - line 16: should not write variable's type of
int
when returning it - line 16:
int smaller
is out of scope here (declare outsideif
or return directly)
- line 5:
-
Output of
ifElseMystery1
calls:Call Output a. ifElseMystery1(3, 20);
13 21
b. ifElseMystery1(4, 5);
5 6
c. ifElseMystery1(5, 5);
6 5
d. ifElseMystery1(6, 10);
7 11
-
Output of
ifElseMystery2
calls:Call Output a. ifElseMystery2(10, 2);
10 6
b. ifElseMystery2(3, 8);
9 9
c. ifElseMystery2(4, 4);
3 4
d. ifElseMystery2(10, 30);
29 30
-
Code to read an integer from the user, then print
even
if that number is an even number orodd
otherwise:Scanner console = new Scanner(System.in); System.out.print("Type a number: "); int number = console.nextInt(); if (number % 2 == 0) { System.out.println("even"); } else { System.out.println("odd"); }
-
The code incorrectly prints that even numbers not divisible by 3 are odd. This is because the
else
statement matches the most closely nestedif
statement (number % 3 == 0
), not the outerif
statement. The following change corrects the problem. Note the braces around the outerif
statement:if (number % 2 == 0) { if (number % 3 == 0) { System.out.println("Divisible by 6."); } } else { System.out.println("Odd."); }
-
The code won't ever print "Mine, too!" because it mistakenly uses the
==
operator to compare two strings. It should use theequals
method to compare them:if (name.equals("blue")) { ...
-
Refactored code to reduce redundancy:
a = 2; if (x < 30) { x++; } System.out.println("Java is awesome! " + x);
-
Refactored code to reduce redundancy:
Scanner console = new Scanner(System.in); System.out.print("Is your money multiplied 1 or 2 times? "); int times = console.nextInt(); System.out.print("And how much are you contributing? "); int donation = console.nextInt(); sum += times * donation; total += donation; if (times == 1) { count1++; } else if (times == 2) { count2++; }
If the user could type any number, the code might need additional
if
statements to increment the proper count variable. If the user could type anything, even a non-integer, the code might need to use thehasNextInt
method of theScanner
to ensure valid input before proceeding. -
Refactored code to reduce redundancy:
// Prompts for two people's money and reports how many $20 bills are needed. import java.util.*; public class Bills { public static void main(String[] args) { Scanner console = new Scanner(System.in); int numBills1 = getBills(console, "John"); int numBills2 = getBills(console, "Jane"); System.out.println("John needs " + numBills1 + " bills"); System.out.println("Jane needs " + numBills2 + " bills"); } public static int getBills(Scanner console, String name) { System.out.print("How much will " + name + " be spending? "); double amount = console.nextDouble(); System.out.println(); int numBills = (int) (amount / 20.0); if (numBills * 20.0 < amount) { numBills++; } return numBills; } }
-
Code to read red/green/blue color:
Scanner console = new Scanner(System.in); System.out.print("What color do you want? "); String choice = console.nextLine(); if (choice.equalsIgnoreCase("r")) { System.out.println("You have chosen Red."); } else if (choice.equalsIgnoreCase("g")) { System.out.println("You have chosen Green."); } else if (choice.equalsIgnoreCase("b")) { System.out.println("You have chosen Blue."); } else { System.out.println("Unknown color: " + choice); }
-
Code to read playing card information:
Scanner console = new Scanner(System.in); System.out.print("Enter a card: "); String rank = console.next(); String suit = console.next(); if (rank.equals("2")) { rank = "Two"; } else if (rank.equals("3")) { rank = "Three"; } else if (rank.equals("4")) { rank = "Four"; } else if (rank.equals("5")) { rank = "Five"; } else if (rank.equals("6")) { rank = "Six"; } else if (rank.equals("7")) { rank = "Seven"; } else if (rank.equals("8")) { rank = "Eight"; } else if (rank.equals("9")) { rank = "Nine"; } else if (rank.equals("10")) { rank = "Ten"; } else if (rank.equals("J")) { rank = "Jack"; } else if (rank.equals("Q")) { rank = "Queen"; } else if (rank.equals("K")) { rank = "King"; } else { // rank.equals("A") rank = "Ace"; } if (suit.equals("C")) { suit = "Clubs"; } else if (suit.equals("D")) { suit = "Diamonds"; } else if (suit.equals("H")) { suit = "Hearts"; } else { // suit.equals("S") suit = "Spades"; } System.out.println(rank + " of " + suit);
-
The problem with the given
sumTo
method is that thesum
variable needs to be declared outside thefor
loop. The following code fixes the problem:public static int sumTo(int n) { int sum = 0; for (int i = 1; i <= n; i++) { sum += i; } return sum; }
-
The
countFactors
method shown will not compile. It should count the factors using a a cumulative sum; it should not return inside the loop when it finds each factor. Instead, it should declare a counter outside the loop that is incremented as each factor is seen. The following code fixes the problem:public static int countFactors(int n) { int count = 0; for (int i = 1; i <= n; i++) { if (n % i == 0) { count++; } } return count; }
-
Code to produce a cumulative product by multiplying together many numbers that are read from the console:
Scanner console = new Scanner(System.in); System.out.print("How many numbers? "); int count = console.nextInt(); int product = 1; for (int i = 1; i <= count; i++) { System.out.print("Next number --> "); int num = console.nextInt(); product *= num; } System.out.println("Product = " + product);
-
The expression equals
6.800000000000001
rather than the expected6.8
because the limited precision of thedouble
type led to a roundoff error. -
The expression
gpa * 3
equals9.600000000000001
rather than the expected9.6
because of a roundoff error. A fix would be to test that the value is close to9.6
rather than exactly equal to it, as shown in the following code:double gpa = 3.2; double diff = Math.abs(gpa * 3 - 9.6); if (diff < 0.1) { System.out.println("You earned enough credits."); }
-
Output of
CharMystery
program:efg nopqrs qr
-
Statement that tests to see whether a string begins with a capital letter:
if (Character.isUpperCase(theString.charAt(0))) { ... }
-
The
toLowerCase
method cannot be called on achar
value, which is what thecharAt
method returns. A better solution would be to call theCharacter.toLowerCase
method on the characters of the string, as shown in the following code:int count = 0; for (int i = 0; i < s.length(); i++) { if (Character.toLowerCase(s.charAt(i)) == 'e') { count++; } }
Another solution would be to lowercase the entire string once before the loop:
s = s.toLowerCase(); int count = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == 'e') { count++; } }
-
The following expression would produce the desired result:
String name = "Marla Singer"; int space = name.indexOf(" "); String lastName = name.substring(space + 1); String firstInitial = name.substring(0, 1); String lastNameFirstInitial = lastName + ", " + firstInitial + "."; System.out.println(lastNameFirstInitial);
-
Code to examine a string and determine how many of its letters come from the second half of the alphabet (
'n'
or later):// assuming that the String is stored in the variable str int count = 0; for (int i = 0; i < str.length(); i++) { if (Character.toLowerCase(str.charAt(i)) >= 'n') { count++; } } System.out.println(count + " letters come after n.");
-
The preconditions of
printTriangleType
method are that the three side lengths constitute a valid triangle. Namely:- All three side lengths passed are >= 0.
- No side's length exceeds the sum of any two other sides.
-
The preconditions of the
getGrade
method are that the grade parameter's value is between 0 and 100. -
The
medianOf3
code fails whenn3
is the smallest of the three numbers; for example, when the parameters' values are (4, 7, 2), the code should return 4 but instead returns 2. The method could be correctly written as:public static int medianOf3(int n1, int n2, int n3) { if (n1 < n2 && n1 < n3) { if (n2 < n3) { return n2; } else { return n3; } } else if (n2 < n1 && n2 < n3) { if (n1 < n3) { return n1; } else { return n3; } } else { // (n3 < n1 && n3 < n2) if (n1 < n2) { return n1; } else { return n2; } } }
or the following shorter version:
public static int medianOf3(int n1, int n2, int n3) { return Math.max(Math.max(Math.min(n1, n2), Math.min(n2, n3)), Math.min(n1, n3)); }
-
The
quadratic
method would fail if the coefficienta
is 0 Invalid values are when a = 0 (because it makes the denominator of the equation equal 0), or if the determinant (b2 - 4ac) is negative (because then it has no real square root). The following version of the code checks for these cases and throws exceptions:// Throws an exception if a, b, c are invalid public static void quadratic(int a, int b, int c) { double determinant = b * b - 4 * a * c; if (a == 0) { throw new IllegalArgumentException( "Invalid a value of 0"); } if (determinant < 0) { throw new IllegalArgumentException( "Invalid determinant"); } ... }
-
The code fails when more than one number is odd, because it uses
else if
rather thanif
. The tests should not be nested because they are not mutually exclusive; more than one number could be odd. The following code fixes the problem:public static void printNumOdd(int n1, int n2, int n3) { int count = 0; if (n1 % 2 != 0) { count++; } if (n2 % 2 != 0) { count++; } if (n3 % 2 != 0) { count++; } System.out.println(count + " of the 3 numbers are odd."); }
The following version without
if
statements also works:public static void printNumOdd(int n1, int n2, int n3) { int count = n1 % 2 + n2 % 2 + n3 % 2; System.out.println(count + " of the 3 numbers are odd."); }
Alternatively, you could use this shorter version:
String name = "Marla Singer"; System.out.println(name.substring(name.indexOf(" ") + 1) + ", " + name.charAt(0) + ".");
Chapter 5
-
- Executes body 10 times. Output is:
1 11 21 31 41 51 61 71 81 91
- Executes body 0 times. No output.
- Loops infinitely. Output is:
250 250 250 ...
- Executes body 3 times. Output is:
2 4 16
- Executes body 5 times. Output is:
bbbbbabbbbb
- Executes body 7 times. Output is:
10 5 2 1 0 0 0
- Executes body 10 times. Output is:
-
-
int n = 1; while (n <= max) { System.out.println(n); n++; }
-
int total = 25; int number = 1; while (number <= (total / 2)) { total = total - number; System.out.println(total + " " + number); number++; }
-
int i = 1; while (i <= 2) { int j = 1; while (j <= 3) { int k = 1; while (k <= 4) { System.out.print("*"); k++; } System.out.print("!"); j++; } System.out.println(); i++; }
-
int number = 4; int count = 1; while (count <= number) { System.out.println(number); number = number / 2; count++; }
-
-
Output of
mystery
calls:Call Output a. mystery(1);
1 0
b. mystery(6);
4 2
c. mystery(19);
16 4
d. mystery(39);
32 5
e. mystery(74);
64 6
-
Output of
mystery
calls:Call Output a. mystery(19);
19 0
b. mystery(42);
21 1
c. mystery(48);
3 4
d. mystery(40);
5 3
e. mystery(64);
1 6
-
Range of random values generated:
- 0 through 99 inclusive
- 50 through 69 inclusive
- 0 through 69 inclusive
- -20 through 79 inclusive
- 0, 4, 8, 12, 16, 20, 24, 28, 32, or 36
-
Code that generates a random integer between 0 and 10 inclusive:
Random rand = new Random(); int num = rand.nextInt(11);
-
Code that generates a random odd integer between 50 and 99 inclusive.
Random rand = new Random(); int num = rand.nextInt(25) * 2 + 51;
-
- Executes body 10 times. Output is:
1 11 21 31 41 51 61 71 81 91
- Loops infinitely. Output is:
count down: 10 count down: 9 count down: 8 count down: 7 count down: 6 count down: 5 count down: 4 count down: 3 count down: 2 count down: 1 count down: 0 count down: -1 ...
- Loops infinitely. Output is:
250 250 250 ...
- Executes body 2 times. Output is:
100 50
- Executes body 3 times. Output is:
2 4 16
- Executes body 5 times. Output is:
bbbbbabbbbb
- Executes body 7 times. Output is:
10 5 2 1 0 0 0
- Executes body 3 times. Output is:
/\/\/\/\/\/\/\/\
- Executes body 10 times. Output is:
-
do/while
loop that repeatedly prints a certain message until the user tells the program to stop:Scanner console = new Scanner(System.in); String response; do { System.out.println("She sells seashells by the seashore."); System.out.print("Do you want to hear it again? "); response = console.nextLine(); } while (response.equals("y"));
-
public static int zeroDigits(int number) { int count = 0; do { if (number % 10 == 0) { count++; } number = number / 10; } while (number > 0); return count; }
-
do/while
loop that repeatedly prints random numbers between 0 and 1000 until a number above 900 is printed:Scanner console = new Scanner(System.in); Random rand = new Random(); int num; do { num = rand.nextInt(1000); System.out.println("Random number: " + num); } while (num < 900);
-
The
printLetters
code has a fencepost problem; it will print a dash after the last letter. The following code corrects the problem:public static void printLetters(String text) { if (text.length() > 0) { System.out.print(text.charAt(0)); for (int i = 1; i < text.length(); i++) { System.out.print("-" + text.charAt(i)); } } System.out.println(); // to end the line of output }
-
Sentinel loop that repeatedly prompts the user to enter a number and, once the number
-1
is typed, displays the maximum and minimum numbers that the user entered:int SENTINEL = -1; System.out.print("Type a number (or " + SENTINEL + " to stop): "); Scanner console = new Scanner(System.in); int input = console.nextInt(); int min = input; int max = input; while (input != SENTINEL) { if (input < min) { min = input; } else if (input > max) { max = input; } System.out.print("Type a number (or " + SENTINEL + " to stop): "); input = console.nextInt(); } if (min != SENTINEL) { System.out.println("Maximum was " + max); System.out.println("Minimum was " + min); }
-
Results of
boolean
expressions:-
true
-
true
-
false
-
true
-
true
-
false
-
false
-
true
-
true
-
true
-
true
-
false
-
-
public static boolean isVowel(char c) { c = Character.toLowerCase(c); // case-insensitive return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; }
or:public static boolean isVowel(char c) { return "aeiouAEIOU".indexOf(c) >= 0; }
-
In this
isPrime
code theboolean
flag isn't being used properly, because if the code finds a factor of the number,prime
will be set tofalse
, but on the next pass through the loop, if the next number isn't a factor,prime
will be reset totrue
again. The following code fixes the problem:public static boolean isPrime(int n) { boolean prime = true; for (int i = 2; i < n; i++) { if (n % i == 0) { prime = false; } } return prime; }
-
In this
contains
code theboolean
flag isn't being used properly, because if the code finds the character,found
will be set totrue
, but on the next pass through the loop, if the next character isn'tch
, thenfound
will be reset tofalse
again. The following code fixes the problem:public static boolean contains(String str, char ch) { boolean found = false; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == ch) { found = true; } } return found; }
-
Improved version of
startEndSame
code using Boolean zen:public static boolean startEndSame(String str) { return str.charAt(0) == str.charAt(str.length() - 1); }
-
Improved version of
hasPennies
code using Boolean zen:public static boolean hasPennies(int cents) { return cents % 5 != 0; }
-
Output of
mystery
calls:Call Value Returned a. mystery(3, 3)
3
b. mystery(5, 3)
1
c. mystery(2, 6)
2
d. mystery(12, 18)
6
e. mystery(30, 75)
15
-
The Zune code will get stuck in an infinite loop when the current date is the end of a leap year. On December 31 of a leap year, the
days
value will be 366, so code enters theif (isLeapYear)
statement but does not enter theif (days > 366)
statement. So the loop does not subtract any days and never terminates. It can be fixed by adding abreak
statement to the loop:int days = getTotalDaysSince1980(); year = 1980; while (days > 365) { // subtract out years if (isLeapYear(year)) { if (days > 366) { days -= 366; year += 1; } else { // new code here break; // new code here } // new code here } else { days -= 365; year += 1; } }
- d.
(2 != 3) || (-1 >= 5) || !isPrime(n)
-
Negations of
boolean
expressions:-
!b
-
(x <= y) || (y <= z)
-
(x != y) && (x > z)
-
(x % 2 == 0) || !b
-
(x / 2 != 13) && !b && (z * 3 != 96)
-
(z >= x) || (z <= y && x < y)
-
-
The age/GPA reading code should reprompt for a valid integer for the user's age and a valid real number for the user's GPA. If the user types a token of the wrong type, the line of input should be consumed and the user should be reprompted. The following code implements the corrected behavior:
Scanner console = new Scanner(System.in); System.out.print("Type your age: "); while (!console.hasNextInt()) { console.next(); // throw away offending token System.out.print("Type your age: "); } int age = console.nextInt(); print("Type your GPA: "); while (!console.hasNextDouble()) { console.next(); // throw away offending token System.out.print("Type your GPA: "); } double gpa = console.nextDouble(); System.out.println("age = " + age + ", GPA = " + gpa);
-
The code will have the following behavior when each value is typed:
-
Type something for me! Jane Your name is Jane
-
Type something for me! 56 Your IQ is 56
-
Type something for me! 56.2 Your name is 56.2
-
-
Code that prompts the user for a number and then prints a different message depending on whether the number was an integer or a real number:
Scanner console = new Scanner(System.in); System.out.print("Type a number: "); if (console.hasNextInt()) { int value = console.nextInt(); System.out.println("You typed the integer " + value); } else if (console.hasNextDouble()) { double value = console.nextDouble(); System.out.println("You typed the real number " + value); }
-
Write code that prompts for three integers, averages them, and prints the average; robust against invalid input:
String prompt = "Please enter a number: "; Scanner console = new Scanner(System.in); int num1 = getInt(console, prompt); int num2 = getInt(console, prompt); int num3 = getInt(console, prompt); double average = (num1 + num2 + num3) / 3.0; System.out.println("Average: " + average);
- Point B
Point y < x
y == 0
count > 0
Point A SOMETIMES SOMETIMES NEVER ALWAYS SOMETIMES SOMETIMES Point C ALWAYS ALWAYS ALWAYS Point D SOMETIMES SOMETIMES SOMETIMES Point E NEVER SOMETIMES SOMETIMES - Point B
Point n > b
a > 1
b > a
Point A SOMETIMES SOMETIMES SOMETIMES ALWAYS SOMETIMES SOMETIMES Point C SOMETIMES ALWAYS ALWAYS Point D SOMETIMES ALWAYS NEVER Point E NEVER SOMETIMES SOMETIMES -
Point next == 0
prev == 0
next == prev
Point A SOMETIMES ALWAYS SOMETIMES Point B NEVER SOMETIMES SOMETIMES Point C NEVER NEVER ALWAYS Point D SOMETIMES NEVER SOMETIMES Point E ALWAYS SOMETIMES SOMETIMES
Chapter 6
-
A file is a named collection of information stored on a computer. We can read a file with a
Scanner
using the following syntax:Scanner input = new Scanner(new File("input.txt"));
-
The
Scanner
should read anew File
with the nametest.dat
. The correct line of code is:Scanner input = new Scanner(new File("test.dat"));
-
Correct syntax to declare a Scanner to read the file example.txt in the current directory:
b.Scanner input = new Scanner(new File("example.txt"));
-
Scanner input = new Scanner(new File("input.txt"));
-
The
c.Scanner
tokenizes the line into:"welcome...to", "the", "matrix."
-
The
b.Scanner
tokenizes the lines into:"in", "fourteen-hundred", "92", "columbus", "sailed", "the", "ocean", "blue", ":)"
-
There are 17 tokens in the input. The "string" tokens can be read with the
next
method. The "integer" tokens can be read withnextInt
. The "real number" tokens can be read withnextDouble
. The tokens are:-
Hello
(string) -
there,how
(string) -
are
(string) -
you?
(string) -
I
(string) -
am
(string) -
"very
(string) -
well",
(string) -
thank
(string) -
you.
(string) -
12
(integer, real number, string) -
34
(integer, real number, string) -
5.67
(real number, string) -
(8
(string) -
+
(string) -
9)
(string) -
"10
" (string)
-
-
The file name string should use
/
or\\
instead of\
. The\
is used to create escape sequences, and\\
represents a literal backslash. The correct string is:Scanner input = new Scanner(new File("C:/temp/new files/test.dat"));
-
-
"numbers.dat"
or"C:/Documents and Settings/amanda/My Documents/programs/numbers.dat"
-
"data/homework6/input.dat"
or"C:/Documents and Settings/amanda/My Documents/programs/data/homework6/input.dat"
- There is only one legal way to refer to this file: by its absolute path,
"C:/Documents and Settings/amanda/My Documents/homework/data.txt"
-
-
-
"names.txt"
or"/home/amanda/Documents/hw6/names.txt"
-
"data/numbers.txt"
or"/home/amanda/Documents/hw6/data/numbers.txt"
- There is only one legal way to refer to this file: by its absolute path,
"/home/amanda/download/saved.html"
-
-
Mistakes in
Oops6
program:- line 2:
main
method must say throwsFileNotFoundException
when constructing a fileScanner
- line 3: must create a
new File
when declaring theScanner
- line 9: should not declare another
Scanner
for the file - line 13:
nextLine
should behasNextLine
- line 14:
line
should benextLine
- line 16: need a second line
Scanner
to read the tokens of each line - line 16:
hasNext
should benext()
- line 19: need to add 3
println
statements to print line/word stats
- line 2:
-
The following output would be produced:
input: 6.7 This file has input: several input lines. input: input: 10 20 30 40 input: input: test 6 total
-
Output produced if
hasNext
andnext
are used:input: 6.7 input: This input: file input: has input: several input: input input: lines. input: 10 input: 20 input: 30 input: 40 input: test 12 total
-
Output produced if
hasNextInt
andnextInt
are used:0 total
Output produced if
hasNextDouble
andnextDouble
are used:input: 6.7 1 total
- a.
the quick brown fox jumps over the lazy dog
b.the quick brown fox jumps over the lazy dog
-
Program that prints itself as output:
import java.io.*; import java.util.*; public class PrintMyself { public static void main(String[] args) throws FileNotFoundException { Scanner input = new Scanner(new File("PrintMyself.java")); while (input.hasNextLine()) { System.out.println(input.nextLine()); } } }
-
Code that prompts the user for a file name and prints the contents of that file to the console as output:
public static void printEntireFile() throws FileNotFoundException { Scanner console = new Scanner(System.in); System.out.print("Type a file name: "); String filename = console.nextLine(); Scanner input = new Scanner(new File(filename)); while (input.hasNextLine()) { System.out.println(input.nextLine()); } }
-
Program that takes as input lines of text and produces as output the same text inside a box:
// precondition: no line in input is longer than width public static void printBox(Scanner input, int width) { printTopBottom(width); while (input.hasNextLine()) { String line = input.nextLine(); System.out.print("| " + line); for (int i = line.length(); i < width; i++) { System.out.print(" "); } System.out.println(" |"); } printTopBottom(width); } public static void printTopBottom(int width) { System.out.print("+"); for (int i = 0; i < width + 2; i++) { System.out.print("-"); } System.out.println("+"); }
-
A
PrintStream
object is used to write to an external file. It has methods such asprintln
andprint
. -
Code to print the following four lines of text into a file named
message.txt
:PrintStream out = new PrintStream(new File("message.txt")); out.println("Testing,"); out.println("1, 2, 3."); out.println(); out.println("This is my output file.");
-
Code that repeatedly prompts the user for a file name until the user types the name of a file that exists on the system.
public static String getFileName() { Scanner console = new Scanner(System.in); String filename = ""; do { System.out.print("Type a file name: "); filename = console.nextLine(); } while (!(new File(filename).exists())); return filename; }
-
Code that uses
getFileName
before callingprintEntireFile
:// reprompts until file name is valid public static void printEntireFile2() throws FileNotFoundException { String filename = getFileName(); Scanner input = new Scanner(new File(filename)); while (input.hasNextLine()) { System.out.println(input.nextLine()); } }
Chapter 7
-
Syntax to declare an array of ten integers:
e.int[] a = new int[10];
-
- First element:
numbers[0]
- Last element:
numbers[9]
ornumbers[numbers.length - 1]
- First element:
-
int[] data = new int[5]; data[0] = 27; data[1] = 51; data[2] = 33; data[3] = -1; data[4] = 101;
-
Code that stores all odd numbers between -6 and 38 into an array using a loop:
int[] odds = new int[22]; for (int i = 0; i < 22; i++) { odds[i] = i * 2 - 5; }
-
After the code is executed, the
numbers
array contains the following element values:[0, 4, 11, 0, 44, 0, 0, 2]
-
After the code is executed, the
data
array contains the following element values:[3, 3, 0, 0, 6, 9, 0, -18]
-
The code to print the arrays and to compare them doesn't work properly. Arrays can't be printed directly by
println
, nor can they be compared directly using relational operators such as==
. These operations can be done correctly by looping over the elements of each array and printing/comparing them one at a time, or by calling methods of theArrays
class:// print the array elements System.out.println(Arrays.toString(first)); System.out.println(Arrays.toString(second)); // see if the elements are the same if (Arrays.equals(first, second)) { ...
-
Correct syntax to declare an array of six integer values:
a.int[] a = {17, -3, 42, 5, 9, 28};
-
int[] data = {7, -1, 13, 24, 6};
-
public static int max(int[] data) { int max = data[0]; for (int i = 1; i < data.length; i++) { if (data[i] > max) { max = data[i]; } } return max; }
-
public static double average(int[] a) { double mean = 0.0; for (int i = 0; i < a.length; i++) { mean += a[i]; } return mean / a.length; }
-
An array traversal is a sequential processing of each of an array's elements. Problems that can be solved in this manner include printing an array, comparing two arrays for equality, and searching an array for a given value.
-
Code that uses a
for
loop to print each element of an array nameddata
:for (int i = 0; i < data.length; i++) { System.out.println("element [" + i + "] is " + data[i]); }
-
After the code is executed, the
list
array contains the following element values:[3, 24, 8, -5, 6, 1]
-
public static void printBackwards(int[] list) { if (list.length == 0) { System.out.println("[]"); } else { System.out.print("[" + list[list.length - 1]); for (int i = list.length - 2; i >= 0; i--) { System.out.print(", " + list[i]); } System.out.println("]"); } }
-
To make the
count
andequals
methods process arrays ofString
s, you must changeint[]
toString[]
and replace all other occurrences of the word int with String. You must also change any comparisons using==
to comparisons using theequals
method. -
public static boolean allLess(int[] list1, int[] list2) { if (list1.length != list2.length) { return false; } for (int i = 0; i < list1.length; i++) { if (list1[i] >= list2[i]) { return false; } } return true; }
-
The method to swap array elements works because, unlike integers, arrays are objects and use reference semantics. This means that changes to an array parameter's elements will be seen in the original array by the caller.
-
Output of
ReferenceMystery1
program:2 [0, 0, 1, 0] 1 [0, 0, 1, 0] 3 [0, 0, 1, 1] 2 [0, 0, 1, 1]
-
Output of
ReferenceMystery2
program:2 [0, 1] 1 [0, 1] 1 [1, 2] 0 [1, 2]
-
public static void swapPairs(int[] list) { for (int i = 0; i < list.length - 1; i += 2) { swap(list, i, i + 1); } }
-
After the code is executed, the
numbers
array contains the following element values:[20, 30, 40, 50, 60, 70, 80, 90, 100, 100]
-
After the code is executed, the
numbers
array contains the following element values:[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
-
After the
mystery
method is executed, the arrays contain the following element values:-
a1
:[26, 19, 14, 11, 10]
-
a2
:[1, 4, 9, 16, 25]
-
-
After the
mystery2
method is executed, the arrays contain the following element values:-
a1
:[1, 3, -3, 13, -4, -24, -6, -14]
-
a2
:[1, 1, 2, 3, 5, 8, 13, 21]
-
-
After the
mystery3
method is executed, the array contains the following element values:[7, 3, 1, 0, 8, 18, 5, -1, 5]
-
Results of calls to
mystery4
method:-
0
-
9
-
6
-
8
-
2
-
-
Final array contents after calls to
mystery5
method:-
[8]
-
[14, 8]
-
[7, 2, 3, 3, 1, 4]
-
[10, 9, 9, 6, 6]
-
[12, 12, 11, 11, 9, 8]
-
-
public static double averageLength(String[] strings) { int sum = 0; for (int i = 0; i < strings.length; i++) { sum += strings[i].length(); } return (double) sum / strings.length; }
-
public static boolean isPalindrome(String[] array) { for (int i = 0; i < array.length / 2; i++) { if (!array[i].equals(array[array.length - 1 - i])) { return false; } } return true; }
-
After the code is executed, the
numbers
array contains the following element values:[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5]]
-
Loop to initialize the third row of data to store the numbers 1 through 7:
for (int i = 0; i < 7; i++) { data[2][i] = i + 1; }
-
Code that constructs a two-dimensional array of integers with 5 rows and 10 columns, filled with a multiplication table:
int[][] table = new int[5][10]; for (int i = 0; i < 5; i++) { for (int j = 0; j < 10; j++) { table[i][j] = i * j; } }
-
Loop to copy the contents of second column into fifth column:
for (int i = 0; i < 6; i++) { matrix[i][4] = matrix[i][1]; }
-
After the
mystery2d
method is executed, thenumbers
array contains the following element values:[[4, 5, 6, 6], [5, 6, 7, 7], [6, 7, 8, 8]]
-
int[][] jagged = new int[5][]; int value = 1; for (int i = 0; i < 5; i++) { jagged[i] = new int[i + 1]; for (int j = 0; j < i + 1; j++) { jagged[i][j] = value; value++; } }
- If the 2D array is named
pixels
, theDrawingPanel
's height is stored aspixels.length
and its width is stored aspixels[0].length
. -
public static void toRedChannel(DrawingPanel panel) { Color[][] pixels = panel.getPixels(); for (int row = 0; row < pixels.length; row++) { for (int col = 0; col < pixels[0].length; col++) { // your code goes here pixel = DrawingPanel.getRed(pixels[row][col]); } } panel.setPixels(pixels); }
- The panel will display a diagonal gradient of black to white, like the following image:
Chapter 8
-
Procedural programming treats a program as a sequence of actions or commands to perform. Object-oriented programming looks at a program as a group of interacting entities named objects that each keep track of related data and behavior.
-
An object is an entity that encapsulates data and behavior that operates on the data. A class is the blueprint for a type of object, specifying what data and behavior the object will have and how to construct it.
-
The state of a
String
object is its sequence of characters (which are actually stored internally as an array ofchar
values). AString
object's behavior includes its methods, such aslength
,substring
,toUpperCase
, andindexOf
. -
Output of
ReferenceMystery3
program:14 14 7 9 14 2 18 18 7 9 14 18
-
The state of a
Calculator
object might include the number that has just been computed, as well as another number that is currently being input. A more complexCalculator
object might also include a memory feature that stores an additional value. The behavior of aCalculator
object might include methods to add, subtract, multiply, divide, and perhaps carryout other math operations (such as exponentiation, logarithms, and trigonometric functions like sine and cosine). -
A field is a variable that exists inside of an object. A parameter is a variable inside a method whose value is passed in from outside. Fields have different syntax because they are usually declared with the
private
keyword and not in a method's header. A field's scope is throughout the class, while a parameter's scope is limited to the method. -
Name
class that represents a person's name:// A Name object represents a name such as "John Q. Public". public class Name { String firstName; char middleInitial; String lastName; }
-
An accessor provides the client access to some data in the object, while a mutator lets the client change the object's state in some way. Accessors' names often begin with "get" or "is", while mutators' names often begin with "set".
-
Correct syntax for calling
d.computeInterest
method on aBankAccount
object:double result = acct.computeInterest(42);
-
// Returns the distance from this point to the given other point. public double distance(Point other) { int dx = x - other.x; int dy = y - other.y; return Math.sqrt(dx * dx + dy * dy); }
-
Name
class with two methods:// A Name object represents a name such as "John Q. Public". public class Name { String firstName; char middleInitial; String lastName; // The name in normal order such as "John Q. Public". public String getNormalOrder() { return firstName + " " + middleInitial + ". " + lastName; } // The name in reverse order such as "Public, John Q.". public String getReverseOrder() { return lastName + ", " + firstName + " " + middleInitial + "."; } }
-
To make the objects of your class printable, define a
toString
method in it. -
The
c.println
statement is equivalent to the following:System.out.println(p1.toString());
-
toString
method forPoint
class:// Returns a String representation of this point, such as "java.awt.Point[x=7,y=2]". public String toString() { return "java.awt.Point[x=" + x + ", y=" + y + "]"; }
-
toString
method forName
class:// Returns a String representation of this Name, such as "John Q. Public". public String toString() { return firstName + " " + middleInitial + ". " + lastName; }
or:// Returns a String representation of this Name, such as "John Q. Public". public String toString() { return getNormalOrder(); }
-
Finished version of client code:
// construct two Point objects, one at (8, 2) and one at (4, 3) Point p1 = new Point(8, 2); Point p2 = new Point(4, 3); // display the two Point objects' state System.out.println("p1 is " + p1); System.out.println("p2 is " + p2); // display p1 distance from origin System.out.println("p1's distance from origin is " + p1.distanceFromOrigin()); // translate p1 to (9, 4) // translate p2 to (3, 13) p1.translate(1, 2); p2.translate(-1, 10); // display the two Point objects' state again System.out.println("p1 is now " + p1); System.out.println("p2 is now " + p2);
-
A constructor is a special method that creates an object and initializes its state. It's the method that is called when you use the
new
keyword. A constructor is declared without a return type. -
Two errors with the
Point
constructor:- The constructor shouldn't have the
void
keyword in its header, because constructors have no return type. The header should be:public Point(int x, int y) {
- The fields
x
andy
shouldn't have their types redeclared in front of them. This bug causes shadowing of the fields. Here are the corrected lines:x = initialX; y = initialY;
- The constructor shouldn't have the
-
Constructor for
Name
class:// A Name object represents a name such as "John Q. Public". public class Name { String firstName; char middleInitial; String lastName; // Initializes a new Name with the given values. public Name(String initialFirst, char initialMiddle, String initialLast) { firstName = initialFirst; middleInitial = initialMiddle; lastName = initialLast; } // The name in normal order such as "John Q. Public". public String getNormalOrder() { return firstName + " " + middleInitial + ". " + lastName; } // The name in reverse order such as "Public, John Q.". public String getReverseOrder() { return lastName + ", " + firstName + " " + middleInitial + "."; } }
-
The keyword
this
refers to the object on which a method or constructor has been called (sometimes called the "implicit parameter"). It is used to access or set the object's field values, to call the object's methods, or to call one constructor from another. -
Constructor for
Point
class that copies another point:// Constructs a Point object with the same x and y // coordinates as the given Point. public Point(Point p) { this.x = p.x; this.y = p.y; }
or:// Constructs a Point object with the same x and y // coordinates as the given Point. public Point(Point p) { this(p.x, p.y); // call the (int, int) constructor }
-
Abstraction is the ability to focus on a problem at a high level without worrying about the minor details. Objects provide abstraction by giving us more powerful pieces of data that have sophisticated behavior without having to manage and manipulate the data directly.
-
Items declared
public
may be seen and used from any class. Items declaredprivate
may be seen and used only from within their own classes. Objects' fields should be declaredprivate
to provide encapsulation, so that external code can't make unwanted direct modifications to the fields' values. -
To access private fields, create accessor methods that return their values. For example, add a
getName
method to access thename
field of an object. -
Adding
setX
andsetY
methods to thePoint
class:// Sets this Point's x coordinate to the given value. public void setX(int newX) { x = newX; } // Sets this Point's y coordinate to the given value. public void setY(int newY) { y = newY; }
-
Encapsulated version of
Name
class:// A Name object represents a name such as "John Q. Public". public class Name { private String firstName; private char middleInitial; private String lastName; // Initializes a new Name with the given values. public Name(String initialFirst, char initialMiddle, String initialLast) { firstName = initialFirst; middleInitial = initialMiddle; lastName = initialLast; } // Returns the person's first name. public String getFirstName() { return firstName; } // Returns the person's middle initial. public char getMiddleInitial() { return middleInitial; } // Returns the person's last name. public String getLastName() { return lastName; } // The name in normal order such as "John Q. Public". public String getNormalOrder() { return firstName + " " + middleInitial + ". " + lastName; } // The name in reverse order such as "Public, John Q.". public String getReverseOrder() { return lastName + ", " + firstName + " " + middleInitial + "."; } }
-
Mutator methods for
Name
class:// Sets the first name to the given value. public void setFirstName(String firstName) { this.firstName = firstName; } // Sets the last name to the given value. public void setLastName(String lastName) { this.lastName = lastName; } // Sets the middle initial to the given value. public void setMiddleInitial(char middleInitial) { this.middleInitial = middleInitial; }
-
Encapsulation allows you to change a class's internal implementation without changing its external view to clients. When a class is encapsulated clients cannot directly access its fields, so changing those fields will not disturb client behavior as long as the external view (method behavior) is consistent.
-
Cohesion is the concept of how well a class's contents go together. You can tell that a class is cohesive when each of its fields stores important state related to the object and each method interacts with that state in some way to produce useful behavior.
-
We did not place console I/O code into our
Stock
class because doing so would force clients to use those exact I/O messages. By keeping I/O code out ofStock
, we kept it independent from its clients. -
Accessor methods for
Stock
class:// Returns this Stock's symbol value. public String getSymbol() { return symbol; } // Returns this Stock's total number of shares purchased. public int getTotalShares() { return totalShares; } // Returns this Stock's total cost for all shares. public double getTotalCost() { return totalCost; }
Chapter 9
-
Code reuse is the practice of writing a single piece of code and using it many times in different programs and contexts. Inheritance is useful for code reuse because it allows you to write a class that captures common useful code and then extend that class to add more features and behavior to it.
-
Overloading a method involves creating two methods in the same class that have the same name but different parameters. Overriding a method involves creating a new version of an inherited method in a subclass, with identical parameters but new behavior to replace the old.
-
Correct syntax to indicate that class
a.A
is a subclass ofB
:public class A extends B {
-
The following statements are marked as legal or illegal:
-
Vehicle v = new Car(); // legal
-
Vehicle v = new SUV(); // legal
-
Car c = new SUV(); // legal
-
SUV s = new SUV(); // legal
-
SUV s = new Car(); // illegal
-
Car c = new Vehicle(); // illegal
-
-
The
this
keyword refers to the current object, while thesuper
keyword refers to the current class's superclass. Use thesuper
keyword when calling a method or constructor from the superclass that you've overridden, and use thethis
keyword when accessing your object's own fields, constructors, and methods. -
UndergraduateStudent
can call thesetAge
method but cannot directly access thename
orage
fields fromStudent
. -
public UndergraduateStudent(String name) { super(name, 18); year = 0; }
-
public void setAge(int age) { super.setAge(age); year++; }
-
Output from the
Car
/Truck
statements:vroom car 1 car 2 vroom truck 1 car 2
-
Output from the
Car
/Truck
statements, version 2:vroomvroom truck 1 car 1
-
Output from
A
/B
/C
/D
polymorphism code:B 2 A A 1 D 2 C C 1 A 2 A A 1 A 2 C C 1
-
Output from
Flute
/Blue
/Shoe
/Moo
polymorphism code:flute shoe 1 flute 2 flute blue 1 flute 2 moo moo 1 moo 2 moo blue 1 moo 2
-
Output from
Flute
/Blue
/Shoe
/Moo
polymorphism code, version 2:moo 2 blue 1 moo moo 2 moo 1 moo flute 2 shoe 1 flute flute 2 blue 1 flute
-
Output from
Mammal
/SeaCreature
/Whale
/Squid
polymorphism code:squid creature 1 tentacles BIG! spout creature 2 ocean-dwelling creature 1 creature 2 ocean-dwelling warm-blooded creature 2
-
Output from
Mammal
/SeaCreature
/Whale
/Squid
polymorphism code, version 2:creature 2 ocean-dwelling creature 1 tentacles squid creature 1 creature 2 ocean-dwelling warm-blooded creature 2 BIG! spout
-
Output from
Bay
/Pond
/Ocean
/Lake
polymorphism code:Bay 1 Pond 2 Ocean 2 Lake 3 Ocean 2 Pond 1 Pond 2 Pond 3 Pond 1 Pond 2 Lake 3 Pond 2 Bay 1 Pond 2 Bay 2 Lake 3 Bay 2
-
None of the statements produce errors. Output from
Bay
/Pond
/Ocean
/Lake
polymorphism code, version 2:Bay 1 Pond 2 Bay 1 Pond 2 Ocean 2 Ocean 2 Lake 3 Ocean 2
-
An is-a relationship is a subclass relationship such as those created by inheritance. A has-a relationship is when one object contains a reference to another as a field.
-
Having
Square
extendRectangle
is a poor design because aSquare
cannot substitute for aRectangle
. If the client thinks theSquare
is aRectangle
and callssetWidth
orsetHeight
on it, unexpected results will occur. The client will expect the width and height to be different after the call, but they may not be. -
Having each of the 52 playing cards in its own class is not a good design because it will result in a clutter of code files without significant differences between them. A better design would have one
Card
class with fields for rank and suit. -
We made
DividendStock
a separate subclass fromStock
for two major reasons. First, not all stocks pay dividends, so it does not make sense for everyStock
object to have adividends
field and apayDividend
method. Second, theStock
code already worked correctly, so we did not want to tamper with it needlessly. MakingDividendStock
a separate class constituted an additive and noninvasive change. -
Extending a class causes your class to inherit all methods and data from that class. Implementing an interface forces you to write your own code to implement all the methods in that interface.
-
The code for class
C
must contain implementations of the methodsm1
andm2
to compile correctly, becauseC
claims to implement theI
interface. -
What's wrong is that interfaces can't declare fields or write bodies for methods. The following is a correct
Colored
interface:import java.awt.*; // Represents items that have a color that can be retrieved. public interface Colored { public Color getColor(); }
-
Extension of
Point
class that implements theColored
interface:// Represents a point with a color. import java.awt.*; public class ColoredPoint extends Point implements Colored { private Color color; // Constructs a new colored point with the given // coordinates and color. public ColoredPoint(int x, int y, Color color) { super(x, y); this.color = color; } // Returns this point's color. public Color getColor() { return color; } }
-
Version of
Shape
interface withgetSideCount
method:// A general interface for shape classes. public interface Shape { public double getArea(); public double getPerimeter(); public int getSideCount(); }
The following are the implementations of the method in the
Circle
,Rectangle
, andTriangle
classes:// Returns the number of sides a circle has (0). public int getSideCount() { return 0; } // Returns the number of sides a rectangle has (4). public int getSideCount() { return 4; } // Returns the number of sides a triangle has (3). public int getSideCount() { return 3; }
-
An abstract class is a class intended to be used only as a superclass for inheritance. It's like a normal class in that it can have fields, methods, constructors, and so on. It's different from a normal class in that it can have abstract methods, which are like methods of an interface because only their headers are given, not their bodies. It's also different from a normal class because it can't be instantiated (used to create objects).
-
You can be sure that the
OrderedByLength
class contains agetElement
method and that it implements thearrange
method, because if it extendsOrdered
without beingabstract
itself, it must have that method in order to compile. -
One good design would be to have an abstract superclass named
Movie
with data such as name, director, and date. There would be subclasses ofMovie
to represent particular movie types, such asDrama
,Comedy
, andDocumentary
. Each subclass would store its specific data and behavior.
Chapter 10
-
An
ArrayList
is a structure that stores a collection of objects inside itself as elements. Each element is associated with an integer index starting from 0. You should use anArrayList
instead of an array if you don't know how many elements you'll need in advance, or if you plan to add items to or remove items from the middle of your dataset. -
Correct syntax to construct an
e.ArrayList
to store integers:ArrayList<Integer> list = new ArrayList<Integer>();
-
Code to declare an
ArrayList
containing["It", "was", "a", "stormy", "night"]
:ArrayList<String> list = new ArrayList<String>(); list.add("It"); list.add("was"); list.add("a"); list.add("stormy"); list.add("night");
The list's type is
ArrayList<String>
and its size is 5. -
Code to insert two additional elements,
"dark"
and"and"
, at the proper places:list.add(3, "dark"); list.add(4, "and");
-
Code to change the second element's value to
"IS"
:list.set(1, "IS");
-
Code to remove from the list any strings that contain the letter
"a"
:for (int i = 0; i < list.size(); i++) { if (list.get(i).indexOf("a") >= 0) { list.remove(i); i--; // so the new element i will be checked } }
-
Code to declare an
ArrayList
holding the first 10 multiples of 2:ArrayList<Integer> numbers = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { numbers.add(2 * i); }
-
public static int maxLength(ArrayList<String> list) { int max = 0; for (int i = 0; i < list.size(); i++) { String s = list.get(i); if (s.length() > max) { max = s.length(); } } return max; }
-
Code to print out whether or not a list of
String
s contains the value"IS"
, without using a loop:System.out.println(list.contains("IS"));
-
Code to print out the index at which the list contains the value
"stormy"
and the index at which it contains"dark"
:System.out.println(list.indexOf("stormy")); System.out.println(list.indexOf("dark"));
-
A for-each loop that prints the uppercase version of each
String
in the list on its own line:for (String s : list) { System.out.println(s.toUpperCase()); }
-
The code throws a
ConcurrentModificationException
because it is illegal to modify the elements of anArrayList
while for-each looping over it. -
The code doesn't compile because primitives cannot be specified as type parameters for generic types. The solution is to use the "wrapper" type
Integer
instead ofint
. Change the line declaring theArrayList
to the following:ArrayList<Integer> numbers = new ArrayList<Integer>();
-
A wrapper class is one whose main purpose is to act as a bridge between primitive values and objects. An
Integer
is an object that holds anint
value. Wrappers are useful in that they allow primitive values to be stored into collections. -
Output produced when the
mystery1
method is passed each list:-
[1, 2, 6, 8]
-
[10, 30, 40, 20, 60, 50]
-
[-4, 1, 25, 4, 16, 9, 64, 36, 49]
-
-
Output produced when the
mystery2
method is passed each list:-
[20, 10, 20, 30, 30, 20]
-
[8, 7, 8, 2, 9, 7, 4, 4, 2, 8]
-
[33, 28, 33, -1, 3, 28, 17, 9, 33, 17, -1, 33]
-
-
Output produced when the
mystery3
method is passed each list:-
[72, 20]
-
[1, 20, 18, 15, 11, 6]
-
[10, 90, 70, 40]
-
-
Output produced when the
mystery4
method is passed each list:-
[31, 21, 11]
-
[5, 8, 10, 3, 9]
-
[34, 10, 18, 29, 4, 0]
-
-
To arrange an
ArrayList
into sorted order, call theCollections.sort
method on it. For example, if yourArrayList
is stored in a variable namedlist
, you would call:Collections.sort(list);
For this to work, the type of the objects stored in the list must be
Comparable
. -
A natural ordering is an order for objects of a class where "lesser" objects come before "greater" ones, as determined by a procedure called the class's comparison function. To give your own class a natural ordering, declare it to implement the
Comparable
interface and define a comparison function for it by writing an appropriatecompareTo
method. -
-
n1.compareTo(n2) > 0
-
n3.compareTo(n1) == 0
-
n2.compareTo(n1) < 0
-
s1.compareTo(s2) < 0
-
s3.compareTo(s1) > 0
-
s2.compareTo(s2) == 0
-
-
Code that reads two names from the console and prints the one that comes first in alphabetical order:
Scanner console = new Scanner(System.in); System.out.print("Type a name: "); String name1 = console.nextLine(); System.out.print("Type a name: "); String name2 = console.nextLine(); if (name1.compareTo(name2) < 0) { System.out.println(name1 + " goes before " + name2); } else if (name1.compareTo(name2) > 0) { System.out.println(name1 + " goes after " + name2); } else { // equal System.out.println(name1 + " is the same as " + name2); }
-
Code to read a line of input from the user and print the words of that line in sorted order:
Scanner console = new Scanner(System.in); System.out.print("Type a message to sort: "); String message = console.nextLine(); ArrayList<String> words = new ArrayList<String>(); Scanner lineScan = new Scanner(message); while (lineScan.hasNext()) { words.add(lineScan.next()); } System.out.print("Your message sorted: "); Collections.sort(words); for (String word : words) { System.out.print(word + " "); } System.out.println(); // to end the line of output
Chapter 11
-
You should use a
LinkedList
when you plan to add or remove many values at the front or back of the list, or when you plan to make many filtering passes over the list in which you remove certain elements. -
The code shown would perform better with an
ArrayList
, because it calls theget
method many times using indexes in the middle and end of the list. This is a slow operation for aLinkedList
. -
An iterator is an object that represents a position within a list and enables you to view or make changes to the elements at that position. Iterators are often used with linked lists because they retain the position in the list, so you don't have to call expensive list methods like
get
,add
, orremove
many times on the middle or end of the list. -
public static int countDuplicates(LinkedList<Integer> list) { int count = 0; Iterator<Integer> i = list.iterator(); int prev = i.next(); while (i.hasNext()) { int next = i.next(); if (prev == next) { count++; } prev = next; } return count; }
-
public static void insertInOrder(LinkedList<String> list, String value) { int index = 0; Iterator<String> i = list.iterator(); String next = i.next(); // advance until the proper index while (i.hasNext() && next.compareTo(value) < 0) { next = i.next(); index++; } list.add(index, value); }
-
public static void removeAll(LinkedList<Integer> list, int value) { Iterator<Integer> i = list.iterator(); while (i.hasNext()) { if (i.next() == value) { i.remove(); } } }
-
public static void wrapHalf(LinkedList<Integer> list) { int halfSize = (list.size() + 1) / 2; for (int i = 0; i < halfSize; i++) { // wrap around one element int element = list.remove(list.size() - 1); list.add(0, element); } }
-
An abstract data type defines the type of data a collection can hold and the operations it can perform on that data. Linked lists implement the
List
abstract data type. -
public static int countDuplicates(List<Integer> list) { int count = 0; Iterator<Integer> i = list.iterator(); int prev = i.next(); while (i.hasNext()) { int next = i.next(); if (prev == next) { count++; } prev = next; } return count; }
-
You should use a
Set
rather than aList
if you wanted to avoid duplicates or wanted to be able to search the collection quickly. -
You should use a
TreeSet
when you want to keep the data in sorted natural order. You should useHashSet
s with non-Comparable
types or when order doesn't matter, to get the fastest searching time. -
You can examine every element of a
Set
using an iterator or a for-each loop. -
After the code executes, the set contains the following elements (in some order):
[32, 90, 9, 182, 29, 12]
-
To do a union, use the
addAll
method to add one set's contents to the other. To do an intersection, use theretainAll
method to remove elements not common to both sets. - Output produced when the
mystery
method is passed each list:-
[amanda, helene, jessica]
-
[riley]
-
[alex, charlie, phil, roy, tyler]
-
-
Code to declare a
Map
that associates people's names with their ages:Map<String, Integer> ageMap = new TreeMap<String, Integer>(); ageMap.put("Stuart", 85); ageMap.put("Marty", 12); ageMap.put("Amanda", 25);
-
You can examine every key of a
Map
by calling thekeySet
method and then iterating or for-eaching over thekeySet
. You can examine every value of aMap
by calling thevalues
method and then iterating or for-eaching over that collection of values, or by looking up each associated value using the keys from thekeySet
. -
Keys and values contained in the map after the code executes:
{79=Seventy-nine, 8=Ocho, 132=OneThreeTwo, 50=Fifty, 98=Ninety-eight, 86=Eighty-six}
- Output produced when the
mystery
method is passed each map:-
{cinq=five, deux=two, four=quatre, one=un, three=trois}
-
{board=skate, car=drive, computer=play}
-
{begin=end, boy=girl, ebert=siskel, first=last, heads=tails}
-
{cotton=rain, light=tree, seed=tree, tree=violin}
-
- Output produced when the
mystery
method is passed each map:-
{brick, plaster}
-
{blue, green, yellow}
-
{fruit}
-
{animal, cat, dog, ipl}
-
- Result returned when the
mystery
method is passed each pair of maps:-
{bar=earth, baz=wind, foo=air, mumble=fire}
-
{five=quatro, one=dos, three=tres}
-
{b=years, c=seven, e=ago, g=seven}
-
-
The following method implements the new behavior in the
WordCount
program:public static void reverseMap(Map<String, Integer> wordCountMap) { Map<Integer, String> reverseMap = new TreeMap<Integer, String>(); // reverse the original map for (String word : wordCountMap.keySet()) { int count = wordCountMap.get(word); if (count > OCCURRENCES) { reverseMap.put(count, word); } } // print the words sorted by count for (int count : reverseMap.keySet()) { String word = reverseMap.get(count); } }
Chapter 12
-
Recursion is a technique where an algorithm is expressed in terms of itself. A recursive method differs from a regular method in that it contains one or more calls to itself within its body.
-
A base case is a situation where a recursive method does not need to make a recursive call to solve the problem. A recursive case is a situation where the recursive method does call itself. Recursive methods need both cases because the recursive case is called repeatedly until the base case is reached, stopping the chain of recursive calls.
-
Output produced by the
mystery1
method by each call:-
1
-
1, 2
-
1, 3
-
1, 2, 4
-
1, 2, 4, 8, 16
-
1, 3, 7, 15, 30
-
1, 3, 6, 12, 25, 50, 100
-
-
Output produced by the
mystery2
method by each call:-
113
-
140, 70
-
168, 84, 42
-
120, 60, 30
-
160, 80, 40, 20, 10
-
-
Output produced by the
mystery3
method by each call:-
*
-
[*]
-
([*])
-
([([*])])
-
[([([*])])]
-
-
Output produced by the
mysteryXY
method by each call:-
4
-
8, 4, 8
-
16, 8, 16
-
12, 8, 4, 8, 12
-
12, 9, 6, 3, 6, 9, 12
-
-
Recursive version of
doubleReverse
method:public static void doubleReverse(String s) { if (s.length() > 0) { char last = s.charAt(s.length() - 1); System.out.print(last); System.out.print(last); doubleReverse(s.substring(0, s.length() - 1)); } }
-
A call stack is the structure of information about all methods that have currently been called by your program. Recursion produces a tall call stack in which each recursive call is represented.
-
The new code shown would print the lines in their original order, not reversed.
-
The new code shown would cause infinite recursion, because each recursive call just makes another recursive call and doesn't progress toward the base case.
-
The version of the
pow
method shown does not have any base case, so the recursive calls will never stop. It can be fixed by adding a check fory == 0
that does not make a recursive call. -
The second version of the
pow
method is more efficient than the first because it requires fewer recursive calls. Both versions are recursive. -
Value returned by the
mystery4
method for each call:-
6
-
4
-
7
-
0
-
1
-
-
Value returned by the
mystery5
method for each call:-
57
-
1029
-
-74
-
2438
-
132483
-
-
Value returned by the
mystery6
method for each call:-
7
-
6
-
4
-
10
-
5
-
-
Recursive version of
factorial
method:public static int factorial(int n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } }
-
The base case
if
statement has a bug: It should test for numbers less than 10, not greater. The following is the correct line:if (n < 10) {
-
When the parameters needed for recursion don't match those that make sense for the client to pass, use a public method with the signature desired by the client and a private helper method with the signature needed for the recursion.
-
The following version of the
fibonacci
code has improved efficiency:public static int fibonacci(int n) { if (n <= 2) { return 1; } else { return fibonacci(n, 3, 1, 1); } } private static int fibonacci(int n, int i, int prev, int curr) { if (n == i) { return prev + curr; } else { return fibonacci(n, i + 1, curr, prev + curr); } }
-
A fractal is an image that is recursively constructed to contain smaller versions of itself. Recursive methods are useful when drawing fractal images because they can elegantly express the recursive nature of the images.
-
Code to create and draw a regular hexagon:
public static void drawHexagon(Graphics g, Point position, int size) { Polygon poly = new Polygon(); poly.addPoint(position.x, position.y + size / 2); poly.addPoint(position.x + size / 3, position.y); poly.addPoint(position.x + 2 * size / 3, position.y); poly.addPoint(position.x + size, position.y + size / 2); poly.addPoint(position.x + 2 * size / 3, position.y + size); poly.addPoint(position.x + size / 3, position.y + size); g.drawPolygon(poly); }
-
Recursion is an effective way to implement a backtracking algorithm because the memory of decisions and points to go back to are represented by the recursive call stack. The pattern of "choose, explore, un-choose is elegantly represented by recursive calls for each individual choice.
-
A decision tree is a description of the set of choices that can be made by a recursive backtracking method at any point in the algorithm.
-
Decision tree that would have resulted for Figure 12.9 for paths to (1, 2) if the backtracking solution had explored NE first instead of last in the recursive
explore
method:start (0, 0) | +--- NE (1, 1) | | | +--- NE NE (2, 2) | | | +--- NE N (1, 2) - output | | | +--- NE E (2, 1) | +--- N (0, 1) | | | +--- N NE (1, 2) - output | | | +--- N N (0, 2) | | | | | +--- N N NE (1, 3) | | | | | +--- N N N (0, 3) | | | | | +--- N N E (1, 2) - output | | | +--- N E (1, 1) | | | +--- N E NE (2, 2) | | | +--- N E N (1, 2) - output | | | +--- N E E (2, 1) | +--- E (1, 0) | +--- E NE (2, 1) | +--- E N (1, 1) | | | +--- E N NE (2, 2) | | | +--- E N N (1, 2) - output | | | +--- E N E (2, 1) | +--- E E (2, 0)
-
If the solution had explored NE first instead of last, the solutions would have been printed in this order:
moves: NE N moves: N NE moves: N N E moves: N E N moves: E N N
-
There are 64 entries at the second level of the full tree. There are 512 entries at the third level of the full tree.
-
If our 8 Queens algorithm tried every possible square on the board for placing each queen, there would be (64*63*62*61*60*59*58*57) = 178,462,987,637,760 entries are there at the 8th and final level of the full tree. Our algorithm avoids such a huge number of choices by only placing one queen in each column of the board.
-
The 8 Queens
explore
method stops once it finds one solution to the problem. This is because the code has the following lines around its recursive call:if (explore(b, col + 1)) { return true; }
The code could be modified so that it would find and output every solution to the problem by changing that code to the following:
explore(b, col + 1);
And changing the base case to the following:
if (col > b.size()) { System.out.println("One solution is as follows:"); b.print(); return true; }
Chapter 13
-
You can perform a sequential search over the array using a loop, or you can sort the array using
Arrays.sort
and then perform a binary search over it usingArrays.binarySearch
. -
Closest value to the number of elements that the binary search algorithm will need to examineon an array of one million integers:
e. less than 1% (10,000 or fewer) -
A sequential search must be used on an array of
Point
objects because they do not implementComparable
. -
Arrays.binarySearch
andCollections.binarySearch
can be used successfully if the array or collection contains elements that are sorted, according to either their natural ordering or the ordering of aComparator
. -
Collections.sort
on a list of strings would arrange them in alphabetical order, case-sensitive. To change the order, you could pass aComparator
that defines a different order. -
Collections.sort
would not work on a list ofPoint
objects by default because they do not implement theComparable
interface. To make it work, you could pass aComparator
that defines an ordering forPoint
s. -
The
AccountComparator
shown has a few errors:- line 2: It should implement Comparator
rather than just Comparator
. - line 3: The method should be named
compare
, notcompareTo
. It should also accept twoBankAccount
parameters, not just one. - lines 5,7: The code should refer to the two parameters passed in, not
this
. - line 7: You cannot return the subtraction of two
double
s from acompare
method. The result must be of typeint
, and it must still work even if the accounts differ only by a few cents.
import java.util.*; public class AccountComparator extends Comparator<BankAccount> { public int compare(BankAccount account1, BankAccount account2) { if (!account1.getName().equals(account2.getName())) { return account1.getName().compareTo(account2.getName()); } else if (account1.getBalance() < account2.getBalance()) { return -1; } else if (account1.getBalance() > account2.getBalance()) { return 1; } else { return 0; } } }
- line 2: It should implement Comparator
-
We could easily reverse the order of our
LengthComparator
by using the built-in methodCollections.reverseOrder
, which accepts aComparator
and returns a new one with the opposite order of the one passed in. -
O(log N)
-
O(N)
-
O(N2)
-
O(N2)
-
O(N)
-
Complexity classes of the given algorithms in terms of N:
- O(N)
- O(N2)
- O(N)
- O(N)
- O(log B)
- O(N3)
- O(N)
- O(N)
-
Complexity classes of the given statements:
- O(N log N)
- O(N2)
- O(N2 log N)
- O(N)
- O(1)
- O(N)
- O(N!)
-
The runtime complexity of both sequential searches is O(N).
-
Binary search requires a sorted dataset because it uses the ordering to jump to the next index. If the elements are out of order, the search isn't guaranteed to find the target element.
-
A binary search of 60 elements examines at most 6 elements, because log2 60 (when rounded up) equals 6.
-
- The algorithm will examine index 4 and will return 4.
- The algorithm will examine indexes 4 and 6 and will return 6.
- The algorithm will examine indexes 4, 6, and 7 and will return 7.
- The algorithm will examine indexes 4, 2, 1, and 0 and will return 0.
-
The algorithm will examine indexes 4, 6, and 5 and will return -1. The algorithm doesn't work properly because the input array isn't sorted.
-
The binary search algorithm will examine the following indexes and return the following values for each search:
- 42: examines 7, 11, 9; returns 9
- 11: examines 7, 3, 4; returns -5
- 74: examines 7, 11, 13, 14; returns 14
- 30: examines 7, 3, 5, 6; returns -8
-
The binary search algorithm will examine the following indexes and return the following values for each search:
- -5: examines 6, 2, 4, 3; returns -4
- 0: examines 6; returns 6
- 11: examines 6, 10, 8, 9; returns -10
- -100: examines 6, 2, 0; returns -1
-
The parameter array type should be changed to
double
. Also, a newswap
method will be needed that accepts adouble[]
as the first parameter. Here's the new code:public static void selectionSort(double[] a) { for (int i = 0; i < a.length - 1; i++) { // find index of smallest element int smallest = i; for (int j = i + 1; j < a.length; j++) { if (a[j] < a[smallest]) { smallest = j; } } swap(a, i, smallest); // swap smallest to front } }
-
After a single pass of the selection sort algorithm (a single swap), the state of the array is:
d.[-4, 17, 3, 94, 46, 8, 29, 12]
-
All steps of selection sort algorithm:
-
[29, 17, 3, 94, 46, 8, -4, 12] [-4, 17, 3, 94, 46, 8, 29, 12] [-4, 3, 17, 94, 46, 8, 29, 12] [-4, 3, 8, 94, 46, 17, 29, 12] [-4, 3, 8, 12, 46, 17, 29, 94] [-4, 3, 8, 12, 17, 46, 29, 94] [-4, 3, 8, 12, 17, 29, 46, 94]
-
[33, 14, 3, 95, 47, 9, -42, 13] [-42, 14, 3, 95, 47, 9, 33, 13] [-42, 3, 14, 95, 47, 9, 33, 13] [-42, 3, 9, 95, 47, 14, 33, 13] [-42, 3, 9, 13, 47, 14, 33, 95] [-42, 3, 9, 13, 14, 47, 33, 95] [-42, 3, 9, 13, 14, 33, 47, 95]
-
[7, 1, 6, 12, -3, 8, 4, 21, 2, 30, -1, 9] [-3, 1, 6, 12, 7, 8, 4, 21, 2, 30, -1, 9] [-3, -1, 6, 12, 7, 8, 4, 21, 2, 30, 1, 9] [-3, -1, 1, 12, 7, 8, 4, 21, 2, 30, 6, 9] [-3, -1, 1, 2, 7, 8, 4, 21, 12, 30, 6, 9] [-3, -1, 1, 2, 4, 8, 7, 21, 12, 30, 6, 9] [-3, -1, 1, 2, 4, 6, 7, 21, 12, 30, 8, 9] [-3, -1, 1, 2, 4, 6, 7, 21, 12, 30, 8, 9] [-3, -1, 1, 2, 4, 6, 7, 8, 12, 30, 21, 9] [-3, -1, 1, 2, 4, 6, 7, 8, 9, 30, 21, 12] [-3, -1, 1, 2, 4, 6, 7, 8, 9, 12, 21, 30]
-
[6, 7, 4, 8, 11, 1, 10, 3, 5, 9] [1, 7, 4, 8, 11, 6, 10, 3, 5, 9] [1, 3, 4, 8, 11, 6, 10, 7, 5, 9] [1, 3, 4, 8, 11, 6, 10, 7, 5, 9] [1, 3, 4, 5, 11, 6, 10, 7, 8, 9] [1, 3, 4, 5, 6, 11, 10, 7, 8, 9] [1, 3, 4, 5, 6, 7, 10, 11, 8, 9] [1, 3, 4, 5, 6, 7, 8, 11, 10, 9] [1, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-
-
A merge sort of 32 elements will generate 63 total calls to
mergeSort
and will perform themerge
operation 31 times. -
-
State of the elements after five passes of the outermost loop of selection sort have occurred:
[1, 2, 3, 4, 5, 11, 9, 7, 8, 10]
-
Trace of merge sort algorithm:
[7, 2, 8, 4, 1, 11, 9, 5, 3, 10] [7, 2, 8, 4, 1], [11, 9, 5, 3, 10] [7, 2], [8, 4, 1], [11, 9], [5, 3, 10] [7], [2], [8], [4, 1], [11], [9], [5], [3, 10] [4], [1], [3], [10] [8], [1, 4], [5], [3, 10] [2, 7], [1, 4, 8], [9, 11], [3, 5, 10] [1, 2, 4, 7, 8], [3, 5, 9, 10, 11] [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]
-
-
-
State of the elements after five passes of the outermost loop of selection sort have occurred:
[-3, -1, 1, 2, 4, 8, 7, 21, 12, 30, 6, 9]
-
Trace of merge sort algorithm:
[7, 1, 6, 12, -3, 8, 4, 21, 2, 30, -1, 9] [7, 1, 6, 12, -3, 8], [4, 21, 2, 30, -1, 9] [7, 1, 6], [12, -3, 8], [4, 21, 2], [30, -1, 9] [7], [1, 6], [12], [-3, 8], [4], [21, 2], [30], [-1, 9] [1], [6], [-3], [8], [21], [2], [-1], [9] [7], [1, 6], [12], [-3, 8], [4], [2, 21], [30], [-1, 9] [1, 6, 7], [-3, 8, 12], [2, 4, 21], [-1, 9, 30] [-3, 1, 6, 7, 8, 12], [-1, 2, 4, 9, 21, 30] [-3, -1, 1, 2, 4, 6, 7, 8, 9, 12, 21, 30]
-
-
The following statement about sorting and big-Oh is true:
b. Merge sort achieves an O(N log N) runtime by dividing the array in half at each step and then recursively sorting and merging the halves back together. -
Traces of merge sort algorithm:
-
[29, 17, 3, 94, 46, 8, -4, 12] [29, 17, 3, 94], [46, 8, -4, 12] [29, 17], [3, 94], [46, 8], [-4, 12] [29], [17], [3], [94], [46], [8], [-4], [12] [17, 29], [3, 94], [8, 46], [-4, 12] [3, 17, 29, 94], [-4, 8, 12, 46] [-4, 3, 8, 12, 17, 29, 46, 94]
-
[6, 5, 3, 7, 1, 8, 4, 2] [6, 5, 3, 7], [1, 8, 4, 2] [6, 5], [3, 7], [1, 8], [4, 2] [6], [5], [3], [7], [1], [8], [4], [2] [5, 6], [3, 7], [1, 8], [2, 4] [3, 5, 6, 7], [1, 2, 4, 8] [1, 2, 3, 4, 5, 6, 7, 8]
-
[33, 14, 3, 95, 47, 9, -42, 13] [33, 14, 3, 95], [47, 9, -42, 13] [33, 14], [3, 95], [47, 9], [-42, 13] [33], [14], [3], [95], [47], [9], [-42], [13] [14, 33], [3, 95], [9, 47], [-42, 13] [14, 33], [3, 95], [9, 47], [-42, 13] [3, 14, 33, 95], [-42, 9, 13, 47] [-42, 3, 9, 13, 14, 33, 47, 95]
Chapter 14
-
Statement that is true about stacks and queues:
c. A queue's remove method removes and returns the element at the front of the queue. -
A real-world example of data that could be modeled using a stack is the plates in a cafeteria, or the undo/redo feature of a software application. A real-world example of a queue is the waiting line at a fast-food restaurant.
-
When you push onto a stack, the new element is added to the top. When you pop from a stack, the top element is removed and returned.
-
When you add to a queue, the new element is added to the back. When you remove from a queue, the front element is removed and returned.
-
The value 3 will be returned from the stack.
-
The value 1 will be returned from the queue.
-
The problem with the code is that
Queue
is an interface, so it cannot be instantiated. Instead, construct aLinkedList
object:Queue<Integer> q = new LinkedList<Integer>();
-
Stack<String> stack = new Stack<String>(); stack.push("hello"); stack.push("hi"); stack.push("goodbye"); stack.push("howdy"); System.out.println(stack);
-
Stack<Integer> stack = new Stack<Integer>(); for (int i = 100; i >= 0; i -= 2) { stack.push(i); } System.out.println(stack);
-
Queue<String> queue = new LinkedList<String>(); queue.add("alpha"); queue.add("beta"); queue.add("gamma"); queue.add("delta"); System.out.println(queue);
-
To access elements in the middle of a stack or queue, you must remove/pop out elements until you reach the one you're looking for. In many cases, it's important to save the removed elements somewhere so that you can put them back into the stack or queue when you are done.
-
Stacks and queues are still useful despite their limited functionality because they are simple and easy to use, and because their operations are all efficient to execute. Many common operations are also naturally represented as a stack or queue.
-
The code produces the following output:
[you, are, how]
-
10 7 5 false 2 3 8 3
-
The code produces the following output:
2 10 10 4 6 6 3
-
Output produced by the
mystery1
method by each call:-
[1, 1, 6, 6, 2, 2]
-
[9, 9, 15, 15, 4, 4, -3, -3, 42, 42]
-
[40, 40, 50, 50, 60, 60, 10, 10, 20, 20, 30, 30]
-
-
Output produced by the
mystery2
method by each call:-
[1, 3, 5] [2, 4, 6]
-
[-3, 15, 9, 71] [42, 4]
-
[3] [30, 20, 10, 60, 50, 40, 0]
-
-
Output produced by the
mystery3
method by each call:-
[-1, -3, -5]
-
[-42, -4, -71]
-
[-10, -60, -50]
-
-
The problem with the code is that the size of the queue is changing while the loop goes over it. Another problem with the code is that it destroys the contents of the queue being examined. The following version of the code fixes both problems:
int sum = 0; Queue<Integer> backup = new LinkedList<Integer>(); int largest = q.remove(); int size = q.size(); for (int i = 0; i < size; i++) { int n = q.remove(); largest = Math.max(largest, n); backup.add(n); } while (!backup.isEmpty()) { q.add(backup.remove()); }
-
The problem with the code is that it calls the
remove
method twice on each element, which double-removes it and therefore skips elements. Another problem with the code is that it destroys the contents of the stack being examined. The following version of the code fixes both problems:int sum = 0; Queue<Integer> backup = new LinkedList<Integer>(); while (!q.isEmpty()) { int n = q.remove(); if (n > 0) { sum += n; } backup.add(n); } while (!backup.isEmpty()) { q.add(backup.remove()); }
-
The problem with the code is that it puts the odd elements back at the top of the stack each time, so it will never make progress down the stack toward the bottom. If the stack contains any odd elements, the code will get stuck in an infinite loop. The following version of the code fixes the problem:
Stack<Integer> backup = new Stack<Integer>(); while (!s.isEmpty()) { int n = s.pop(); if (n % 2 != 0) { backup.push(n); } } while (!backup.isEmpty()) { s.push(backup.pop()); }
-
public static void print(Queue<Integer> queue) { for (int i = 0; i < queue.size(); i++) { int n = queue.remove(); System.out.println(n); queue.add(n); } }
-
public static void printLongest(Stack<String> stack) { Stack<String> backup = new Stack<String>(); String longest = stack.pop(); backup.push(longest); while (!stack.isEmpty()) { String s = stack.pop(); if (s.length() > longest.length()) { longest = s; } backup.push(s); } while (!backup.isEmpty()) { // restore stack stack.push(backup.pop()); } System.out.println(longest); }
Chapter 15
-
An array list's size is the number of elements that have been added to it. Its capacity is the length of its internal array. The size is always less than or equal to the capacity.
-
The ArrayIntList class keeps at least two fields: an array of elements and a size. The array is necessary because it is where we store the data inside the collection. The size is necessary because some of the elements at the end of the array may not be meaningful values. If we removed the size field, we would not know how many elements were meaningful.
-
If the fields were static, all lists would share the same array and size. Any modification to one list would also be seen in all other lists. The client's output would be the following:
[1, 82, 97, 7, -8] [1, 82, 97, 7, -8]
-
In this section's version of the list class, if the client tries to add too many values, the code crashes with an out of bounds exception.
-
We use a
toString
method because this is the standard way of printing objects in Java. It is also more versatile than aprint
method because it can print the text representation of the list to any target, such as a file or GUI. -
Having accessor methods such as
size
is better than making the fields public because it preserves the encapsulation of the object. As discussed in Chapter 8, this improves the cleanliness of the abstraction of the object and would allow us to change the implementation later if so desired. -
It is most expensive to insert or remove at the beginning of the list, because all elements must be shifted to the right by one index.
-
public int min() { if (size == 0) { throw new IllegalStateException(); } int minValue = elementData[0]; for (int i = 1; i < size; i++) { minValue = Math.min(minValue, elementData[i]); } return minValue; } public int max() { if (size == 0) { throw new IllegalStateException(); } int maxValue = elementData[0]; for (int i = 1; i < size; i++) { maxValue = Math.max(maxValue, elementData[i]); } return maxValue; }
-
The preconditions are that the client will not try to construct a list with a negative capacity, and that the client will never pass an index that is negative or outside the size of the list.
-
The
checkIndex
method tests whether a given index is between 0 and the size of the list, and if not, throws an exception. If the client passes an invalid index by mistake, the method will halt the program's execution. -
The
checkCapacity
method tests whether the array's size will exceed the length of the internal array (capacity), and if so, throws an exception. If the client adds too many elements to the list, the method will halt the program's execution. -
With our preconditions, we may now assume that
size <= capacity
at all times. We can also assume all index parameters passed to various methods are valid once they get through thecheckIndex
test. -
These methods are provided as a convenience to the client, to give the list object a more simple and pleasant external interface to use.
-
The list doubles in size when it exceeds its capacity. This is done instead of resizing by a constant amount so that the overall cost of adding elements to the end of a list will be amortized to be O(1), constant time.
-
An iterator provides a standard way of examining the elements of a collection.
-
The iterator keeps track of the list to examine, the current index in the list, and whether it is safe to remove an element from the list using the iterator.
-
The iterator knows there are more elements to examine if its current index is below the size of the list. If there is no such element but the client calls next, an exception is thrown.
-
The precondition of
remove
is that the methodnext
has been called and thatnext
was called more recently than any other call toremove
. The precondition is enforced by aboolean
flag in the iterator whose value is changed on every call tonext
orremove
. If the precondition is violated, an exception is thrown. -
public int sum() { int total = 0; for (int i = 0; i < size; i++) { total += elementData[i]; } return total; }
-
public double average() { if (isEmpty()) { return 0.0; } else { return (double) sum() / size; } }
-
Java does not allow the construction of arrays of generic types. To work around this, we instead create an array of
Object[]
and cast it to typeE[]
. -
Instead of 0, we fill all of our empty cells of type
E
withnull
. -
We must modify
indexOf
to compare objects usingequals
rather than==
because==
compares only references and not the state of the objects. -
An annotation is a special directive to the compiler with additional information about a class, method, or other structure. Annotations help us when writing our generic list because we can instruct the compiler not to warn us about potentially unsafe casting operations.
-
It is important to set the removed/cleared elements to
null
so that Java's garbage collector can potentially reclaim their memory. -
When the iterator is an inner class, it can directly access the fields of the enclosing list object. This makes it easier for the iterator to do its work without keeping track of as much state.
Chapter 16
-
The difference between a linked list and an array list is that while an array list stores all of its elements in a single large array, a linked list stores each element inside its own container object called a node. The nodes are connected (linked) to each other by references. The two kinds of lists are similar in that they both implement the same external operations to clients, such as methods for adding, removing, accessing, and locating elements.
-
A node is a small object that stores a single element of a linked list. The list object stores reference(s) to a small number of nodes, perhaps only the front of the list. The front contains a chain of references that connect to the other elements of the list.
-
The
next
field of the last node of a list, as well as any unspecifiednext
field, storesnull
. -
When the client tries to go past the end of a linked list, there will be a null pointer exception.
-
+----+----+ +----+----+ list ----> | 1 | +----> | 3 | / | +----+----+ +----+----+
-
+----+----+ +----+----+ +----+----+ list ----> | 1 | +----> | 3 | +----> | 2 | / | +----+----+ +----+----+ +----+----+
-
+----+----+ +----+----+ list ----> | 4 | +----> | 3 | / | +----+----+ +----+----+
-
+----+----+ +----+----+ list ----> | 1 | +----> | 2 | / | +----+----+ +----+----+
-
list.next.next = new ListNode(3, null); // 2 -> 3
-
list = new ListNode(3, list); // 3 -> 1 and list -> 3
-
temp.next.next = list.next; // 4 -> 2 list.next = temp; // 1 -> 3
-
ListNode list2 = list; // list2 -> 1 list = list.next; // list -> 2 list2.next = list2.next.next; // 1 -> 3 list.next = null; // 2 /
-
ListNode temp = list; // temp -> 5 list = list.next; // list -> 4 temp.next = list.next; // 5 -> 3 list.next = temp; // 4 -> 5
-
ListNode temp = list.next.next; // temp -> 3 temp.next = list.next; // 3 -> 4 list.next.next = list; // 4 -> 5 list.next.next.next = null; // 5 / list = temp; // list -> 3
-
list.next.next.next = temp; // 3 -> 4 temp.next.next = list.next.next; // 5 -> 3 list.next.next = null; // 2 / ListNode temp2 = temp.next; // temp2 -> 5 temp.next = list.next; // 4 -> 2 list = temp2; // list -> 5
-
list2.next.next.next = list; // 4 -> 1 list.next = list2; // 1 -> 2 list = list2.next.next; // list -> 4 list2 = list2.next; // list2 -> 3 list2.next = null; // 3 / list.next.next.next = null; // 2 /
-
ListNode list2 = list.next.next; // list2 -> 3 list.next.next.next.next = list.next; // 4 -> 2 ListNode temp = list; // temp -> 1 list = list.next.next.next; // list -> 4 list2.next = temp; // 3 -> 1 list.next.next = null; // 2 / list2.next.next = null; // 1 /
-
The two ways to change an object of our linked list class are to change its front reference or to change the next or data field of an existing node.
-
Inserting and removing is most expensive at the end of the list, because the code must loop through all of the next references to reach the end. This is the opposite of the array list, which inserts/removes most slowly at the start because of the shifting of elements that is required.
-
The loop should stop and index
i - 1
, the index before the one to add or remove. This is so that you can adjust the preceding node's next reference. -
Resizing is not necessary for a linked list, since more nodes can be dynamically allocated. The only limit on the number of elements is the amount of memory available to the Java virtual machine.
-
ListNode current = list; while (current != null) { current.data = 42; current = current.next; }
-
ListNode current = list; while (current.next != null) { current = current.next; } current.data = 42;
-
ListNode current = list; while (current.next != null) { current = current.next; } current.next = new ListNode(42);
-
public int min() { if (front == null) { throw new IllegalStateException(); } else { int minValue = front.data; ListNode current = front.next; while (current != null) { minValue = Math.min(minValue, current.data); current = current.next; } return minValue; } } public int max() { if (front == null) { throw new IllegalStateException(); } else { int maxValue = front.data; ListNode current = front.next; while (current != null) { maxValue = Math.max(maxValue, current.data); current = current.next; } return maxValue; } }
-
The four cases examined by the
addSorted
method are: the typical case in the "middle" of the list; inserting at the back of the list; inserting at the front; and the empty list case. -
The "inchworm approach" is when an algorithm keeps track of two linked node references, one for the previous node and one for the current node. They are moved forward together over the list until a particular position is reached. At that point, the previous reference is modified as appropriate. One advantage of this approach is that you do not need to write complex chains of dereferences such as
current.next.data
. -
public int sum() { int total = 0; ListNode current = front; while (current != null) { total += current.data; current = current.next; } return total; } public double average() { if (front == null) { return 0.0; } else { int total = 0; int count = 0; ListNode current = front; while (current != null) { total += current.data; current = current.next; count++; } return (double) total / count; } }
-
The main advantage of the
IntList
interface is that client code can take advantage of polymorphism. A client program can deal with anIntList
reference and the actual object at runtime can be an instance of either kind of list. -
public void firstLast(IntList list) { if (!list.isEmpty()) { int element = list.get(0); list.remove(0); list.add(element); } }
-
When changing the linked list to store elements of type
E
, the list class, its nested classes, and several methods must be changed to use the new generic type. We must change any comparisons between objects to useequals
instead of==
. In our code, we also use dummy header nodes and add aback
reference to increase the efficiency when adding to the end of the list. -
Iterators are important with linked lists because it is inefficient to traverse a linked list by calling the
get
method once for each index. Such an algorithm must repeatedly traverse the entire list to each index passed. The iterator instead remembers its position between calls tonext
. -
The linked list iterator keeps a reference to its current node and a
boolean
for whether it is safe to remove an element. The iterator knows there are more elements by looking at thenext
reference of its current node.
Chapter 17
-
A tree has only one root. A tree could have more leaves than branches (for example, a perfect tree of height 3) or could have more branches than leaves (for example, a tree whose root has two child nodes, each of which has one child, each of which has one child).
-
Twice as many leaves as branches:
+---+ | 1 | +---+ / \ / \ +---+ +---+ | 2 | | 3 | +---+ +---+
Same number of leaves as branches:
+---+ | 1 | +---+ / \ / \ +---+ +---+ | 2 | | 3 | +---+ +---+ / / \ / / \ +---+ +---+ +---+ | 4 | | 5 | | 6 | +---+ +---+ +---+
-
- 3 levels
- 3 branches: Nodes 3, 5, and 2
- 3 leaves: Nodes 1, 4, and 6
- The node containing 3 is the root.
- Node 5 is the sibling of Node 2. Nodes 4 and 6 are the children of Node 2.
-
- preorder: 3 5 1 2 4 6
- inorder: 1 5 3 4 2 6
- postorder: 1 5 4 6 2 3
-
- preorder: 19 47 23 -2 55 63 94 28
- inorder: 23 47 55 -2 19 63 94 28
- postorder: 23 55 -2 47 28 94 63 19
-
- preorder: 2 1 7 4 3 5 6 9 8
- inorder: 2 3 4 5 7 1 6 8 9
- postorder: 3 5 4 7 8 9 6 1 2
-
If we removed the
root != null
test from theprintPreorder
method, the method would eventually crash when trying to dereferenceroot
to examine its data or to make a recursive call. -
public void printPostorder() { System.out.print("postorder:"); printPostorder(overallRoot); System.out.println(); } private void printPostorder(IntTreeNode root) { if (root != null) { printPostorder(root.left); printPostorder(root.right); System.out.print(" " + root.data); } }
-
public void printMirror() { System.out.print("mirror:"); printMirror(overallRoot); System.out.println(); } private void printMirror(IntTreeNode root) { if (root != null) { printMirror(root.right); System.out.print(" " + root.data); printMirror(root.left); } }
-
Many tree methods use a public/private pair because the algorithms are best implemented recursively, but each recursive call must examine a progressively smaller portion of the tree. Therefore the header of the private method generally accepts a tree node as an additional parameter.
-
public int size() { return size(overallRoot); } private int size(IntTreeNode root) { if (root == null) { return 0; } else { return 1 + size(root.left) + size(root.right); } }
-
public int min() { if (overallRoot == null) { throw new IllegalStateException("empty tree"); } return min(overallRoot); } private int min(IntTreeNode root) { if (root.left == null && root.right == null) { return root.data; } else { int minValue = root.data; if (root.left != null) { minValue = Math.min(minValue, min(root.left)); } if (root.right != null) { minValue = Math.min(minValue, min(root.right)); } return minValue; } }
// max is written in the same fashion as min, but with 'max' // in place of 'min' everywhere in the code. public int max() { if (overallRoot == null) { throw new IllegalStateException("empty tree"); } return max(overallRoot); } private int max(IntTreeNode root) { if (root.left == null && root.right == null) { return root.data; } else { int maxValue = root.data; if (root.left != null) { maxValue = Math.max(maxValue, max(root.left)); } if (root.right != null) { maxValue = Math.max(maxValue, max(root.right)); } return maxValue; } }
-
public int countBranches() { return countBranches(overallRoot); } private int countBranches(IntTreeNode root) { if (root == null || (root.left == null && root.right == null)) { return 0; } else { return 1 + countBranches(root.left) + countBranches(root.right); } }
-
A binary search tree is one that is ordered such that smaller nodes appear to the left and larger nodes appear to the right.
-
Valid binary search trees: (b), if duplicates are allowed; (c); and (e).
-
An in-order traversal of a BST will examine the elements in their sorted order. For example, in-order traversal of a BST of integers will visit the integers in increasing numerical order.
-
Resulting tree:
+--------+ | Leia | +--------+ / \ / \ +--------+ +--------+ | Boba | | R2D2 | +--------+ +--------+ \ / \ / +--------+ +--------+ | Darth | | Luke | +--------+ +--------+ / \ / \ +--------+ +--------+ | Chewy | | Han | +--------+ +--------+ \ \ +--------+ | Jabba | +--------+
- Pre-order: Leia, Boba, Darth, Chewy, Han, Jabba, R2D2, Luke
- In-order: Boba, Chewy, Darth, Han, Jabba, Leia, Luke, R2D2
- Post-order: Chewy, Jabba, Han, Darth, Boba, Luke, R2D2, Leia
-
Resulting tree:
+-----+ | Meg | +-----+ / \ / \ +-----+ +--------+ | Joe | | Stewie | +-----+ +--------+ / \ / / \ / +-------+ +------+ +-------+ | Brian | | Lois | | Peter | +-------+ +------+ +-------+ \ \ \ \ +-----------+ +----------+ | Cleveland | | Quagmire | +-----------+ +----------+
- Pre-order: Meg, Joe, Brian, Cleveland, Lois, Stewie, Peter, Quagmire
- In-order: Brian, Cleveland, Joe, Lois, Meg, Peter, Quagmire, Stewie
- Post-order: Cleveland, Brian, Lois, Joe, Quagmire, Peter, Stewie, Meg
-
Resulting tree:
+------------+ | Kirk | +------------+ / \ / \ / \ +------------+ +------------+ | Chekov | | Spock | +------------+ +------------+ \ / \ \ / \ \ / \ +------------+ +------------+ +------------+ | Khaaaan! | | Scotty | | Uhuru | +------------+ +------------+ +------------+ / / / / / / +------------+ +------------+ | McCoy | | Sulu | +------------+ +------------+
- Pre-order: Kirk, Chekov, Khaaaan!, Spock, Scotty, McCoy, Uhuru, Sulu
- In-order: Chekov, Khaaaan!, Kirk, McCoy, Scotty, Spock, Sulu, Uhuru
- Post-order: Khaaaan!, Chekov, McCoy, Scotty, Sulu, Uhuru, Spock, Kirk
-
Resulting tree:
+------------+ | Lisa | +------------+ / \ / \ / \ +------------+ +------------+ | Bart | | Marge | +------------+ +------------+ \ / \ \ / \ \ / \ +------------+ +------------+ +------------+ | Homer | | Maggie | | Smithers | +------------+ +------------+ +------------+ / / / / / / +------------+ +------------+ | Flanders | | Milhouse | +------------+ +------------+
- Pre-order: Lisa, Bart, Homer, Flanders, Marge, Maggie, Smithers, Milhouse
- In-order: Bart, Flanders, Homer, Lisa, Maggie, Marge, Milhouse, Smithers
- Post-order: Flanders, Homer, Bart, Maggie, Milhouse, Smithers, Marge, Lisa
-
The
add
method needs to return the newly added node to enable thex = change(x)
pattern. If no reference to the new node is returned, it is not possible to attach that new node to the rest of the tree. Such attachment is crucial to the working of the algorithm. -
The
x = change(x)
pattern is an algorithmic strategy where a recursive method (such as a binary tree method) will accept a node's initial state as a parameter and will then return the node's new state as its result. This returned result will be stored by the client back into its original place of reference. This allows recursive methods to return modified versions of trees using elegant code that follows the "zen" of recursion. -
The
contains
method is efficient on BSTs and needs to go at most one direction in each recursive call. Each call advances one level in the tree, so the total number of calls / advancements is the height of the tree, or N. This is logarithmic with respect to the total number of nodes in the tree (its size). -
This second version of
contains
is much less efficient than the one written in the chapter. It goes both to the left and to the right recursively to find the value, but this does not take advantage of the sortedness of the tree. It will have linear O(N) runtime rather than the much faster O(log N) desired runtime of our original method. -
public int min() { if (overallRoot == null) { throw new IllegalStateException("empty tree"); } return min(overallRoot); } private int min(IntTreeNode root) { if (root.left == null) { return root.data; } else { return min(root.left); } } public int max() { if (overallRoot == null) { throw new IllegalStateException("empty tree"); } return max(overallRoot); } private int max(IntTreeNode root) { if (root.right == null) { return root.data; } else { return max(root.right); } }
-
When converting the tree to store type
E
, we must add a type parameter to the class header. This parameter must beComparable
. When examining whether a given element is too small or large (whether to go left or right recursively) in methods such asadd
orcontains
, we must callcompareTo
instead of using the<
and>
operators that do not work with objects. -
To add a tree iterator, each node would need to have a reference to the "next" node after it, so that the nodes could be traversed in a left-to-right order. Another solution would be for nodes to have references to their parents so that the iterator could go back up the tree as necessary when traversing through the elements.
Chapter 18
-
Hashing is a process of mapping element values to integer indexes and storing the elements at those indexes in an array. Hashing is a good way of implementing a set because it provides theoretically O(1) runtime for adding, removing, and searching a set.
-
The following statement about hash tables is true:
d. A hash function maps element values to integer indexes in the hash table. -
A hash table being "full" depends on what strategy is used to resolve collisions. If probing is used, the table is literally full when it has no empty buckets for storing elements, but often it is considered to be too full when its load factor (the ratio of its size to its array capacity) reaches some maximum like 0.75 or 0.66. A hash table that uses separate chaining is never literally full because elements can be added indefinitely to each bucket's linked list, but it still resizes once the load factor reaches some threshold.
-
The code shown is incorrect because it just copies over every element from the hash table into the same index in the new larger array. This may lead to elements being at the wrong index, because the proper index is based on the element's hash code modded by the array length. For example, the value 37 would be at index 7 in an array of size 10, but in a larger array of size 20 it should be at index 17.
-
After adding the elements, the hash table's state is the following:
0 1 2 3 4 5 6 7 8 9 [ 80, 0, 2, 42, 0, 35, 15, 95, 66, 0]
-
After adding the elements, the hash table's state is the following:
0 1 2 3 4 5 6 7 8 9 [ |, /, |, /, /, |, |, /, /, /] 80 42 95 66 | | 2 15 | 35
-
After adding the elements, the hash table's state is the following:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [ 0, 0, 32, 0, 24, 5, 44, 47, 0, 0, 0, 0, 0, X, 0, X, 0, 17, 0, 0] size = 6 capacity = 20 load factor = 0.3
-
After adding the elements, the hash table's state is the following:
0 1 2 3 4 5 6 7 8 9 10 [ 0, 0, 0, 0, 70, 82, 50, 39, 15, 29, 18] size = 7 capacity = 11 load factor = 0.636
-
- This is a legal
hashCode
implementation, according to the contract. It distributes hash codes somewhat well, but it has certain groups of points that will collide with each other unnecessarily (for example, every point with an x-coordinate or y-coordinate of 0 will have the same hash code). - This is a legal
hashCode
implementation, according to the contract. But it distributes hash codes extremely poorly; literally it could not be worse in that respect, because every point has the same hash code. It's important to note that it is still a technically correct implementation, though it works very poorly in terms of hash table performance. - This is not a legal
hashCode
implementation, according to the contract. It does not consistently return the same hash code for the same point object state.
- This is a legal
-
hashCode
method for aDate
class (the constant multipliers for each component are somewhat arbitrary):public int hashCode() { return 1331 * year + 37 * month + day; }
-
hashCode
method for aStudent
class (the constant multipliers for each component are somewhat arbitrary):public int hashCode() { return 373 * name.hashCode() + 1341 * studentID + 31 * Double.valueOf(weight).hashCode(); }
-
After adding the key/value pairs, the hash table's state is the following:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [ /, /, /, /, X, /, 6=Tina, 7=Meghan, /, /, /, /, /, 33=Kona, 34=Tyler, 15=Daisy, /, X, /, /] size = 5 capacity = 20 load factor = 0.4
-
The following statement about min-heaps is true:
b. The smallest value is the root. -
If a binary heap has 26 nodes, its height is 5. If it has 73 nodes, its height is 7. We know for sure because every heap is a complete tree, so its shape and height are predictable given its size. The height of a heap of size N will always be equal to ceil(log2 N).
-
- Invalid; the value 9 cannot be below 12.
- Invalid; not a complete binary tree.
- Valid.
-
For our heap implementation, an element at index 8 of the array has its children at indexes 16 and 17. Its parent is at index 4. An element at index 23 has its children at indexes 46 and 47, and its parent at index 11.
-
The min-heap after 21 is added:
12 / \ 29 21 / \ / \ 30 39 72 91 / \ / \ / 55 64 40 99 84
-
The min-heap after 7 is added:
7 / \ 29 12 / \ / \ 30 39 21 91 / \ / \ / \ 55 64 40 99 84 72
-
The resulting binary min-heap after all adds is the following:
2 / \ 3 4 / \ / \ 6 7 5 8 / 9
-
The resulting binary min-heap after each of the three removals is the following. After first removal:
3 / \ 6 4 / \ / \ 9 7 5 8
After second removal:
4 / \ 6 5 / \ / 9 7 8
After third removal:
5 / \ 6 8 / \ 9 7
-
The resulting binary min-heap after all adds is the following:
1 / \ 3 7 / \ / \ 8 11 15 12 / \ 14 9
-
The resulting binary min-heap after each of the three removals is the following. After first removal:
3 / \ 8 7 / \ / \ 9 11 15 12 / 14
After second removal:
7 / \ 8 12 / \ / \ 9 11 15 14
After third removal:
8 / \ 9 12 / \ / 14 11 15
-
The array does not begin with its root at 1. (The array also contains some incorrect element values, but that's an error on the part of the authors. Oh well.) The proper array state is the following:
0 1 2 3 4 5 6 7 8 9 10 11 12 [ /, 12, 29, 70, 30, 39, 84, 91, 55, 64, 40, 99, ...]
-
Heap represented by the given array:
29 / \ 41 30 / \ / \ 55 68 37 41 / 80
-
Array representation of the heap from Self-Check #19:
0 1 2 3 4 5 6 7 8 9 [ /, 2, 3, 4, 6, 7, 5, 8, 9, ...]
-
Array representation of the heap from Self-Check #21:
0 1 2 3 4 5 6 7 8 9 10 [ /, 1, 3, 7, 8, 11, 15, 12, 14, 9, ...]
Chapter 19
-
Because functional programming focuses so much on individual functions, the community of programmers who use functional programming regularly have concluded that side effects should be avoided when possible.
-
Calling
System.out.println
is considered a side effect because it produces a noticeable outcome, namely printing output to the console. So you can detect whether a given function was called or not by looking for output. This doesn't mean that printing output is a bad thing, merely that it is a side effect. -
The function's side effect is that it modifies the array that was passed in. It could be changed to remove side effects by having it return the new array state rather than changing the existing array.
// Returns a new array whose values are twice as large as // the values of all elements in the given array. public static int[] doubleAll(int[] a) { int[] result = new int[a.length]; for (int i = 0; i < a.length; i++) { result[i] = 2 * a[i]; } return result; }
-
Rewritten version of the program with no side effects:
public class SideEffect2 { public static int f(int x, int n) { x = x * 2; return x + n; } public static void main(String[] args) { int x = 5; int result = f(x, 5) + f(x, 5); System.out.println(result); } }
-
To support subtraction problems, we must call
giveProblems
and pass a lambda function that does subtraction, such as:giveProblems(console, 3, "-", (x, y) -> x * y);
-
(x) -> x * x
-
(a, b) -> (a > b ? a : b)
-
(first, last) -> (last + ", " + first)
-
A stream is not the same as an array. Both can be thought of as containing a collection of elements. But streams do not support mutating data, and you can only access an element at a time, not random access like in an array.
-
The variable
result
stores 4. -
int sum = Arrays.stream(a) .map(n -> -n) .sum();
-
int evens = (int) Arrays.stream(a) .filter(n -> n % 2 == 0) .count();
-
The variable
result
stores 44. -
The code does not compile because it returns an optional result. You must call
getAsDouble
to retrieve the actual double value:double avg = DoubleStream.of(3.1, -4.5, 8.9, -6.2, 1.0) .map(n -> Math.abs(n)) .average() .getAsDouble();
-
A bound variable is inside the lambda, typically one of its parameters. A free variable is a variable referred to in the lambda's code that is declared outside the lambda and enclosed into its closure.
-
The free variables are
a
andb
, and the bound variables arec
andd
. -
The code is not allowed to modify the free variable
a
. The code could be modified as follows:int a = 10; int b = 20; int sum = IntStream.of(1, 2, 3, 4, 5) .map(n -> n + b - (a + 1)) .sum();
-
The code produces the following output:
10 28 33 28 49 56 49
-
// this version will not print duplicate values Arrays.stream(a) .map(Math::abs) .distinct() .forEach(System.out::println);
-
// retain the positive integers only int[] positives = Arrays.stream(a) .filter(n -> n > 0) .toArray();
-
// print all four-letter words in the list: list.stream() .filter(s -> s.length() == 4) .forEach(System.out::println);
-
// print all lines from notes.txt that are at least 40 chars long Files.lines(Paths.get("notes.txt")) .filter(line -> line.length() >= 40) .forEach(System.out::println);
-
The code has four problems: (1) The
Files.lines
method accepts a path, not a string; (2) Themap
call should bemapToInt
; (3) Themax
call needs to be followed by a call togetAsInt
because it returns an optional integer result; and (4) The overall method must havethrows IOException
in its header. The corrected code is:// Returns the length of the longest line in the given file. // Assumes that the file contains at least one line. public static int longestLineLength(String filename) throws IOException { return Files.lines(Paths.get(filename)) .mapToInt(String::length) .max() .getAsInt(); }
This document, all self-check problems, and their solutions are Copyright © Pearson 2013. All rights reserved.
-
Chapter 8 Exercises Solution Building Java Programs 4th Edition
Source: https://www.buildingjavaprograms.com/self-check-solutions-4ed.html