This issue presents tips, techniques, and sample code for the following topics:
Javadoc
Javadoc is a system of structured comments used to document
JavaTM language APIs. The Java Development
Kit comes with a program that you can run over your source code to extract
these comments. Javadoc is not part of the Java programming language itself,
but a documentation convention that is widely used for documenting Java language
APIs.
A simple example of Javadoc comments looks like this:
/**
* Class Sort implements some common sorting algorithms.
*/
public class Sort {
/**
* Sorts a Vector of objects.
*
* @param vec the vector
* @param dir true for ascending order,
* false for descending
* @exception SortArgumentException if vec is null
*/
public void sort_vec(Vector vec, boolean dir)
throws SortArgumentException
{
...
}
...
}
Javadoc comments start with /**, and use tags such as @param, @return,
and @exception to describe the workings of a method. Chapter 18 of
the book The Java Language Specification by James Gosling
et al. describes Javadoc conventions.
Extracted comments are processed into a set of HTML files for later
perusal by a web browser. Using Javadoc you can view the class hierarchy,
an index of all methods and fields, and the details of each class.
Using Hashtable
Hashtable is a class that is part of the core API java.util. It is used to
efficiently store and look up key/element pairs. Hashtable is extended from
an abstract class called Dictionary, a name that clearly describes its purpose.
To see how Hashtable might be used, consider an application that needs
to count how many times each line occurs in a file. This technique could
be used in tabulating word frequencies, for example. Using Hashtable, one
way of doing this is the following:
import java.io.*;
import java.util.*;
public class hash {
private static class countrec {
int count;
};
public static void main(String args[])
{
try {
FileReader fr = new FileReader(args[0]);
BufferedReader br = new BufferedReader(fr);
Hashtable ht = new Hashtable();
String key = null;
while ((key = br.readLine()) != null) {
countrec crec = (countrec)ht.get(key);
if (crec == null) {
crec = new countrec();
crec.count = 1;
ht.put(key, crec);
}
else {
crec.count++;
}
}
br.close();
Enumeration en = ht.keys();
while (en.hasMoreElements()) {
String el = (String)en.nextElement();
countrec crec = (countrec)ht.get(el);
System.out.println(crec.count +
" " + el);
}
}
catch (Throwable e) {
System.err.println(e);
}
}
}
There are several interesting points to note in the example. The basic
operations of adding to a hash table, or looking up keys in it, are
implemented via the put and get methods. The put method puts a key
and element pair into the table, while get looks up an element using
its key and returns the element. Object.hashCode or an overriding
hashCode method in a subclass of Object is used to compute the actual
hash value needed for insertion into the hash table. countrec is an
example of an inner class, and is new feature in
JDKTM 1.1. It's a nested top-level
class, meaning that it is available only within the hash class that
declares it. countrec could be defined outside of hash, or even in
a separate file. But defining it in the way shown here offers the
benefit of keeping it very localized, and not exposed to other classes
or applications.
Note also that get and put deal with Object references. If you want
to use fundamental types like int or double with Hashtable, you will
need to use wrapper classes such as Integer or Double defined in
java.lang.
Retrieving Results:
Once all the lines have been read from the file and inserted into the
hash table, the next step is to retrieve the results, that is, the set
of keys and the associated elements that go with each key. To do this,
an enumeration is retrieved using the keys method of Hashtable.
Enumeration is an interface, and a class that implements it is guaranteed
to define the methods hasMoreElements and nextElement used for stepping
through a list of items. In this example the items are keys from the
hash table. These are stepped through in turn and the associated elements
retrieved. It's possible to tune the performance of a hash table by setting
its initial size and its load factor. For example, the initial load factor
is 0.75, meaning that if the table becomes more than 75 percent full, the
capacity will be increased via internal rehashing of the table.
Definite Assignment
You may have noticed that a Java compiler is kind of stubborn about code
such as the following:
public class assign1 {
public static void main(String args[])
{
int a = 10;
int b;
if (a >= 5)
b = 17;
System.out.println(b);
}
}
which gives a compile error. The reason for the error is that the Java
language has a "definite assignment" rule, which means that a
compiler must make a specific check about whether a local variable has
been assigned to before its value is used. In the example above, the
compiler does not take into account that the value of "a"
is known at compile time, and rejects this code.
Definite assignment is a complicated topic, covering about 15 pages in
the Java Language Specification. But it's worth knowing about, because
the Java language enforces much tighter rules than do other languages in
checking whether a variable is used before it is assigned to. This checking
ultimately results in higher quality programs.
|