Last updated October 14, 2013
See also the companion errata sheet.
The following items note things that are not strictly errors but that nonetheless depart from conventional practice or provoke controversy among experts.
Students are free to use their judgment in adhering to or departing from the author's conventions, as long as the results conform to the quality criteria we discuss starting in the second week.
* Constructs a list containing the elements of the specified collection, in the order * they are stored in the specified collection. This ArrayList object has an * initial capacity of 110% of the specified collection. The worstTime(n) * is O(n), where N is the number of elements in the specified collection. * * @param c the specified collection whose elements this ArrayList object is * initialized from)
If you write commentary like that on a real project, your colleagues will consider you mathematically naïve and unprofessional. Repetition sometimes helps to clarify content, but usually it just takes up space and irritates the reader.
What does "specified" mean? Isn't everything in a program specified? Just give the collection a name and then use it.
On page 252 the commentary switches from "specified" to "given". Neither term contributes anything except consuming space and slowing-up the reader. Just say what the thing is.
In sample solutions and classroom discussions we shall show sensible module documentation.
On page 487 note the repeated line
if (len < 7).
It also occurs on page 474 and is explained unaplogetically on page 461. If you just saw it
in the middle of complicated logic, it would be a mystery value that you'd have to decipher
from analyzing the detailed logic.
In our discussion of program quality we agreed that the value of a fundamental constant must never be "hard coded" (i.e. bound at coding time) in program statements. Instead, the constant should be given a well-chosen name in a single easy-to-find place, and that name should be used wherever the program needs the value, even if there's only one such occurence. Then if future insights call for a change in the value, programmers won't have to search through dozens of pages of source code to comply.
Hard-coding of fundamental constants is one of the surest signs of a naïve beginner programmer, and would be regarded by many employers as a serious gaffe. Don't ever do that.
if (boolean expression) return true; return false;is equivalent to the more compact and direct
return boolean expression;See Setting Result to True or False.
The author presumably intends the example on page 272 to show the benefits of using the JUNIT testing framework, but it will actually send any reasonable programmer seeking almost any alternative. Three dozen lines of painfully repetitive code produces only a single useful test: Store three items in a freshly allocated collection, and validate the state of the collection.
To flesh out this example with adequate testing of the things that might actually go wrong would require, at this tedious level of detail, nearly a dozen more pages of test cases!
Note that this line
assertEquals ("[Berkin, Brian, Greg]", list.toString());
depends upon detailed knowledge of the exact format of the string returned by that specific toString method, including the square brackets and comma plus single blank separators. Can we be confident that that's a Java standard that will never change?
You should know about JUNIT and be prepared to use it when you encounter a situation where it can simplify your testing strategy. But automatically reaching for it can just add meaningless clutter.
Some of the examples and even more of the exercises violate long-established principles of modularity, in particular mixing unrelated functions in the same method.
Exercises 2.1 & 2.2, page 100, call upon the student to do develop a single method that performs:
Mixing input editing and processing in the same subroutine is a notorious indicator of amateurish, if not incompetent, programming. It leads to programs that are hard to understand, confusing to debug, and tricky to modify. One method should read and validate the data. Another method should compare and select from the valid data. The latter one ought to be free of exception handling.
In the Towers of Hanoi problem, page 168, the introductory JavaDoc comment is misleading:
* Determines the steps needed to move n disks from an origin to a desination
That's just what we'd expect to find, but surprise! It actually does that and then composes a formatted message instructing a human agent to carry out the move. That's a lot more than "determining".
We say that a module (subroutine, function, method) that mixes unrelated processes has poor cohesion.