Solutions to selected exercises can be found in the electronic document The Thinking in Java Annotated Solution Guide, available for a small fee from www.BruceEckel.com.
Create an array of double and fill( ) it using
RandDoubleGenerator. Print the results.
Create a new class called Gerbil with an int gerbilNumber
thats initialized in the constructor (similar to the Mouse
example in this chapter). Give it a method called hop( ) that
prints out which gerbil number this is, and that its hopping. Create an
ArrayList and add a bunch of Gerbil objects to the List.
Now use the get( ) method to move through the List and call
hop( ) for each Gerbil.
Modify Exercise 2 so you use an Iterator to move through the
List while calling hop( ).
Take the Gerbil class in Exercise 2 and put it into a Map
instead, associating the name of the Gerbil as a String (the key)
for each Gerbil (the value) you put in the table. Get an Iterator
for the keySet( ) and use it to move through the Map, looking
up the Gerbil for each key and printing out the key and telling the
gerbil to hop( ).
Create a List (try both ArrayList and LinkedList)and fill it using Collections2.countries. Sort the list and print it,
then apply Collections.shuffle( ) to the list repeatedly, printing
it each time so that you can see how the shuffle( ) method
randomizes the list differently each time.
Demonstrate that you cant add anything but a Mouse to a
MouseList.
Its possible, however, to ask how big the vector is, and the at( ) method does perform bounds checking.
[52] This is one of the places where C++ is distinctly superior to Java, since C++ supports parameterized types with the template keyword.
[53] The C++ programmer will note how much the code could be collapsed with the use of default arguments and templates. The Python programmer will note that this entire library would be largely unnecessary in that language.
[54]Design Patterns, Erich Gamma et al., Addison-Wesley 1995.
[56] This data was found on the Internet, then processed by creating a Python program (see www.Python.org).
[57] This is a place where operator overloading would be nice.
[58] If these speedups still dont meet your performance needs, you can further accelerate table lookup by writing your own Map and customizing it to your particular types to avoid delays due to casting to and from Objects. To reach even higher levels of performance, speed enthusiasts can use Donald Knuths The Art of Computer Programming, Volume 3: Sorting and Searching, Second Edition to replace overflow bucket lists with arrays that have two additional benefits: they can be optimized for disk storage characteristics and they can save most of the time of creating and garbage collecting individual records.
[59] As it turns out, a prime number is not actually the ideal size for hash buckets, and recent hashed implementations in Java uses a power of two size (after extensive testing). Division or remainder is the slowest operation on a modern processor. With a power-of-two hash table length, masking can be used instead of division. Since get( ) is by far the most common operation, the % is a large part of the cost, and the power-of-two approach eliminates this (but may also affect some hashCode( ) methods).
[60] In a private message, Joshua Bloch wrote: ... I believe that we erred by allowing implementation details (such as hash table size and load factor) into our APIs. The client should perhaps tell us the maximum expected size of a collection, and we should take it from there. Clients can easily do more harm than good by choosing values for these parameters. As an extreme example, consider Vectors capacityIncrement. No one should ever set this, and we shouldnt have provided it. If you set it to any non-zero value, the asymptotic cost of a sequence of appends goes from linear to quadratic. In other words, it destroys your performance. Over time, were beginning to wise up about this sort of thing. If you look at IdentityHashMap, youll see that it has no low-level tuning parameters.