 Home : Course Map : Chapter 3 : Java : Tech : Histogram Class   Introduction Class Definition Data Fields Methods Constructors Instantiation   Demo 1   Demo 2 Static Members   Demo 3 Value&Reference   Demo 4 Overloading    Demo 5 Wrappers    Demo 6 Autobox/Unbox    Demo 7 Arrays   Demo 8 Exceptions Exercises
 Supplements MoreAboutObjects Creating Types Classes,Objs&JVM Java OOP vs C++ Garbage Collection
 About JavaTech      Codes List      Exercises      Feedback      References      Resources      Tips      Topic Index      Course Guide      What's New

A histogram provides the frequency distribution of values taken by a parameter of interest. These types of distributions are often needed in science and engineering studies.

For example, say that an experiment counts the number of cosmic rays passing through a detector every minute. We might expect, say, a distribution of "hits" per minute to have a mean around 10. We record the number of hits every minute over a period of a few hours and then make a histogram of the values.

We create a histogram with, say, 10 bins in which the first bin holds the number of times the hits measured between 0 and 4, the second bin for between 5 and 8, and so forth, up to the last bin which counts the number of times the hits were between 37 and 40. The resulting Poisson type distribution would peak below 10 and have a tail that falls to zero on the low side and a long tail on the high side.

The following BasicHist.java class provides some essential histogram features. The class attributes include instance variables for the number of bins, an integer array of bins, over and under flow counts, and the minimum and maximum values that the histogram spans. The constructor creates an instance of the class for a given set of bins and for a lower and upper parameter range.

The three methods provide for adding an entry to the histogram, clearing the histogram, and for obtaining the values in the bins (including the over and underflows.)

 BasicHist.java /** A simple histogram class to count the frequency of   * values of a parameter of interest.  **/ public class BasicHist {   int [] bins;   int numBins;   int underflows;   int overflows;   double lo;   double hi;   double range;   /** The constructor will create an array of a given     * number of bins. The range of the histogram given     * by the upper and lower limt values.    **/   public BasicHist (int numBins, double lo, double hi) {     this.numBins = numBins;     bins = new int[numBins];     this.lo = lo;     this.hi = hi;     range = hi - lo;   }   /**     * Add an entry to a bin.     * Include if value is in the range     * lo <= x < hi    **/   public void add(double x) {     if( x >= hi) overflows++;     else if( x < lo) underflows++;     else {       double val = x - lo;       // Casting to int will round off to lower       // integer value.      int bin = (int)(numBins * (val/range) );       // Increment the corresponding bin.       bins[bin]++;     }   }   /** Clear the histogram bins. **/   public void clear() {     for (int i=0; i < numBins; i++) {         bins[i] = 0;         overflows = 0;         underflows= 0;     }   }   /** Provide access to the bin values. **/   public int getValue(int bin) {     if (bin < 0)         return underflows;     else if( bin >= numBins)         return overflows;     else         return bins[bin];   } }

The applet below creates and instance of BasicHist and uses it to provide a histogram of the distribution of values generated by Gaussian random number generator. (We will discuss details about random number generation in Java in Chapter 4: Tech.)

BasicHistApplet1.java
(Output goes to browser's Java console.)
public class  BasicHistApplet1 extends java.applet.Applet
{
public void init() {
// Create an instance of the Random class for
// producing our random values.

java.util.Random r = new java.util.Random();
// Them method nextGaussian in the class Random produces
// values centered at 0.0 and with a standard deviation
// of 1.0.

// Create an instance of our basic histogram class.
// Make it wide enough enough to include most of the
// gaussian values.

BasicHist bh = new BasicHist (10,-2.0,2.0);

// Fill the histogram
for (int i=0; i < 100; i++) {
double val = r.nextGaussian ();
}

// Print out the frequency values in each bin.
for(int i=0; i < 10; i++) {
System.out.println("Bin " + i + " = "+ bh.getValue (i));
}

// Negative bin values gives the underflows
System.out.println ("Underflows = "+ bh.getValue (-1));

// Bin values above the range give the overflows.
System.out.println ("Overflows = "+ bh.getValue (10));

//------------------------------------------------
// and this line.

}
... standard code...
}

When we run the above applet, an output similar to the following will be produced:

 Bin 0 = 3 Bin 1 = 8 Bin 2 = 12 Bin 3 = 14 Bin 4 = 15 Bin 5 = 17 Bin 6 = 9 Bin 7 = 9 Bin 8 = 7 Bin 9 = 3 Underflows = 1 Overflows = 2

We see that the distribution does in fact roughly follow the general shape of a guassian centered in the middle bins.

Object Oriented vs Procedural

The histogram example provides a nice illustration of the power and utility of object oriented program design.

If your program had 20 parameters to examine, you can simply create 20 instances of BasicHist, each with its own number of bins and range limits relevant to that parameter. If at some later point, we add new methods and instance variables to the BasicHist, you don't not need to modify the code in your program as long as the changes are internal and don't affect the argument lists in the methods that you invoke.

If you think about how to do histogramming in a purely procedural code manner, you will start to appreciate the elegance of the object oriented approach. In a procedural program, you would need to create arrays to hold the histogram values. Most likely you would use a 2-D array with the first index for the given histogram, and the second index corresponding to the bins.

Similarly, you could use arrays to hold the parameters of the histograms, such as the number of bins, the lower and upper ranges, and so forth. Functions to add entries to the histograms would require a lot of bookkeeping to determine which histogram was needed. With classes, we just create 20 instances of the BasicHist type and each instance knows which histogram it is and you don't have to worry about keeping track of the histogramming details in your code.

Furthermore, if you wanted to use the histogram code in another program, it would be messy to extract just that code from the program and move it into the new one. The encapsulation aspect inherent to the object approach makes reusability far easier that with procedural code.

References & Web Resources

Latest update: Oct. 19.2004

 Tech OOP in Tech Apps Complex Number Histogram Class   Demo More Wrappers
 Physics OOP in Physics Particle Class Root Finding   Demo 1 Newton Methods   Demo 2 Exercises   Part I Part II Part III Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17 18 19 20 21 22 23 24 Supplements 1  2  3  4  5  6  7  8  9  10  11  12 Tech 1  2  3  4  5  6  7  8  9  10  11  12 Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.