Exercise 1.1: Enter, compile, and run HelloWorld
on your system. 3
Exercise 1.2: Try changing parts of HelloWorld
and see what errors you might get. 3
Exercise 1.3: Add a title to the printed list of the Fibonacci
program. 6
Exercise 1.4: Write a program that generates a different sequence, such as a table of squares. 6
Exercise 1.5: Change the HelloWorld
application to use a named string constant as the string to print. (A string constant can be initialized with a string literal.) 8
Exercise 1.6: Change your program from Exercise 1.3 to use a named string constant for the title. 8
Exercise 1.7: Change the loop in ImprovedFibonacci
so that i
counts backward instead of forward. 12
Exercise 1.8: Add a method to the Point
class that sets the current object's coordinates to those of a passed in Point
object. 17
Exercise 1.9: Modify the Fibonacci
application to store the sequence into an array and print the list of values at the end. 20
Exercise 1.10: Modify the ImprovedFibonacci
application to store its sequence in an array. Do this by creating a new class to hold both the value and a boolean
value that says whether the value is even, and then having an array of object references to objects of that class. 20
Exercise 1.11: Modify the StringsDemo
application to use different strings. 23
Exercise 1.12: Modify ImprovedFibonacci
to store the String
objects it creates into an array instead of invoking println
with them directly. 23
Exercise 1.13: Rewrite the ImprovedFibonacci
program using printf
instead of println
. 24
Exercise 1.14: Sketch out a set of classes that reflects the class structure of the Sony Walkman product family we have described. Use methods to hide the data, making all the data private
and the methods public
. What methods would belong in the Walkman
class? Which methods would be added for which extended classes? 27
Exercise 1.15: Write an interface that extends Lookup
to declare add
and remove
methods. Implement the extended interface in a new class. 29
Exercise 1.16: Add fields to BadDataSetException
to hold the set name and the I/O exception that signaled the problem so that whoever catches the exception will know details about the error. 35
Exercise 2.1: Write a simple Vehicle
class that has fields for (at least) current speed, current direction in degrees, and owner name. 44
Exercise 2.2: Write a LinkedList
class that has a field of type Object
and a reference to the next LinkedList
element in the list. 44
Exercise 2.3: Add a static field to your Vehicle
class to hold the next vehicle identification number, and a non-static field to the Vehicle
class to hold each car's ID number. 46
Exercise 2.4: Consider your solution to Exercise 2.3. Do you think the identification number field should be final
? 47
Exercise 2.5: Write a main
method for your Vehicle
class that creates a few vehicles and prints their field values. 50
Exercise 2.6: Write a main
method for your LinkedList
class that creates a few objects of type Vehicle
and places them into successive nodes in the list. 50
Exercise 2.7: Add two constructors to Vehicle
: a no-arg constructor and one that takes an initial owner's name. Modify the main
program so that it generates the same output it did before. 54
Exercise 2.8: What constructors should you add to LinkedList
? 54
Exercise 2.9: Add a static method to Vehicle
that returns the highest identification number used thus far. 58
Exercise 2.10: Add a toString
method to Vehicle
. 60
Exercise 2.11: Add a toString
method to LinkedList
. 60
Exercise 2.12: Considering your Vehicle
and LinkedList
classes, can you think of a need for any methods that take a variable number of arguments? 61
Exercise 2.13: Make the fields in your Vehicle
class private
, and add accessor methods for the fields. Which fields should have methods to change them, and which should not? 68
Exercise 2.14: Make the fields in your LinkedList
class private
, and add accessor methods for the fields. Which fields should have methods to change them, and which should not? 68
Exercise 2.15: Add a changeSpeed
method that changes the current speed of the vehicle to a passed-in value and add a stop
method that sets the speed to zero. 68
Exercise 2.16: Add a method to LinkedList
to return the number of elements in a list. 68
Exercise 2.17: Add two turn
methods to Vehicle
: one that takes a number of degrees to turn and one that takes either of the constants Vehicle.TURN_LEFT
or Vehicle.TURN_RIGHT
. 71
Exercise 2.18: Change Vehicle.main
to create cars with owners whose names are specified on the command line, and then print them. 74
Exercise 3.1: Starting with the Vehicle
class from the exercises in Chapter 2, create an extended class called PassengerVehicle
to add a capability for counting the number of seats available in the car and the number currently occupied. Provide a new main
method in PassengerVehicle
to create a few of these objects and print them out. 79
Exercise 3.2: Type in the classes X
and Y
as shown previously, and add print statements to trace the values of the masks. Add a main
method and run it to see the results. (Hint: Use the printf
method—shown in Chapter 1—with a format specifier of %x
to print integers in hexadecimal format.) 83
Exercise 3.3: If it were critical to set up these masks using the values from the extended class during construction, how could you work around these problems? 83
Exercise 3.4: Which methods (if any) of Vehicle
and PassengerVehicle
might reasonably be made final
? 97
Exercise 3.5: Write a new extended class that benchmarks something else, such as how long it takes to run a loop from zero to some passed-in parameter. 99
Exercise 3.6: Change Vehicle
so that it has an EnergySource
object reference, which is associated with the Vehicle
in its constructor. EnergySource
must be an abstract
class, because a GasTank
object's measure of fullness will differ from that of a Battery
object. Put an abstractempty
method in EnergySource
and implement it in GasTank
and Battery
classes. Add a start
method to Vehicle
that ensures that the energy source isn't empty
. 99
Exercise 3.7: Override equals
and hashCode
for ColorAttr
. 101
Exercise 3.8: Make Vehicle
and PassengerVehicle
into Cloneable
types.
Which of the four described attitudes should each class take toward cloning? Is the simple copying done by Object.clone
correct for the clone methods of these classes? 107
Exercise 3.9: Write a Garage
class whose objects can hold up to some number of Vehicle
objects in an array. Make Garage
a Cloneable
type, and write a proper clone
method for it. Write a Garage.main
method to test it. 107
Exercise 3.10: Make your LinkedList
class (from the exercises in Chapter 2) Cloneable
, with clone
returning a new list that refers to the same values as the original list, not clones of the values. In other words, changes to one list should not affect the other list, but changes to the objects referenced by the list would be visible in both lists. 107
Exercise 3.11: Find at least one security hole in SortDouble
that would let a sorting algorithm cheat on its metrics without getting caught. Fix the security hole. Assume that the sorting algorithm author doesn't get to write main
. 114
Exercise 3.12: Write a general-purpose SortHarness
class that can sort any object type. How would you provide a way to represent ordering for the objects in a general way, given that you cannot use <
to compare them? 114
Exercise 4.1: Rewrite your solution to Exercise 3.6 on page 99 using an interface for EnergySource
instead of an abstract class. 131
Exercise 4.2: Rewrite your solution to Exercise 3.12 on page 114 using an interface if you didn't write it that way in the first place. 132
Exercise 4.3: Should the LinkedList
class from previous exercises be an interface? Rewrite it that way with an implementation class before you decide. 132
Exercise 4.4: Design a collection class hierarchy using only interfaces. 132
Exercise 4.5: Think about whether the following types should be represented as interfaces, abstract classes, or concrete classes: (a) TreeNode
to represent nodes in an N-ary tree; (b) TreeWalker
to walk the tree in a particular order (such as depth-first or breadth-first); (c) Drawable
for objects that can be drawn by a graphics system; (d) Application
for programs that can be run from a graphical desktop. 132
Exercise 4.6: What changes in your assumptions about each of the problems in Exercise 4.5 would make you change your answers? 132
Exercise 5.1: Consider the Attr
class and Attributed
interface from Chapter 4. Should one of these be a nested type of the other? If so, which way makes the most sense? 136
Exercise 5.2: Create a version of BankAccount
that records the last ten actions on the account. Add a history
method that returns a History
object that will return Action
objects one at a time via a next
method, returning null
at the end of the list. Should History
be a nested class? If so, should it be static or not? 138
Exercise 6.1: Define simple enums for the days of the week and traffic light colors. 152
Exercise 6.2: Redo your solution to Exercise 2.17 to use an enum to represent the TURN_LEFT
and TURN_RIGHT
constants. What advantage is there to using the enum? 152
Exercise 6.3: Redefine the Verbose
interface from Section 4.2.1 on page 121 to use an enum for the verbosity level instead of integer constants. 152
Exercise 6.4: Expand your traffic light color enum from Exercise 6.1 on page 152 so that each enum constant has a suitable Color
object that can be retrieved with getColor
. 156
Exercise 6.5: Redo Exercise 6.4 making getColor
an abstract method and defining constant-specific methods for each enum constant to return the correct Color
object. Would you recommend using constant-specific methods to do this? 159
Exercise 7.1: Just for fun, write a “Hello, World” program entirely using Unicode escape sequences. 163
Exercise 7.2: Write a class that declares a field for each of the primitive numeric types, and try to assign values using the different literal forms—for example, try to assign 3.5f
to an int
field. Which literals can be used with which type of field? Try changing the magnitude of the values used to see if that affects things. 169
Exercise 7.3: Write a program that calculates Pascal's triangle to a depth of 12, storing each row of the triangle in an array of the appropriate length and putting each of the row arrays into an array of 12 int
arrays. Design your solution so that the results are printed by a method that prints the array of arrays using the lengths of each array, not a constant 12. Now change the code to use a constant other than 12 without modifying your printing method. 178
Exercise 9.1: Write a program that uses the operators +
, –
, *
, and /
, on two infinite operands and show the result. Ensure that you try both same signed and opposite-signed infinity values. 203
Exercise 9.2: Write a method that determines the number of 1 bits in a passed-in int
, by using just the bit manipulation operators (that is, don't use Integer.bitCount
). Compare your solution with published algorithms for doing this—see the related reading for “General Programming Techniques” on page 758 for one source. 210
Exercise 9.3: Review your solution to Exercise 7.3 to see if it can be written more clearly or succinctly with the operators you've learned about in this chapter. 213
Exercise 9.4: Using what you've learned in this chapter but without writing code, figure out which of the following expressions are invalid and what the type and values are of the valid expressions: 223
Exercise 10.1: Using if–else
in a loop, write a method that takes a string parameter and returns a string with all the special characters in the original string replaced by their language equivalents. For example, a string with a "
in the middle of it should create a return value with that "
replaced by "
. (Section 7.2.3 on page 167 lists all special characters). 232
Exercise 10.2: Rewrite your method from Exercise 10.1 to use a switch
. 235
Exercise 10.3: Using your “days of the week” enum from Exercise 6.1 write a method that takes a day of the week and returns true
if it is a working day, and false
otherwise. First use nested if
–else
statements and then a switch
statement. Which do you think results in clearer code? 235
Exercise 10.4: Select a few previous exercise solutions for which you have used a for
loop and rewrite it using a while
loop. Can you also rewrite it using a do
–while
loop? Would you do so? If not, why not? 236
Exercise 10.5: Write a method that takes two char
parameters and prints the characters between those two values, including the endpoints. 239
Exercise 11.1: Revisit the LinkedList
class that you started back in Exercise 2.2 and rewrite it as a generic class. 252
Exercise 11.2: Rewrite the Attr
class from Chapter 3 as a generic class. 252
Exercise 11.3: Was Exercise 11.2 a good idea? How does Attr
being generic affect the Attributed
interface defined in Chapter 4? What does it mean for Attributed
objects? 252
Exercise 12.1: Create an ObjectNotFoundException
class for the LinkedList
class you built in previous exercises. Add a find
method that looks for an object in the list and either returns the LinkedList
object that contains the desired object or throws the exception if the object isn't found in the list. Why is this preferable to returning null
if the object isn't found? What additional data if any should ObjectNotFoundException
contain? 286
Exercise 12.2: Decide which way the following conditions should be communicated to the programmer: 295
Exercise 13.1: Write a method that counts the number of occurrences of a given character in a string. 308
Exercise 13.2: Write a method that counts the number of occurrences of a particular string in another string. 308
Exercise 13.3: As shown, the delimitedString
method assumes only one such string per input string. Write a version that will pull out all the delimited strings and return an array. 316
Exercise 13.4: Write a program to read an input string with lines of the form “type value
”, where type
is one of the wrapper class names (Boolean
, Character
, and so on) and value
is a string that the type's constructor can decode. For each such entry, create an object of that type with that value and add it to an ArrayList
—see “ArrayList” on page 582. Display the final result when all the lines have been read. Assume a line is ended simply by the newline character '
'
. 316
Exercise 13.5: Write a method to convert strings containing decimal numbers into comma-punctuated numbers, with a comma every third digit from the right. For example, given the string "1543729"
, the method should return the string "1,543,729"
. 335
Exercise 13.6: Modify the method to accept parameters specifying the separator character to use and the number of digits between separator characters. 336
Exercise 14.1: Write a program that displays the name of the thread that executes main
. 341
Exercise 14.2: Modify the first version of PrintServer
so that only the thread created in the constructor can successfully execute run
, using the identity of the thread as suggested. 345
Exercise 14.3: Write a class whose objects hold a current value and have a method that will add to that value, printing the new value. Write a program that creates such an object, creates multiple threads, and invokes the adding method repeatedly from each thread. Write the class so that no addition can be lost. 354
Exercise 14.4: Modify your code from Exercise 14.3 to use static data and methods. 354
Exercise 14.5: Modify your code from Exercise 14.4 so that threads can safely decrement the value without using a static synchronized method. 354
Exercise 14.6: Write a program that prints the elapsed time each second from the start of execution, with another thread that prints a message every fifteen seconds. Have the message-printing thread be notified by the time-printing thread as each second passes by. Add another thread that prints a different message every seven seconds without modifying the time-printing thread. 358
Exercise 14.7: Run Babble
multiple times and examine the output: Is it always the same? If possible, run it on different systems and compare. 362
Exercise 14.8: Experiment with the Friendly
program. How often does the deadlock actually happen on your system? If you add yield
calls, can you change the likelihood of deadlock? If you can, try this exercise on more than one kind of system. Remove the deadlock potential without getting rid of the synchronization. 364
Exercise 14.9: Write a method that takes a thread group and starts a thread that periodically prints the hierarchy of threads and thread groups within that group, using the methods just described. Test it with a program that creates several short-lived threads in various groups. 379
Exercise 16.1: Modify TypeDesc
to skip printing anything for the Object
class. It is redundant because everything ultimately extends it. Use the reference for the Class
object for the Object
type. 407
Exercise 16.2: Modify TypeDesc
to show whether the named type is a nested type, and if so, what other type it is nested within. 408
Exercise 16.3: Modify ClassContents
to show information for all declared and all public inherited members. Make sure you don't list anything twice. 411
Exercise 16.4: Write a program that prints all the available annotations applied to a given type. (Only annotations with a retention policy of RUNTIME
will be available.) 415
Exercise 16.5: Expand ClassContents
to include the available annotation information for each member. 416
Exercise 16.6: Create an Interpret
program that creates an object of a requested type and allows the user to examine and modify fields of that object. 420
Exercise 16.7: Modify your Interpret
program to invoke methods on the object. You should properly display any values returned or exceptions thrown. 422
Exercise 16.8: Modify your Interpret
program further to let users invoke constructors of an arbitrary class, displaying any exceptions. If a construction is successful, let users invoke methods on the returned object. 425
Exercise 16.9: Use reflection to write a program that will print a full declaration of a named class, including everything except the import statements, comments, and code for initializers, constructors, and methods. The member declarations should appear just as you would write them. You will need to use all the reflection classes you have seen. Also note that the toString
methods of many of the reflection objects will not provide the information you want in the correct format, so you will need to piece together the individual pieces of information. 429
Exercise 16.10: Modify Interpret
further to allow users to specify a type and size of array to create; set and get the elements of that array; and access fields and invoke methods on specific elements of the array. 432
Exercise 16.11: Expand on Game
and Player
to implement a simple game, such as tic-tac-toe. Score some Player
implementations over several runs each. 441
Exercise 16.12: Modify your results for Exercise 16.11 to allow player strategies to use attached resources by implementing findResource
and findResources
. 444
Exercise 17.1: Write a program to examine the amount of memory available on start up and after allocation of a number of objects. Try invoking the garbage collector explicitly to see how the amount of free memory changes—make sure you don't hold references to the newly allocated objects of course. 454
Exercise 17.2: Modify DataHandler
so that lastFile
is also stored weakly. 458
Exercise 17.3: Rework the resource implementation class so that it uses a reference object to keep track of the key instead of using the hash code. 464
Exercise 17.4: Modify the reaper thread so that it stays alive after shutdown until all the allocated resources can be released. 464
Exercise 17.5: Redesign the resource manager to not use a reaper thread. Be clear on what semantics the resource manager has and on when resources will be released. 464
Exercise 19.1: Add doc comments to your LinkedList
class from Exercise 2.16. Generate the javadoc and ask someone else to write a simple program using your class. Repeat, improving your doc comments if needed, until someone can do so. 496
Exercise 19.2: Expand on Exercise 19.1 by including the private members. Generate the full (private members included) javadoc and ask someone else to explain the class to you. Repeat, improving your comments if needed, until someone can do so. 496
Exercise 20.1: Rewrite the TranslateByte
program as a method that translates the contents of an InputStream
onto an OutputStream
, in which the mapping and the streams are parameters. For each type of InputStream
and OutputStream
you read about in this chapter, write a new main
method that uses the translation method to operate on a stream of that type. If you have paired input and output streams, you can cover both in one main
method. 506
Exercise 20.2: Rewrite the TranslateByte
class as a filter. 518
Exercise 20.3: Create a pair of Filter
stream classes that encrypt bytes using any algorithm you choose—such as XOR
ing the bytes with some value—with your DecryptInputStream
able to decrypt the bytes that your EncryptOutputStream
class creates. 518
Exercise 20.4: Create a subclass of FilterReader
that will return one line of input at a time via a method that blocks until a full line of input is available. 518
Exercise 20.5: Write a program that reads a specified file and searches for a specified word, printing each line number and line in which the word is found. 528
Exercise 20.6: Write a program that takes input of the form name op value
, where name
is one of three words of your choosing, op
is +
, -
, or =
, and value
is a number. Apply each operator to the named value. When input is exhausted, print the three values. For extra credit, use the HashMap
class that was used for AttributedImpl
so that you can use an arbitrary number of named values. 536
Exercise 20.7: Add a method to the Attr
class of Chapter 3 that writes the contents of an object to a DataOutputStream
and add a constructor that will read the state from a DataInputStream
. 539
Exercise 20.8: Write a program that reads a file with entries separated by lines starting with %%
and creates a table file with the starting position of each such entry. Then write a program that uses that table to print a random entry (see the Math.random
method described in “Math and StrictMath” on page 657). 543
Exercise 20.9: Write a method that, given one or more pathnames, will print all the information available about the file it represents (if any). 548
Exercise 20.10: Write a program that uses a StreamTokenizer
object to break an input file into words and counts the number of times each word occurs in the file, printing the result. Use a HashMap
to keep track of the words and counts. 548
Exercise 20.11: Using FilenameFilter
or FileFilter
, write a program that takes a directory and a suffix as parameters and prints all files it can find that have that suffix. 549
Exercise 21.1: Write a program that opens a file and reads its lines one at a time, storing each line in a List
sorted by String.compareTo
. The line-reading class you created for Exercise 20.4 should prove helpful. 584
Exercise 21.2: Rewrite the DataHandler
class on page 457 to use a WeakHashMap
to store the returned data instead of a single WeakReference
. 593
Exercise 21.3: A WeakHashMap
has weak keys and strong values. A WeakValueMap
would have strong keys and weak values. Design a WeakValueMap
. Be cautioned that this is not as simple as it might seem, in fact it is extremely complicated and requires a number of design choices to be made. For example, should iteration of values be allowed to yield null
after hasNext
has returned true
, or should iteration keep the values alive while they are being iterated? Hint: Don't try to extend AbstractMap
, delegate to a HashMap
instead. 593
Exercise 21.4: Write a version of ShortStrings
that implements ListIterator
to filter a ListIterator
object. Should your class extend ShortStrings
? 611
Exercise 21.5: Implement a more efficient ListIterator
for ArrayBunchList
. Be careful of the specific contracts of ListIterator
methods, such as set
not being valid until either next
or previous
is invoked. 616
Exercise 21.6: Rewrite the example program Concat
on page 528 so that it uses an implementation of Enumeration
that has only one FileInputStream
object open at a time. 617
Exercise 21.7: Implement a stack using ArrayList
. Should your stack class be a subclass of ArrayList
or use an ArrayList
internally, providing different stack-specific methods? 619
Exercise 22.1: Write a method that takes an array of floating-point values and a number indicating how many columns to use, and prints the array contents. Try to ensure that the entries in each column line up neatly. Assume a line is 80 characters wide. 632
Exercise 22.2: The WhichChars
class has a problem marking characters near the top of the Unicode range because the high character values will leave many unused bits in the lower ranges. Use a HashSet
to solve this problem by storing Character
objects for each character seen. 635
Exercise 22.3: Now use a HashMap
to store a BitSet
object for each different top byte (high 8 bits) encountered in the input string, with each BitSet
storing the low bytes that have been seen with the particular high byte. 635
Exercise 22.4: Provide an implementation of the Attributed
interface that uses Observer
/Observable
to notify observers of changes. 639
Exercise 22.5: Given a certain number of six-sided dice, you can calculate the theoretical probability of each possible total. For example, with two six-sided dice, the probability of a total of seven is one in six. Write a program that compares the theoretical distribution of sums for a given number of six-sided dice with the actual results over a large number of “rolls” using Random
to generate numbers between one and six. Does it matter which of the number-generating methods you use? 641
Exercise 22.6: Write a program that tests nextGaussian
, displaying the results of a large number of runs as a graph (a bar chart of *
characters will do). 641
Exercise 22.7: Rewrite readCSVTable
so that the number of cells of data expected is passed as an argument. 646
Exercise 22.8: As it stands, readCSVTable
is both too strict and too lenient on the input format it expects. It is too strict because an empty line at the end of the input will cause the IOException
to be thrown. It is too lenient because a line of input with more than three commas will not cause an exception. Rectify both of these problems. 646
Exercise 22.9: Referring back to the discussion of efficiency of regular expressions on page 329, devise at least four patterns that will parse a line of comma-separated-values. (Hint: In addition to the suggestion on page 329 also consider the use of greedy versus non-greedy quantifiers.) Write a benchmark program that compares the efficiency of each pattern, and be sure that you test with both short strings between commas and very long strings. 647
Exercise 22.10: Write a method to tokenize input that ignores comments, using the comment pattern as part of the scanner's delimiter. 650
Exercise 22.11: Write a version of readCSV
that uses a StreamTokenizer
rather than a Scanner
. 650
Exercise 22.12: Write a version of the attribute reading method from page 533 that uses a Scanner
. For this exercise it is only necessary that both versions accept the same correctly formatted input. 650
Exercise 22.13: Extend your solution to Exercise 22.12 so that misplaced =
characters are detected, as in the StreamTokenizer
version. (Hint: You might want to try to dynamically change the delimiter pattern between certain tokens.) 650
Exercise 22.14: Write a method that will take a string containing floating-point numbers, break it up using whitespace as the delimiter, and return the sum of the numbers. 653
Exercise 22.15: Write a calculator that has all Math
or StrictMath
functions, as well as (at least) the basic operators +
, -
, *
, /
, and %
. (The simplest form is probably a reverse Polish stack calculator because operator precedence is not an issue.) 659
Exercise 23.1: Write the plugTogether
method. You will need threads. 669
Exercise 23.2: Write a program that runs exec
on its command-line arguments and prints the output from the command, preceding each line of output by its line number. 672
Exercise 23.3: Write a program that runs exec
on command-line arguments and prints the output from the command, killing the command when a particular string appears in the output. 672
Exercise 24.1: Get GlobalHello
to work with the example locales. Add some more locales, using ListResourceBundle
, .properties
files, and your own specific subclass of ResourceBundle
. 693
Exercise 24.2: Select six different locales and six different currencies, and print a table showing the currency symbol for each currency in each locale. 694
Exercise 24.3: Write a program that takes a string argument that is parsed into the date to print, and print that date in all possible styles. How lenient will the date parsing be? 706
18.188.139.172