0% found this document useful (0 votes)
31 views77 pages

Advanced Topics in Java Core Concepts in Data Structures 1st Edition Noel Kalicharan (Auth.) - Download The Full Ebook Version Right Now

The document provides information about various ebooks available for instant download at ebookgate.com, focusing on topics related to Java data structures and algorithms. It includes links to specific titles and a brief overview of the content covered in a chapter about sorting algorithms, specifically selection sort and insertion sort. The document also discusses the performance analysis of selection sort and its implementation in Java.

Uploaded by

mawawawashu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views77 pages

Advanced Topics in Java Core Concepts in Data Structures 1st Edition Noel Kalicharan (Auth.) - Download The Full Ebook Version Right Now

The document provides information about various ebooks available for instant download at ebookgate.com, focusing on topics related to Java data structures and algorithms. It includes links to specific titles and a brief overview of the content covered in a chapter about sorting algorithms, specifically selection sort and insertion sort. The document also discusses the performance analysis of selection sort and its implementation in Java.

Uploaded by

mawawawashu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 77

Instant Ebook Access, One Click Away – Begin at ebookgate.

com

Advanced Topics in Java Core Concepts in Data


Structures 1st Edition Noel Kalicharan (Auth.)

https://ebookgate.com/product/advanced-topics-in-java-core-
concepts-in-data-structures-1st-edition-noel-kalicharan-
auth/

OR CLICK BUTTON

DOWLOAD EBOOK

Get Instant Ebook Downloads – Browse at https://ebookgate.com


Click here to visit ebookgate.com and download ebook now
Instant digital products (PDF, ePub, MOBI) available
Download now and explore formats that suit you...

Java Structures Data Structures in Java for the Principled


Programmer 2nd edition Duane Bailey

https://ebookgate.com/product/java-structures-data-structures-in-java-
for-the-principled-programmer-2nd-edition-duane-bailey/

ebookgate.com

Data Structures Outside In with Java 1st Edition Sesh


Venugopal

https://ebookgate.com/product/data-structures-outside-in-with-
java-1st-edition-sesh-venugopal/

ebookgate.com

CAIA Level II Advanced Core Topics in Alternative


Investments 2nd Edition Caia Association

https://ebookgate.com/product/caia-level-ii-advanced-core-topics-in-
alternative-investments-2nd-edition-caia-association/

ebookgate.com

Core Topics in Pain 1st Edition Anita Holdcroft

https://ebookgate.com/product/core-topics-in-pain-1st-edition-anita-
holdcroft/

ebookgate.com
Java Software Structures Designing and Using Data
Structures 3rd Edition John Lewis

https://ebookgate.com/product/java-software-structures-designing-and-
using-data-structures-3rd-edition-john-lewis/

ebookgate.com

Data structures and algorithms made easy in Java data


structure and algorithmic puzzles 2nd Edition Narasimha
Karumanchi
https://ebookgate.com/product/data-structures-and-algorithms-made-
easy-in-java-data-structure-and-algorithmic-puzzles-2nd-edition-
narasimha-karumanchi/
ebookgate.com

Core topics in mechanical ventilation 1st Edition Iain


Mackenzie

https://ebookgate.com/product/core-topics-in-mechanical-
ventilation-1st-edition-iain-mackenzie/

ebookgate.com

AAGBI Core Topics in Anaesthesia 2015 1st Edition


Griffiths

https://ebookgate.com/product/aagbi-core-topics-in-
anaesthesia-2015-1st-edition-griffiths/

ebookgate.com

Data Structures Other Objects using Java 4th Edition


Michael Mann

https://ebookgate.com/product/data-structures-other-objects-using-
java-4th-edition-michael-mann/

ebookgate.com
For your convenience Apress has placed some of the front
matter material after the index. Please use the Bookmarks
and Contents at a Glance links to access them.
Contents at a Glance

About the Author���������������������������������������������������������������������������������������������������������������xiii


About the Technical Reviewers������������������������������������������������������������������������������������������ xv
Preface����������������������������������������������������������������������������������������������������������������������������� xvii

■■Chapter 1: Sorting, Searching, and Merging���������������������������������������������������������������������1


■■Chapter 2: Introduction to Objects����������������������������������������������������������������������������������29
■■Chapter 3: Linked Lists����������������������������������������������������������������������������������������������������71
■■Chapter 4: Stacks and Queues���������������������������������������������������������������������������������������111
■■Chapter 5: Recursion�����������������������������������������������������������������������������������������������������143
■■Chapter 6: Random Numbers, Games, and Simulation��������������������������������������������������167
■■Chapter 7: Working with Files���������������������������������������������������������������������������������������189
■■Chapter 8: Introduction to Binary Trees������������������������������������������������������������������������219
■■Chapter 9: Advanced Sorting�����������������������������������������������������������������������������������������259
■■Chapter 10: Hashing������������������������������������������������������������������������������������������������������287

Index���������������������������������������������������������������������������������������������������������������������������������309

v
Chapter 1

Sorting, Searching, and Merging

In this chapter, we will explain the following:


• How to sort a list of items using selection sort
• How to sort a list of items using insertion sort
• How to add a new item to a sorted list so that the list remains sorted
• How to sort an array of strings
• How to sort related (parallel) arrays
• How to search a sorted list using binary search
• How to search an array of strings
• How to write a program to do a frequency count of words in a passage
• How to merge two sorted lists to create one sorted list

1.1 Sorting an Array: Selection Sort


Sorting is the process by which a set of values are arranged in ascending or descending order. There are many reasons
to sort. Sometimes we sort in order to produce more readable output (for example, to produce an alphabetical listing).
A teacher may need to sort her students in order by name or by average score. If we have a large set of values and we
want to identify duplicates, we can do so by sorting; the repeated values will come together in the sorted list.
Another advantage of sorting is that some operations can be performed faster and more efficiently with sorted
data. For example, if data is sorted, it is possible to search it using binary search—this is much faster than using a
sequential search. Also, merging two separate lists of items can be done much faster than if the lists were unsorted.
There are many ways to sort. In this chapter, we will discuss two of the “simple” methods: selection and insertion
sort. In Chapter 9, we will look at more sophisticated ways to sort. We start with selection sort.
Consider the following list of numbers stored in a Java array, num:

1
Chapter 1 ■ Sorting, Searching, and Merging

Sorting num in ascending order using selection sort proceeds as follows:


1st pass
• Find the smallest number in the entire list, from positions 0 to 6; the smallest is 15,
found in position 4.
• Interchange the numbers in positions 0 and 4. This gives us the following:

2nd pass
• Find the smallest number in positions 1 to 6; the smallest is 33, found in position 5.
• Interchange the numbers in positions 1 and 5. This gives us the following:

3rd pass
• Find the smallest number in positions 2 to 6; the smallest is 48, found in position 5.
• Interchange the numbers in positions 2 and 5. This gives us the following:

4th pass
• Find the smallest number in positions 3 to 6; the smallest is 52, found in position 6.
• Interchange the numbers in positions 3 and 6. This gives us the following:

5th pass
• Find the smallest number in positions 4 to 6; the smallest is 57, found in position 4.
• Interchange the numbers in positions 4 and 4. This gives us the following:

2
Chapter 1 ■ Sorting, Searching, and Merging

6th pass
• Find the smallest number in positions 5 to 6; the smallest is 65, found in position 6.
• Interchange the numbers in positions 5 and 6. This gives us the following:

The array is now completely sorted. Note that once the 6th largest (65) has been placed in its final position (5),
the largest (79) would automatically be in the last position (6).
In this example, we made six passes. We will count these passes by letting the variable h go from 0 to 5. On each
pass, we find the smallest number from positions h to 6. If the smallest number is in position s, we interchange the
numbers in positions h and s.
In general, for an array of size n, we make n-1 passes. In our example, we sorted 7 numbers in 6 passes.
The following is a pseudocode outline of the algorithm for sorting num[0..n-1]:

for h = 0 to n - 2
s = position of smallest number from num[h] to num[n-1]
swap num[h] and num[s]
endfor

We can implement this algorithm as follows, using the generic parameter list:

public static void selectionSort(int[] list, int lo, int hi) {


//sort list[lo] to list[hi] in ascending order
for (int h = lo; h < hi; h++) {
int s = getSmallest(list, h, hi);
swap(list, h, s);
}
}

The two statements in the for loop could be replaced by the following:

swap(list, h, getSmallest(list, h, hi));

We can write getSmallest and swap as follows:

public static int getSmallest(int list[], int lo, int hi) {


//return location of smallest from list[lo..hi]
int small = lo;
for (int h = lo + 1; h <= hi; h++)
if (list[h] < list[small]) small = h;
return small;
}

public static void swap(int list[], int i, int j) {


//swap elements list[i] and list[j]
int hold = list[i];
list[i] = list[j];
list[j] = hold;
}

3
Chapter 1 ■ Sorting, Searching, and Merging

To test whether selectionSort works properly, we write Program P1.1. Only main is shown. To complete the
program, just add selectionSort, getSmallest, and swap.

Program P1.1
import java.util.*;
public class SelectSortTest {
final static int MaxNumbers = 10;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] num = new int[MaxNumbers];
System.out.printf("Type up to %d numbers followed by 0\n", MaxNumbers);
int n = 0;
int v = in.nextInt();
while (v != 0 && n < MaxNumbers) {
num[n++] = v;
v = in.nextInt();
}
if (v != 0) {
System.out.printf("\nMore than %d numbers entered\n", MaxNumbers);
System.out.printf("First %d used\n", MaxNumbers);
}
if (n == 0) {
System.out.printf("\nNo numbers supplied\n");
System.exit(1);
}
//n numbers are stored from num[0] to num[n-1]
selectionSort(num, 0, n-1);
System.out.printf("\nThe sorted numbers are\n");
for (v = 0; v < n; v++) System.out.printf("%d ", num[v]);
System.out.printf("\n");
} //end main

// selectionSort, getSmallest and swap go here

} //end class SelectSortTest

The program requests up to 10 numbers (as defined by MaxNumbers), stores them in the array num, calls
selectionSort, and then prints the sorted list.
The following is a sample run of the program:

Type up to 10 numbers followed by 0


57 48 79 65 15 33 52 0

The sorted numbers are


15 33 48 52 57 65 79

Note that if the user enters more than ten numbers, the program will recognize this and sort only the first ten.

4
Chapter 1 ■ Sorting, Searching, and Merging

1.1.1 Analysis of Selection Sort


To find the smallest of k items, we make k-1 comparisons. On the first pass, we make n-1 comparisons to find the
smallest of n items. On the second pass, we make n-2 comparisons to find the smallest of n-1 items. And so on, until
the last pass where we make one comparison to find the smaller of two items. In general, on the jth pass, we make n-j
comparisons to find the smallest of n-j+1 items. Hence, we have this:

total number of comparisons = 1 + 2 + …+ n-1 = ½ n(n-1) » ½ n2

We say selection sort is of order O(n2) (“big O n squared”). The constant ½ is not important in “big O” notation
since, as n gets very big, the constant becomes insignificant.
On each pass, we swap two items using three assignments. Since we make n-1 passes, we make 3(n-1)
assignments in all. Using “big O” notation, we say that the number of assignments is O(n). The constants 3 and 1 are
not important as n gets large.
Does selection sort perform any better if there is order in the data? No. One way to find out is to give it a sorted list
and see what it does. If you work through the algorithm, you will see that the method is oblivious to order in the data.
It will make the same number of comparisons every time, regardless of the data.
As we will see, some sorting methods (mergesort and quicksort; see Chapters 5 and 9) require extra array storage to
implement them. Note that selection sort is performed “in place” in the given array and does not require additional storage.
As an exercise, modify the programming code so that it counts the number of comparisons and assignments
made in sorting a list using selection sort.

1.2 Sorting an Array: Insertion Sort


Consider the same array as before:

Now, think of the numbers as cards on a table that are picked up one at a time in the order they appear in the
array. Thus, we first pick up 57, then 48, then 79, and so on, until we pick up 52. However, as we pick up each new
number, we add it to our hand in such a way that the numbers in our hand are all sorted.
When we pick up 57, we have just one number in our hand. We consider one number to be sorted.
When we pick up 48, we add it in front of 57 so our hand contains the following:
48 57
When we pick up 79, we place it after 57 so our hand contains this:
48 57 79
When we pick up 65, we place it after 57 so our hand contains this:
48 57 65 79
At this stage, four numbers have been picked up, and our hand contains them in sorted order.
When we pick up 15, we place it before 48 so our hand contains this:
15 48 57 65 79
When we pick up 33, we place it after 15 so our hand contains this:
15 33 48 57 65 79
Finally, when we pick up 52, we place it after 48 so our hand contains this:
15 33 48 52 57 65 79

5
Chapter 1 ■ Sorting, Searching, and Merging

The numbers have been sorted in ascending order.


The method described illustrates the idea behind insertion sort. The numbers in the array will be processed one
at a time, from left to right. This is equivalent to picking up the numbers from the table one at a time. Since the first
number, by itself, is sorted, we will process the numbers in the array starting from the second.
When we come to process num[h], we can assume that num[0] to num[h-1] are sorted. We insert num[h] among
num[0] to num[h-1] so that num[0] to num[h] are sorted. We then go on to process num[h+1]. When we do so, our
assumption that num[0] to num[h] are sorted will be true.
Sorting num in ascending order using insertion sort proceeds as follows:

1st pass
• Process num[1], that is, 48. This involves placing 48 so that the first two numbers are sorted;
num[0] and num[1] now contain the following:

The rest of the array remains unchanged.

2nd pass
• Process num[2], that is, 79. This involves placing 79 so that the first three numbers are sorted;
num[0] to num[2] now contain the following:

The rest of the array remains unchanged.

3rd pass
• Process num[3], that is, 65. This involves placing 65 so that the first four numbers are sorted;
num[0] to num[3] now contain the following:

The rest of the array remains unchanged.

4th pass
• Process num[4], that is, 15. This involves placing 15 so that the first five numbers are sorted.
To simplify the explanation, think of 15 as being taken out and stored in a simple variable
(key, say) leaving a “hole” in num[4]. We can picture this as follows:

6
Chapter 1 ■ Sorting, Searching, and Merging

The insertion of 15 in its correct position proceeds as follows:


• Compare 15 with 79; it is smaller, so move 79 to location 4, leaving location 3 free.
This gives the following:

• Compare 15 with 65; it is smaller, so move 65 to location 3, leaving location 2 free.


This gives the following:

• Compare 15 with 57; it is smaller, so move 57 to location 2, leaving location 1 free.


This gives the following:

• Compare 15 with 48; it is smaller, so move 48 to location 1, leaving location 0 free.


This gives the following:

• There are no more numbers to compare with 15, so it is inserted in location 0,


giving the following:

• We can express the logic of placing 15 (key) by comparing it with the numbers to its left,
starting with the nearest one. As long as key is less than num[k], for some k, we move num[k] to
position num[k + 1] and move on to consider num[k-1], providing it exists. It won’t exist when
k is actually 0. In this case, the process stops, and key is inserted in position 0.
5th pass
• Process num[5], that is, 33. This involves placing 33 so that the first six numbers are sorted.
This is done as follows:
• Store 33 in key, leaving location 5 free.
• Compare 33 with 79; it is smaller, so move 79 to location 5, leaving location 4 free.
• Compare 33 with 65; it is smaller, so move 65 to location 4, leaving location 3 free.
• Compare 33 with 57; it is smaller, so move 57 to location 3, leaving location 2 free.
• Compare 33 with 48; it is smaller, so move 48 to location 2, leaving location 1 free.

7
Chapter 1 ■ Sorting, Searching, and Merging

• Compare 33 with 15; it is bigger, so insert 33 in location 1. This gives the following:

• We can express the logic of placing 33 by comparing it with the numbers to its left, starting
with the nearest one. As long as key is less than num[k], for some k, we move num[k] to
position num[k + 1] and move on to consider num[k-1], providing it exists. If key is greater
than or equal to num[k] for some k, then key is inserted in position k+1. Here, 33 is greater
than num[0] and so is inserted into num[1].
6th pass
• Process num[6], that is, 52. This involves placing 52 so that the first seven (all) numbers are
sorted. This is done as follows:
• Store 52 in key, leaving location 6 free.
• Compare 52 with 79; it is smaller, so move 79 to location 6, leaving location 5 free.
• Compare 52 with 65; it is smaller, so move 65 to location 5, leaving location 4 free.
• Compare 52 with 57; it is smaller, so move 57 to location 4, leaving location 3 free.
• Compare 52 with 48; it is bigger; so insert 52 in location 3. This gives the following:

The array is now completely sorted.


The following is an outline of how to sort the first n elements of an array, num, using insertion sort:

for h = 1 to n - 1 do
insert num[h] among num[0] to num[h-1] so that num[0] to num[h] are sorted
endfor

Using this outline, we write the function insertionSort using the parameter list.

public static void insertionSort(int list[], int n) {


//sort list[0] to list[n-1] in ascending order
for (int h = 1; h < n; h++) {
int key = list[h];
int k = h - 1; //start comparing with previous item
while (k >= 0 && key < list[k]) {
list[k + 1] = list[k];
--k;
}
list[k + 1] = key;
} //end for
} //end insertionSort

The while statement is at the heart of the sort. It states that as long as we are within the array (k >= 0) and
the current number (key) is less than the one in the array (key < list[k]), we move list[k] to the right
(list[k+1] = list[k]) and move on to the next number on the left (--k).

8
Chapter 1 ■ Sorting, Searching, and Merging

We exit the while loop if k is equal to -1 or if key is greater than or equal to list[k], for some k. In either case,
key is inserted into list[k+1].
If k is -1, it means that the current number is smaller than all the previous numbers in the list and must be
inserted in list[0]. But list[k + 1] is list[0] when k is -1, so key is inserted correctly in this case.
The function sorts in ascending order. To sort in descending order, all we have to do is change < to > in the while
condition, like this:

while (k >= 0 && key > list[k])

Now, a key moves to the left if it is bigger.


We write Program P1.2 to test whether insertionSort works correctly. Only main is shown. Adding the function
insertionSort completes the program.

Program P1.2
import java.util.*;
public class InsertSortTest {
final static int MaxNumbers = 10;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] num = new int[MaxNumbers];
System.out.printf("Type up to %d numbers followed by 0\n", MaxNumbers);
int n = 0;
int v = in.nextInt();
while (v != 0 && n < MaxNumbers) {
num[n++] = v;
v = in.nextInt();
}
if (v != 0) {
System.out.printf("\nMore than %d numbers entered\n", MaxNumbers);
System.out.printf("First %d used\n", MaxNumbers);
}
if (n == 0) {
System.out.printf("\nNo numbers supplied\n");
System.exit(1);
}
//n numbers are stored from num[0] to num[n-1]
insertionSort(num, n);
System.out.printf("\nThe sorted numbers are\n");
for (v = 0; v < n; v++) System.out.printf("%d ", num[v]);
System.out.printf("\n");
} //end main

public static void insertionSort(int list[], int n) {


//sort list[0] to list[n-1] in ascending order
for (int h = 1; h < n; h++) {
int key = list[h];
int k = h - 1; //start comparing with previous item
while (k >= 0 && key < list[k]) {
list[k + 1] = list[k];
--k;
}

9
Chapter 1 ■ Sorting, Searching, and Merging

list[k + 1] = key;
} //end for
} //end insertionSort
  
} //end class InsertSortTest

The program requests up to ten numbers (as defined by MaxNumbers), stores them in the array num, calls
insertionSort, and then prints the sorted list.
The following is a sample run of the program:

Type up to 10 numbers followed by 0


57 48 79 65 15 33 52 0
The sorted numbers are
15 33 48 52 57 65 79

Note that if the user enters more than ten numbers, the program will recognize this and sort only the first ten.
We could easily generalize insertionSort to sort a portion of a list. To illustrate, we rewrite insertionSort
(calling it insertionSort1) to sort list[lo] to list[hi] where lo and hi are passed as arguments to the function.
Since element lo is the first one, we start processing elements from lo+1 until element hi. This is reflected in the
for statement. Also now, the lowest subscript is lo, rather than 0. This is reflected in the while condition k >= lo.
Everything else remains the same as before.

public static void insertionSort1(int list[], int lo, int hi) {


//sort list[lo] to list[hi] in ascending order
for (int h = lo + 1; h <= hi; h++) {
int key = list[h];
int k = h - 1; //start comparing with previous item
while (k >= lo && key < list[k]) {
list[k + 1] = list[k];
--k;
}
list[k + 1] = key;
} //end for
} //end insertionSort1

We can test insertionSort1 with Program P1.2a.

Program P1.2a
import java.util.*;
public class InsertSort1Test {
final static int MaxNumbers = 10;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] num = new int[MaxNumbers];
System.out.printf("Type up to %d numbers followed by 0\n", MaxNumbers);
int n = 0;
int v = in.nextInt();
while (v != 0 && n < MaxNumbers) {
num[n++] = v;
v = in.nextInt();
}

10
Chapter 1 ■ Sorting, Searching, and Merging

if (v != 0) {
System.out.printf("\nMore than %d numbers entered\n", MaxNumbers);
System.out.printf("First %d used\n", MaxNumbers);
}
if (n == 0) {
System.out.printf("\nNo numbers supplied\n");
System.exit(1);
}
//n numbers are stored from num[0] to num[n-1]
insertionSort1(num, 0, n-1);
System.out.printf("\nThe sorted numbers are\n");
for (v = 0; v < n; v++) System.out.printf("%d ", num[v]);
System.out.printf("\n");
} //end main

// insertionSort1 goes here

} //end class InsertSort1Test

1.2.1 Analysis of Insertion Sort


In processing item j, we can make as few as 1 comparison (if num[j] is bigger than num[j-1]) or as many as j-1
comparisons (if num[j] is smaller than all the previous items). For random data, we would expect to make ½(j-1)
comparisons, on average. Hence, the average total number of comparisons to sort n items is:

∑ 2 ( j − 1) = ½ {1 + 2 + ... + n − 1} = ¼ n (n − 1) ≈ ¼ n
1 2

j =2

We say insertion sort is of order O(n2) (“big O n squared”). The constant ¼ is not important as n gets large.
Each time we make a comparison, we also make an assignment. Hence, the total number of assignments is also
¼ n(n-1) » ¼ n2.
We emphasize that this is an average for random data. Unlike selection sort, the actual performance of insertion
sort depends on the data supplied. If the given array is already sorted, insertion sort will quickly determine this by
making n-1 comparisons. In this case, it runs in O(n) time. One would expect that insertion sort will perform better
the more order there is in the data.
If the given data is in descending order, insertion sort performs at its worst since each new number has to travel
all the way to the beginning of the list. In this case, the number of comparisons is ½ n(n-1) » ½ n2. The number of
assignments is also ½ n(n-1) » ½ n2.
Thus, the number of comparisons made by insertion sort ranges from n-1 (best) to ¼ n2 (average) to ½ n2 (worst).
The number of assignments is always the same as the number of comparisons.
As with selection sort, insertion sort does not require extra array storage for its implementation.
As an exercise, modify the programming code so that it counts the number of comparisons and assignments
made in sorting a list using insertion sort.

11
Chapter 1 ■ Sorting, Searching, and Merging

1.3 Inserting an Element in Place


Insertion sort uses the idea of adding a new element to an already sorted list so that the list remains sorted. We can
treat this as a problem in its own right (nothing to do with insertion sort). Specifically, given a sorted list of items from
list[m] to list[n], we want to add a new item (newItem, say) to the list so that list[m] to list[n+1] are sorted.
Adding a new item increases the size of the list by 1. We assume that the array has room to hold the new item.
We write the function insertInPlace to solve this problem.

public static void insertInPlace(int newItem, int list[], int m, int n) {


//list[m] to list[n] are sorted
//insert newItem so that list[m] to list[n+1] are sorted
int k = n;
while (k >= m && newItem < list[k]) {
list[k + 1] = list[k];
--k;
}
list[k + 1] = newItem;
} //end insertInPlace

Using insertInPlace, we can rewrite insertionSort (calling it insertionSort2) as follows:

public static void insertionSort2(int list[], int lo, int hi) {


//sort list[lo] to list[hi] in ascending order
for (int h = lo + 1; h <= hi; h++)
insertInPlace(list[h], list, lo, h - 1);
} //end insertionSort2

We can test insertionSort2 with Program P1.2b.

Program P1.2b
import java.util.*;
public class InsertSort2Test {
final static int MaxNumbers = 10;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] num = new int[MaxNumbers];
System.out.printf("Type up to %d numbers followed by 0\n", MaxNumbers);
int n = 0;
int v = in.nextInt();
while (v != 0 && n < MaxNumbers) {
num[n++] = v;
v = in.nextInt();
}
if (v != 0) {
System.out.printf("\nMore than %d numbers entered\n", MaxNumbers);
System.out.printf("First %d used\n", MaxNumbers);
}
if (n == 0) {
System.out.printf("\nNo numbers supplied\n");
System.exit(1);
}

12
Chapter 1 ■ Sorting, Searching, and Merging

//n numbers are stored from num[0] to num[n-1]


insertionSort2(num, 0, n-1);
System.out.printf("\nThe sorted numbers are\n");
for (v = 0; v < n; v++) System.out.printf("%d ", num[v]);
System.out.printf("\n");
} //end main

public static void insertionSort2(int list[], int lo, int hi) {


//sort list[lo] to list[hi] in ascending order
for (int h = lo + 1; h <= hi; h++)
insertInPlace(list[h], list, lo, h - 1);
} //end insertionSort2

public static void insertInPlace(int newItem, int list[], int m, int n) {


//list[m] to list[n] are sorted
//insert newItem so that list[m] to list[n+1] are sorted
int k = n;
while (k >= m && newItem < list[k]) {
list[k + 1] = list[k];
--k;
}
list[k + 1] = newItem;
} //end insertInPlace

} //end class InsertSort2Test

1.4 Sorting a String Array


Consider the problem of sorting a list of names in alphabetical order. In Java, a name is stored in a String variable,
and we’ll need a String array to store the list. For the most part, we can work with String as if it were a primitive
type, but it is sometimes useful to remember that, strictly speaking, it is a class. Where necessary, we will point out
the distinction.
One difference that concerns us here is that we cannot use the relational operators (==, <, >, and so on) to
compare strings. We must use functions from the String class (or write our own). Common functions include equals,
equalsIgnoreCase, compareTo, and compareToIgnoreCase. We write a function to sort an array of strings using
insertion sort. We call it insertionSort3.

public static void insertionSort3(String[] list, int lo, int hi) {


//sort list[lo] to list[hi] in ascending order
for (int h = lo + 1; h <= hi; h++) {
String key = list[h];
int k = h - 1; //start comparing with previous item
while (k >= lo && key.compareToIgnoreCase(list[k]) < 0) {
list[k + 1] = list[k];
--k;
}
list[k + 1] = key;
} //end for
} //end insertionSort3

13
Chapter 1 ■ Sorting, Searching, and Merging

The function is pretty much the same as the previous ones except for the declaration of list and the use of
compareToIgnoreCase to compare two strings. If case matters, you can use compareTo.
We test insertionSort3 with Program P1.3.

Program P1.3
import java.util.*;
public class SortStrings {
final static int MaxNames = 8;
public static void main(String[] args) {
String name[] = {"Graham, Ariel", "Perrott, Chloe",
"Charles, Kandice", "Seecharan, Anella", "Reyes, Aaliyah",
"Graham, Ashleigh", "Reyes, Ayanna", "Greaves, Sherrelle" };

insertionSort3(name, 0, MaxNames - 1);

System.out.printf("\nThe sorted names are\n\n");


for (int h = 0; h < MaxNames; h++)
System.out.printf("%s\n", name[h]);
} //end main

// insertionSort3 goes here

} //end class SortStrings

When run, Program P1.3 produced the following output:

The sorted names are

Charles, Kandice
Graham, Ariel
Graham, Ashleigh
Greaves, Sherrelle
Perrott, Chloe
Reyes, Aaliyah
Reyes, Ayanna
Seecharan, Anella

1.5 Sorting Parallel Arrays


It is quite common to have related information in different arrays. For example, suppose, in addition to name, we have
an integer array id such that id[h] is an identification number associated with name[h], as shown in Figure 1-1.

14
Chapter 1 ■ Sorting, Searching, and Merging

name id

0 Graham, Ariel 3050


1 Perrott, Chloe 2795
2 Charles, Kandice 4455
3 Seecharan, Anella 7824
4 Reyes, Aaliyah 6669
5 Graham, Ashleigh 5000
6 Reyes, Ayanna 5464
7 Greaves, Sherrelle 6050

Figure 1-1. Two arrays with related information

Consider the problem of sorting the names in alphabetical order. At the end, we would want each name to have
its correct ID number. So, for example, after the sorting is done, name[0] should contain “Charles, Kandice” and id[0]
should contain 4455.
To achieve this, each time a name is moved during the sorting process, the corresponding ID number must also
be moved. Since the name and ID number must be moved “in parallel,” we say we are doing a “parallel sort” or we are
sorting “parallel arrays.”
We rewrite insertionSort3 to illustrate how to sort parallel arrays. We simply add the code to move an ID
whenever a name is moved. We call it parallelSort.

public static void parallelSort(String[] list, int id[], int lo, int hi) {
//Sort the names in list[lo] to list[hi] in alphabetical order,
//ensuring that each name remains with its original id number.
for (int h = lo + 1; h <= hi; h++) {
String key = list[h];
int m = id[h]; // extract the id number
int k = h - 1; //start comparing with previous item
while (k >= lo && key.compareToIgnoreCase(list[k]) < 0) {
list[k + 1] = list[k];
id[k+ 1] = id[k]; //move up id number when we move a name
--k;
}
list[k + 1] = key;
id[k + 1] = m; //store the id number in the same position as the name
} //end for
} //end parallelSort

We test parallelSort by writing Program P1.4.

Program P1.4
import java.util.*;
public class ParallelSort {
final static int MaxNames = 8;
public static void main(String[] args) {
String name[] = {"Graham, Ariel", "Perrott, Chloe",
"Charles, Kandice", "Seecharan, Anella", "Reyes, Aaliyah",
"Graham, Ashleigh", "Reyes, Ayanna", "Greaves, Sherrelle" };
int id[] = {3050,2795,4455,7824,6669,5000,5464,6050};

parallelSort(name, id, 0, MaxNames - 1);

15
Chapter 1 ■ Sorting, Searching, and Merging

System.out.printf("\nThe sorted names and IDs are\n\n");


for (int h = 0; h < MaxNames; h++)
System.out.printf("%-20s %d\n", name[h], id[h]);
} //end main

// parallelSort goes here

} //end class ParallelSort

When Program P1.4 was run, it produced the following output:

The sorted names and IDs are

Charles, Kandice 4455


Graham, Ariel 3050
Graham, Ashleigh 5000
Greaves, Sherrelle 6050
Perrott, Chloe 2795
Reyes, Aaliyah 6669
Reyes, Ayanna 5464
Seecharan, Anella 7824

We note, in passing, that if we have several sets of related items to process, storing each set in a separate array
would not be the best way to proceed. It would be better to group the items in a class and work with the group as we
would a single item. We’ll show you how to do this in Section 2.14.

1.6 Binary Search


Binary search is a fast method for searching a list of items for a given one, providing the list is sorted (either ascending
or descending). To illustrate the method, consider a list of 13 numbers, sorted in ascending order and stored in an
array num[0..12].

Suppose we want to search for 66. The search proceeds as follows:


1. We find the middle item in the list. This is 56 in position 6. We compare 66 with 56. Since 66
is bigger, we know that if 66 is in the list at all, it must be after position 6, since the numbers
are in ascending order. In our next step, we confine our search to locations 7 to 12.
2. We find the middle item from locations 7 to 12. In this case, we can choose either item 9 or
item 10. The algorithm we will write will choose item 9, that is, 78.
3. We compare 66 with 78. Since 66 is smaller, we know that if 66 is in the list at all, it must be
before position 9, since the numbers are in ascending order. In our next step, we confine
our search to locations 7 to 8.
4. We find the middle item from locations 7 to 8. In this case, we can choose either item 7 or
item 8. The algorithm we will write will choose item 7, that is, 66.
5. We compare 66 with 66. Since they are the same, our search ends successfully, finding the
required item in position 7.
16
Chapter 1 ■ Sorting, Searching, and Merging

Suppose we were searching for 70. The search will proceed as described above until we compare 70 with 66
(in location 7).
• Since 70 is bigger, we know that if 70 is in the list at all, it must be after position 7, since the
numbers are in ascending order. In our next step, we confine our search to locations 8 to 8.
This is just one location.
• We compare 70 with item 8, that is, 72. Since 70 is smaller, we know that if 70 is in the list at
all, it must be before position 8. Since it can’t be after position 7 and before position 8, we
conclude that it is not in the list.
At each stage of the search, we confine our search to some portion of the list. Let us use the variables lo and hi
as the subscripts that define this portion. In other words, our search will be confined to num[lo] to num[hi].
Initially, we want to search the entire list so that we will set lo to 0 and hi to 12, in this example.
How do we find the subscript of the middle item? We will use the following calculation:
mid = (lo + hi) / 2;

Since integer division will be performed, the fraction, if any, is discarded. For example, when lo is 0 and hi is 12,
mid becomes 6; when lo is 7 and hi is 12, mid becomes 9; and when lo is 7 and hi is 8, mid becomes 7.
As long as lo is less than or equal to hi, they define a nonempty portion of the list to be searched. When lo is
equal to hi, they define a single item to be searched. If lo ever gets bigger than hi, it means we have searched the
entire list and the item was not found.
Based on these ideas, we can now write a function binarySearch. To be more general, we will write it so that the
calling routine can specify which portion of the array it wants the search to look for the item.
Thus, the function must be given the item to be searched for (key), the array (list), the start position of the
search (lo), and the end position of the search (hi). For example, to search for the number 66 in the array num, above,
we can issue the call binarySearch(66, num, 0, 12).
The function must tell us the result of the search. If the item is found, the function will return its location. If not
found, it will return -1.

public static int binarySearch(int key, int[] list, int lo, int hi) {
//search for key from list[lo] to list[hi]
//if found, return its location; otherwise, return -1
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (key == list[mid]) return mid; // found
if (key < list[mid]) hi = mid - 1;
else lo = mid + 1;
}
return -1; //lo and hi have crossed; key not found
}

If item contains a number to be searched for, we can write code as follows:

int ans = binarySearch(item, num, 0, 12);


if (ans == -1) System.out.printf("%d not found\n", item);
else System.out.printf("%d found in location %d\n", item, ans);

If we want to search for item from locations i to j, we can write the following:

int ans = binarySearch(item, num, i, j);

17
Chapter 1 ■ Sorting, Searching, and Merging

We can test binarySearch with Program P1.5.

Program P1.5
public class BinarySearchTest {
public static void main(String[] args) {
int[] num = {17, 24, 31, 39, 44, 49, 56, 66, 72, 78, 83, 89, 96};
int n = binarySearch(66, num, 0, 12);
System.out.printf("%d\n", n); //will print 7; 66 in pos. 7
n = binarySearch(66, num, 0, 6);
System.out.printf("%d\n", n); //will print -1; 66 not in 0 to 6
n = binarySearch(70, num, 0, 12);
System.out.printf("%d\n", n); //will print -1; 70 not in list
n = binarySearch(89, num, 5, 12);
System.out.printf("%d\n", n); //will print 11; 89 in pos. 11
} //end main

// binarySearch goes here


} //end class BinarySearchTest

When run, the program will print the following:

7
-1
-1
11

1.7 Searching an Array of Strings


We can search a sorted array of strings (names in alphabetical order, say) using the same technique we used for
searching an integer array. The major differences are in the declaration of the array and the use of the String function
compareTo, rather than == or <, to compare two strings. The following is the string version of binarySearch:

public static int binarySearch(String key, String[] list, int lo, int hi) {
//search for key from list[lo] to list[hi]
//if found, return its location; otherwise, return -1
while (lo <= hi) {
int mid = (lo + hi) / 2;
int cmp = key.compareTo(list[mid]);
if (cmp == 0) return mid; // search succeeds
if (cmp < 0) hi = mid -1; // key is ‘less than’ list[mid]
else lo = mid + 1; // key is ‘greater than’ list[mid]
}
return -1; //lo and hi have crossed; key not found
} //end binarySearch

Since we need to know whether one string is equal to, or less than, another, it is best to use the compareTo
method.

18
Chapter 1 ■ Sorting, Searching, and Merging

Note that we call compareTo only once. The value returned (cmp) tells us all we need to know. If we are
comparing words or names and we want the case of the letters to be ignored in the comparison, we can use
compareToIgnoreCase.
The function can be tested with Program P1.6.

Program P1.6
import java.util.*;
public class BinarySearchString {
final static int MaxNames = 8;
public static void main(String[] args) {
String name[] = {"Charles, Kandice", "Graham, Ariel",
"Graham, Ashleigh", "Greaves, Sherrelle", "Perrott, Chloe",
"Reyes, Aaliyah", "Reyes, Ayanna", "Seecharan, Anella"};

int n = binarySearch("Charles, Kandice", name, 0, MaxNames - 1);


System.out.printf("%d\n", n);
//will print 0, location of Charles, Kandice

n = binarySearch("Reyes, Ayanna", name, 0, MaxNames - 1);


System.out.printf("%d\n", n);
//will print 6, location of Reyes, Ayanna

n = binarySearch("Perrott, Chloe", name, 0, MaxNames - 1);


System.out.printf("%d\n", n);
//will print 4, location of Perrott, Chloe

n = binarySearch("Graham, Ariel", name, 4, MaxNames - 1);


System.out.printf("%d\n", n);
//will print -1, since Graham, Ariel is not in locations 4 to 7

n = binarySearch("Cato, Brittney", name, 0, MaxNames - 1);


System.out.printf("%d\n", n);
//will print -1 since Cato, Brittney is not in the list

} //end main

// binarySearch goes here

} //end class BinarySearchString

This sets up the array name with the names in alphabetical order. It then calls binarySearch with various names
and prints the result of each search.
One may wonder what might happen with a call like this:

n = binarySearch("Perrott, Chloe", name, 5, 10);

Here, we are telling binarySearch to look for "Perrott, Chloe" in locations 5 to 10 of the given array. However,
locations 8 to 10 do not exist in the array. The result of the search will be unpredictable. The program may crash or
return an incorrect result. The onus is on the calling program to ensure that binarySearch (or any other function) is
called with valid arguments.

19
Chapter 1 ■ Sorting, Searching, and Merging

1.8 Example: Word Frequency Count


Let’s write a program to read an English passage and count the number of times each word appears. Output consists
of an alphabetical listing of the words and their frequencies.
We can use the following outline to develop our program:

while there is input


get a word
search for word
if word is in the table
add 1 to its count
else
add word to the table
set its count to 1
endif
endwhile
print table

This is a typical “search and insert” situation. We search for the next word among the words stored so far. If the search
succeeds, the only thing to do is increment its count. If the search fails, the word is put in the table and its count set to 1.
A major design decision here is how to search the table, which, in turn, will depend on where and how a new
word is inserted in the table. The following are two possibilities:
1. A new word is inserted in the next free position in the table. This implies that a sequential
search must be used to look for an incoming word since the words would not be in any
particular order. This method has the advantages of simplicity and easy insertion, but
searching takes longer as more words are put in the table.
2. A new word is inserted in the table in such a way that the words are always in alphabetical
order. This may entail moving words that have already been stored so that the new word
may be slotted in the right place. However, since the table is in order, a binary search can
be used to search for an incoming word.
For (2), searching is faster, but insertion is slower than in (1). Since, in general, searching is done more frequently
than inserting, (2) might be preferable.
Another advantage of (2) is that, at the end, the words will already be in alphabetical order and no sorting will be
required. If (1) is used, the words will need to be sorted to obtain the alphabetical order.
We will write our program using the approach in (2). The complete program is shown as Program P1.7.

Program P1.7
import java.io.*;
import java.util.*;
public class WordFrequency {
final static int MaxWords = 50;
public static void main(String[] args) throws IOException {
String[] wordList = new String[MaxWords];
int[] frequency = new int[MaxWords];
FileReader in = new FileReader("passage.txt");
PrintWriter out = new PrintWriter(new FileWriter("output.txt"));

for (int h = 0; h < MaxWords; h++) {


frequency[h] = 0;
wordList[h] = "";
}

20
Chapter 1 ■ Sorting, Searching, and Merging

int numWords = 0;
String word = getWord(in).toLowerCase();
while (!word.equals("")) {
int loc = binarySearch(word, wordList, 0, numWords-1);
if (word.compareTo(wordList[loc]) == 0) ++frequency[loc]; //word found
else //this is a new word
if (numWords < MaxWords) { //if table is not full
addToList(word, wordList, frequency, loc, numWords-1);
++numWords;
}
else out.printf("'%s' not added to table\n", word);
word = getWord(in).toLowerCase();
}
printResults(out, wordList, frequency, numWords);
in.close();
out.close();
} // end main

public static int binarySearch(String key, String[] list, int lo, int hi){
//search for key from list[lo] to list[hi]
//if found, return its location;
//if not found, return the location in which it should be inserted
//the calling program will check the location to determine if found
while (lo <= hi) {
int mid = (lo + hi) / 2;
int cmp = key.compareTo(list[mid]);
if (cmp == 0) return mid; // search succeeds
if (cmp < 0) hi = mid -1; // key is 'less than' list[mid]
else lo = mid + 1; // key is 'greater than' list[mid]
}
return lo; //key must be inserted in location lo
} //end binarySearch

public static void addToList(String item, String[] list, int[] freq, int p, int n) {
//adds item in position list[p]; sets freq[p] to 1
//shifts list[n] down to list[p] to the right
for (int h = n; h >= p; h--) {
list[h + 1] = list[h];
freq[h + 1] = freq[h];
}
list[p] = item;
freq[p] = 1;
} //end addToList

public static void printResults(PrintWriter out, String[] list, int freq[], int n) {
out.printf("\nWords Frequency\n\n");
for (int h = 0; h < n; h++)
out.printf("%-20s %2d\n", list[h], freq[h]);
} //end printResults

21
Chapter 1 ■ Sorting, Searching, and Merging

public static String getWord(FileReader in) throws IOException {


//returns the next word found
final int MaxLen = 255;
int c, n = 0;
char[] word = new char[MaxLen];
// read over non-letters
while (!Character.isLetter((char) (c = in.read())) && (c != -1)) ;
//empty while body
if (c == -1) return ""; //no letter found
word[n++] = (char) c;
while (Character.isLetter(c = in.read()))
if (n < MaxLen) word[n++] = (char) c;
return new String(word, 0, n);
} // end getWord

} //end class WordFrequency

Suppose the following data is stored in passage.txt:

Be more concerned with your character than your reputation,


because your character is what you really are,
while your reputation is merely what others think you are.
Our character is what we do when we think no one is looking.

When Program P1.7 is run, it stores its output in output.txt. Here is the output:

Words Frequency

are 2
be 1
because 1
character 3
concerned 1
do 1
is 4
looking 1
merely 1
more 1
no 1
one 1
others 1
our 1
really 1
reputation 2
than 1
think 2
we 2
what 3
when 1
while 1
with 1
you 2
your 4

22
Chapter 1 ■ Sorting, Searching, and Merging

Here are some comments on Program P1.7:


• For our purposes, we assume that a word begins with a letter and consists of letters only.
If you want to include other characters (such as a hyphen or apostrophe), you need only
change the getWord function.
• MaxWords denotes the maximum number of distinct words catered for. For testing the
program, we have used 50 for this value. If the number of distinct words in the passage
exceeds MaxWords (50, say), any words after the 50th will be read but not stored, and a message
to that effect will be printed. However, the count for a word already stored will be incremented
if it is encountered again.
• main initializes the frequency counts to 0 and the items in the String array to the empty
string. It then processes the words in the passage based on the outline shown at the start of
Section 1.8.
• getWord reads the input file and returns the next word found.
• All words are converted to lowercase so that, for instance, The and the are counted as the same
word.
• binarySearch is written so that if the word is found, its location is returned. If the word is not
found, then the location in which it should be inserted is returned. The function addToList
is given the location in which to insert a new word. Words to the right of, and including, this
location, are shifted one position to make room for the new word.

1.9 Merging Ordered Lists


Merging is the process by which two or more ordered lists are combined into one ordered list. For example, given two
lists of numbers, A and B, as follows:
A: 21 28 35 40 61 75
B: 16 25 47 54
they can be combined into one ordered list, C:
C: 16 21 25 28 35 40 47 54 61 75
The list C contains all the numbers from lists A and B. How can the merge be performed?
One way to think about it is to imagine that the numbers in the given lists are stored on cards, one per card, and
the cards are placed face up on a table, with the smallest at the top. We can imagine the lists A and B as follows:
21 16
28 25
35 47
40 54
61
75
We look at the top two cards, 21 and 16. The smaller, 16, is removed and placed in C. This exposes the number 25.
The top two cards are now 21 and 25. The smaller, 21, is removed and added to C, which now contains 16 21. This
exposes the number 28.
The top two cards are now 28 and 25. The smaller, 25, is removed and added to C, which now contains 16 21 25.
This exposes the number 47.
The top two cards are now 28 and 47. The smaller, 28, is removed and added to C, which now contains 16 21 25 28.
This exposes the number 35.

23
Chapter 1 ■ Sorting, Searching, and Merging

The top two cards are now 35 and 47. The smaller, 35, is removed and added to C, which now contains 16 21 25
28 35. This exposes the number 40.
The top two cards are now 40 and 47. The smaller, 40, is removed and added to C, which now contains 16 21 25
28 35 40. This exposes the number 61.
The top two cards are now 61 and 47. The smaller, 47, is removed and added to C, which now contains 16 21 25
28 35 40 47. This exposes the number 54.
The top two cards are now 61 and 54. The smaller, 54, is removed and added to C, which now contains 16 21 25
28 35 40 47 54. The list B has no more numbers.
We copy the remaining elements (61 75) of A to C, which now contains the following:
16 21 25 28 35 40 47 54 61 75
The merge is completed.

At each step of the merge, we compare the smallest remaining number of A with the smallest remaining number
of B. The smaller of these is added to C. If the smaller comes from A, we move on to the next number in A; if the smaller
comes from B, we move on to the next number in B.
This is repeated until all the numbers in either A or B have been used. If all the numbers in A have been used, we add
the remaining numbers from B to C. If all the numbers in B have been used, we add the remaining numbers from A to C.
We can express the logic of the merge as follows:

while (at least one number remains in both A and B) {


if (smallest in A < smallest in B)
add smallest in A to C
move on to next number in A
else
add smallest in B to C
move on to next number in B
endif
}
if (A has ended) add remaining numbers in B to C
else add remaining numbers in A to C

1.9.1 Implementing the Merge


Assume that an array A contains m numbers stored in A[0] to A[m-1] and an array B contains n numbers stored in
B[0] to B[n-1]. Assume that the numbers are stored in ascending order. We want to merge the numbers in A and B
into another array C such that C[0] to C[m+n-1] contains all the numbers in A and B sorted in ascending order.
We will use integer variables i, j, and k to subscript the arrays A, B, and C, respectively. “Moving on to the next
position” in an array can be done by adding 1 to the subscript variable. We can implement the merge with this
function:

public static int merge(int[] A, int m, int[] B, int n, int[] C) {


int i = 0; //i points to the first (smallest) number in A
int j = 0; //j points to the first (smallest) number in B
int k = -1; //k will be incremented before storing a number in C[k]
while (i < m && j < n) {
if (A[i] < B[j]) C[++k] = A[i++];
else C[++k] = B[j++];
}
if (i == m) ///copy B[j] to B[n-1] to C
for ( ; j < n; j++) C[++k] = B[j];

24
Chapter 1 ■ Sorting, Searching, and Merging

else // j == n, copy A[i] to A[m-1] to C


for ( ; i < m; i++) C[++k] = A[i];
return m + n;
} //end merge

The function takes the arguments A, m, B, n, and C, performs the merge, and returns the number of elements,
m + n, in C.
Program P1.8 shows a simple main function that tests the logic of merge. It sets up arrays A and B, calls merge,
and prints C. When run, the program prints the following:

16 21 25 28 35 40 47 54 61 75

Program P1.8
public class MergeTest {
public static void main(String[] args) {
int[] A = {21, 28, 35, 40, 61, 75}; //size 6
int[] B = {16, 25, 47, 54}; //size 4
int[] C = new int[20]; //enough to hold all the elements
int n = merge(A, 6, B, 4, C);
for (int j = 0; j < n; j++) System.out.printf("%d ", C[j]);
System.out.printf("\n");
} //end main

// merge goes here

} //end class MergeTest

As a matter of interest, we can also implement merge as follows:

public static int merge(int[] A, int m, int[] B, int n, int[] C) {


int i = 0; //i points to the first (smallest) number in A
int j = 0; //j points to the first (smallest) number in B
int k = -1; //k will be incremented before storing a number in C[k]
while (i < m || j < n) {
if (i == m) C[++k] = B[j++];
else if (j == n) C[++k] = A[i++];
else if (A[i] < B[j]) C[++k] = A[i++];
else C[++k] = B[j++];
}
return m + n;
}

The while loop expresses the following logic: as long as there is at least one element to process in either A or B,
we enter the loop. If we are finished with A (i == m), copy an element from B to C. If we are finished with B (j == n),
copy an element from A to C. Otherwise, copy the smaller of A[i] and B[j] to C. Each time we copy an element from
an array, we add 1 to the subscript for that array.
While the previous version implements the merge in a straightforward way, it seems reasonable to say that this
version is a bit neater.

25
Chapter 1 ■ Sorting, Searching, and Merging

EXERCISES 1

1. A survey of 10 pop artists is made. Each person votes for an artist by specifying the number
of the artist (a value from 1 to 10). Each voter is allowed one vote for the artist of their choice.
The vote is recorded as a number from 1 to 10. The number of voters is unknown beforehand,
but the votes are terminated by a vote of 0. Any vote that is not a number from 1 to 10 is
a spoiled vote. A file, votes.txt, contains the names of the candidates. The first name is
considered as candidate 1, the second as candidate 2, and so on. The names are followed by
the votes. Write a program to read the data and evaluate the results of the survey.
Print the results in alphabetical order by artist name and in order by votes received (most votes first).
Print all output to the file, results.txt.
2. Write a program to read names and phone numbers into two arrays. Request a name and
print the person’s phone number. Use binary search to look up the name.
3. Write a program to read English words and their equivalent Spanish words into two arrays.
Request the user to type several English words. For each, print the equivalent Spanish word.
Choose a suitable end-of-data marker. Search for the typed words using binary search.
Modify the program so that the user types Spanish words instead.
4. The median of a set of n numbers (not necessarily distinct) is obtained by arranging the
numbers in order and taking the number in the middle. If n is odd, there is a unique middle
number. If n is even, then the average of the two middle values is the median. Write a
program to read a set of n positive integers (assume n < 100) and print their median; n is not
given, but 0 indicates the end of the data.
5. The mode of a set of n numbers is the number that appears most frequently. For example, the
mode of 7 3 8 5 7 3 1 3 4 8 9 is 3. Write a program to read a set of n positive integers
(assume n < 100) and print their mode; n is not given, but 0 indicates the end of the data.
6. An array chosen contains n distinct integers arranged in no particular order. Another array
called winners contains m distinct integers arranged in ascending order. Write code to
determine how many of the numbers in chosen appear in winners.
7. A multiple-choice examination consists of 20 questions. Each question has five choices,
labeled A, B, C, D, and E. The first line of data contains the correct answers to the 20
questions in the first 20 consecutive character positions, for example:
BECDCBAADEBACBAEDDBE
Each subsequent line contains the answers for a candidate. Data on a line consists of a
candidate number (an integer), followed by one or more spaces, followed by the 20 answers
given by the candidate in the next 20 consecutive character positions. An X is used if a
candidate did not answer a particular question. You may assume all data is valid and stored
in a file exam.dat. A sample line is as follows:
4325 BECDCBAXDEBACCAEDXBE
There are at most 100 candidates. A line containing a “candidate number” 0 only indicates
the end of the data.

26
Chapter 1 ■ Sorting, Searching, and Merging

Points for a question are awarded as follows—correct answer: 4 points; wrong answer:
-1 point; no answer: 0 points.
Write a program to process the data and print a report consisting of candidate number and
the total points obtained by the candidate, in ascending order by candidate number. At the
end, print the average number of points gained by the candidates.
8. A is an array sorted in descending order. B is an array sorted in descending order. Merge A and
B into C so that C is in descending order.

9. A is an array sorted in descending order. B is an array sorted in descending order. Merge A and
B into C so that C is in ascending order.

10. A is an array sorted in ascending order. B is an array sorted in descending order. Merge A and
B into C so that C is in ascending order.

11. An array A contains integers that first increase in value and then decrease in value. Here’s an
example:

It is unknown at which point the numbers start to decrease. Write efficient code to code to
copy the numbers in A to another array B so that B is sorted in ascending order. Your code
must take advantage of the way the numbers are arranged in A.
12. Two words are anagrams if one word can be formed by rearranging all the letters of the
other word, for example: section, notices. Write a program to read two words and determine
whether they are anagrams.
Write another program to read a list of words and find all sets of words such that words
within a set are anagrams of each other.

27
Chapter 2

Introduction to Objects

In this chapter, we will explain the following:


• What is a class, an object, a field, and a method
• That an object variable does not hold an object but, rather, a pointer (or reference) to where
the object is actually located
• The distinction between a class variable (also called a static variable) and an instance variable
(also called a non-static variable)
• The distinction between a class method (also called a static method) and an instance method
(also called a non-static method)
• What the access modifiers public, private, and protected mean
• What is meant by information hiding
• How to refer to class and instance variables
• How to initialize class and instance variables
• What is a constructor and how to write one
• What is meant by overloading
• What is meant by data encapsulation
• How to write accessor and mutator methods
• How to print an object’s data in various ways
• Why the tostring() method is special in Java
• What happens when we assign an object variable to another
• What it means to compare one object variable with another
• How to compare the contents of two objects
• How a function can return more than one value using an object

29
Chapter 2 ■ Introduction to Objects

2.1 Objects
Java is considered an object-oriented programming language. The designers created it such that objects become the
center of attention. Java programs create and manipulate objects in an attempt to model how the real world operates.
For our purposes, an object is an entity that has a state and methods to manipulate that state. The state of an object is
determined by its attributes.
For example, we can think of a person as an object. A person has attributes such as name, age, gender, height,
color of hair, color of eyes, and so on. Within a program, each attribute is represented by an appropriate variable;
for instance, a String variable can represent name, an int variable can represent age, a char variable can represent
gender, a double variable can represent height, and so on.
We normally use the term field names (or, simply, fields) to refer to these variables. Thus, the state of an object is
defined by the values in its fields. In addition, we will need methods to set and/or change the values of the fields as
well as to retrieve their values. For example, if we are interested in a person’s height, we would need a method to “look
into” the object and return the value of the height field.
A car is another common example of an object. It has attributes such as manufacturer, model, seating capacity,
fuel capacity, actual fuel in the tank, mileage, type of music equipment, and speed. A book object has attributes such
as author, title, price, number of pages, type of binding (hardcover, paperback, spiral), and if it is in stock. A person,
a car, and a book are examples of concrete objects. Note, however, that an object could also represent an abstract
concept such as a department in a company or a faculty in a university.
In the previous example, we did not speak of a specific person. Rather, we spoke of a general category “person”
such that everyone in the category has the attributes mentioned. (Similar remarks apply to car and book.) In Java
terminology, “person” is a class. We think of a class as a general category (a template) from which we can create
specific objects.
An object, then, is an instance of a class; in this example, a Person object would refer to a specific person. To work
with two Person objects, we would need to create two objects from the class definition of Person. Each object would
have its own copy of the field variables (also called instance variables); the values of the variables in one object could
be different from the values of the variables in the other object.

2.2 Defining Classes and Creating Objects


The simplest Java programs consist of a single class. Within the class, we write one or more methods/functions to
perform some task. Program P2.1 shows an example.

Program P2.1
//prompt for two numbers and find their sum
import java.util.*;
public class Sum {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.printf("Enter first number: ");
int a = in.nextInt();
System.out.printf("Enter second number: ");
int b = in.nextInt();
System.out.printf("%d + %d = %d\n", a, b, a + b);
}
} //end class Sum

The program consists of one class (ProgramP1_1) and one method (main) within the class. The class is used
simply as the framework within which to write the logic of the program. We will now show how to define and use a
class to create (we say instantiate) objects.

30
Chapter 2 ■ Introduction to Objects

In Java, every object belongs to some class and can be created from the class definition only. Consider the
following (partial) definition of the class Book:

public class Book {


private static double Discount = 0.25; //class variable
private static int MinBooks = 5; //class variable

private String author; // instance variable


private String title; // instance variable
private double price; // instance variable
private int pages; // instance variable
private char binding; // instance variable
private boolean inStock; // instance variable

// methods to manipulate book data go here


} //end class Book

The class header (the first line) consists of the following:


• An optional access modifier; public is used in the example and will be used for most of our
classes. Essentially it means that the class is available for use by any other class; it can also be
extended to create subclasses. Other access modifiers are abstract and final; we won’t deal
with those in this book.
• The keyword class.
• A user identifier for the name of the class; Book is used in the example.
The braces enclose the body of the class. In general, the body will include the declaration of the following:
• Static variables (class variables); there will be one copy for the entire class—all objects will
share that one copy. A class variable is declared using the word static. If we omit the word
static, the variable is instance.
• Non-static variables (instance variables); each object created will have its own copy. It’s the
instance variables that comprise the data for an object.
• Static methods (class methods); these are loaded once when the class is loaded and can be
used without creating any objects. It makes no sense for a static method to access non-static
variables (which belong to objects), so Java forbids it.
• Non-static methods (instance methods); these can be used only via an object created from the
class. It’s the non-static methods that manipulate the data (the non-static fields) in objects.
• The String class is predefined in Java. If word is String (a String object, to be precise) and
we write word.toLowerCase(), we are asking that the instance method toLowerCase of the
String class be applied to the String object, word. This method converts uppercase letters to
lowercase in the (String) object used to invoke it.
• Similarly, if in is a Scanner object (created when we say new Scanner...), the expression
in.nextInt() applies the instance method nextInt to the object in; here, it reads the next
integer from the input stream associated with in.
In the Book class, we declare two class variables (Discount and MinBooks, declared with static) and six instance
variables; they are instance by default (the word static is omitted).

31
Chapter 2 ■ Introduction to Objects

2.2.1 Access to Class and Instance Variables


In addition to static, a field can be declared using the optional access modifiers private, public, or protected. In
the Book class, we declared all our instance variables using private. The keyword private indicates that the variable
is “known” only inside the class and can be manipulated directly only by methods within the class. In other words, no
method from outside the class has direct access to a private variable. However, as we will see shortly, we can provide
public methods that other classes can use to set and access the values of private variables. This way, we ensure that
class data can be changed only by methods within the class.
Declaring a variable public means that it can be accessed directly from outside the class. Hence, other classes
can “do as they please” with a public variable. For example, if Discount is declared as public, then any other class
can access it using Book.Discount and change it in any way it pleases. This is not normally encouraged since a class
then loses control over its data.
For the most part, we will declare a class’s fields using private. Doing so is the first step in implementing the
concept of information hiding, which is part of the philosophy of object-oriented programming. The idea is that users
of an object must not be able to deal directly with the object’s data; they should do so via the object’s methods.
Declaring a variable protected means that it can be accessed directly from the class and any of its subclasses, as
well as other classes in the same package. We will not use protected variables in this introduction.
If no access modifier is specified, then the variable can be accessed directly by other classes in the same
package only.
A method within a class can refer to any variable (static or non-static, public or private) in the class simply
by using its name. (An exception is that a static method cannot access non-static variables.) If a static variable is
known outside the class (that is, not private), it is referenced by qualifying the variable with the class name, as in
Book.Discount and Book.MinBooks.
From outside the class, a nonprivate instance variable can be referenced only via the object to which it belongs;
this is illustrated in the next Section. However, as indicated, good programming practice dictates that, most of the
time, our variables will be declared private, so the notion of direct access from outside the class does not arise.

2.2.2 Initializing Class and Instance Variables


When the Book class is loaded, storage is immediately allocated to the class variables Discount and MinBooks; they
are then assigned initial values of 0.25 and 5, respectively. The meaning behind these variables is that if five or more
copies of a book are sold, then a 25 percent discount is given. Since these values apply to all books, it would be a waste
of storage to store them with each book’s data, hence their declaration as static variables. All book objects will have
access to the single copy of these variables. (Note, however, that if we wanted to vary these values from book to book,
then they become attributes of a specific book and would have to be declared non-static.)
When the class is first loaded, no storage is allocated to the instance (non-static) variables. At this time, we have
only a specification of the instance variables, but none actually exists as yet. They will come into existence when an
object is created from the class. The data for an object is determined by the instance variables. When an object is
“created,” storage is allocated for all the instance variables defined in the class; each object created has its own copy of
the instance variables. To create an object, we use the keyword new as in the following:

Book b;
b = new Book();

The first statement declares b as a variable of type Book. From this, we see that a class name is considered to be a
type (similar to int or char) and can be used to declare variables. We say that b is an object variable of type Book.
The declaration of b does not create an object; it simply creates a variable whose value will eventually be a pointer
to an object. When declared as shown, its value is undefined.
The second statement finds some available memory where a Book object can be stored, creates the object, and
stores the address of the object in b. (Think of the address as the first memory location occupied by the object. If the
object occupies locations 2575 to 2599, its address is 2575.) We say that b contains a reference or pointer to the object.
Thus, the value of an object variable is a memory address, not an object. This is illustrated as shown in Figure 2-1.
32
Chapter 2 ■ Introduction to Objects

2575
author
title
price
pages
binding

2575 inStock
2599
b

Figure 2-1. An instance of a Book object

As a shortcut, we can declare b and create a book object in one statement, like this:

Book b = new Book();

It is a common error to think that the Book variable b can hold a Book object. It cannot; it can hold only a reference
to a Book object. (In a similar manner, we should be familiar with the idea that a String variable does not hold a
string but, rather, the address of where the string is stored.) However, where the distinction (between an object and a
reference to the object) does not matter, we will speak as if b holds a Book object.
Once an object b is created, we can refer to its instance fields like this:

b.author b.title b.price


b.pages b.binding b.inStock

However, we can do so from outside the class only if the fields are declared public. We will see later how to access
the fields indirectly when they are declared private.
When an object is created, unless we say otherwise, its instance fields are initialized as follows:
• Numeric fields are set to 0.
• Character fields are set to '\0' (Unicode '\u0000', to be precise).
• Boolean fields are set to false.
• Object fields are set to null. (A variable with the value null means that it does not reference or
point to anything.)
In our example, the following happens:
• b.author (of type String) is set to null; remember that String is an object type.
• b.title (of type String) is set to null.
• b.price (of type double) is set to 0.0.
• b.pages (of type int) is set to 0.
• b.binding (of type char) is set to '\0'.
• b.inStock (of type boolean) is set to false.
We could specify an initial value when we declare an instance variable. Consider this code:

public class Book {


private static double Discount = 0.25;
private static int MinBooks = 5;

33
Chapter 2 ■ Introduction to Objects

private String author = "No Author";


private String title;
private double price;
private int pages;
private char binding = 'P'; // for paperback
private boolean inStock = true;
}

Now, when an object is created, author, binding, and inStock will be set to the specified values while title,
price, and pages will assume the default values. A variable is given a default value only if no explicit value is assigned
to it. Suppose we create an object b with this:

Book b = new Book();

The fields will be initialized as follows:


• author is set to "No Author". // specified in the declaration
• title is set to null. // default for (String) object type
• price is set to 0.0. // default for numeric type
• pages is set to 0. // default for numeric type
• binding is set to 'P'. // specified in the declaration
• inStock is set to true. // specified in the declaration

2.3 Constructors
Constructors provide more flexible ways of initializing the state of an object when it is created. In the following
statement, Book() is termed a constructor:

Book b = new Book();

It is similar to a method call. But, you might say, we did not write any such method in our class definition. True,
but in such cases, Java provides a default constructor—one with no arguments (also called a no-arg constructor). The
default constructor is quite simplistic; it just sets the values of the instance variables to their default initial values.
Later, we could assign more meaningful values to the object’s fields, as in the following:

b.author = "Noel Kalicharan";


b.title = "DigitalMath";
b.price = 29.95;
b.pages = 200;
b.binding = 'P'; //for paperback
b.inStock = true; //stock is available

Now suppose that when we create a book object, we want Java to assign the author and title automatically.
We want to be able to use statements such as the following for creating new book objects:

Book b = new Book("Noel Kalicharan", "DigitalMath");

34
Chapter 2 ■ Introduction to Objects

We can do this, but we must first write an appropriate constructor, one defined with two String parameters.
The following shows how it can be done:

public Book(String a, String t) {


author = a;
title = t;
}

Here are some important points to note:


• A constructor for a class has the same name as the class. Our class is called Book; therefore, the
constructor must be called Book. Since a constructor is meant to be used by other classes, it is
declared public.
• A constructor can have zero or more parameters. When called, the constructor must be given
the appropriate number and type of arguments. In our example, the constructor is declared
with two String parameters, a and t. When calling the constructor, two String arguments
must be supplied.
• The body of the constructor contains the code that would be executed when the constructor
is called. Our example sets the instance variable author to the first argument and title to the
second argument. In general, we can have statements other than those that set the values of
instance variables. We can, for instance, validate a supplied value before assigning it to a field.
We will see an example of this in the next section.
• A constructor does not have a return type, not even void.
• If initial values are provided for instance variables in their declaration, those values are stored
before the constructor is called.
For example, suppose the class Book is now declared as follows:

public class Book {


private static double Discount = 0.25;
private static int MinBooks = 5;

private String author = "No Author";


private String title;
private double price;
private int pages;
private char binding = 'P'; // for paperback
private boolean inStock = true;

public Book(String a, String t) {


author = a;
title = t;
}
} //end class Book

The statement

Book b = new Book("Noel Kalicharan", "DigitalMath");

35
Chapter 2 ■ Introduction to Objects

will be executed as follows:


1. Storage is found for a Book object, and the address of the storage is stored in b.
2. The fields are set as follows:

author is set to "No Author"; // specified in the declaration


title is set to null; // default for (String) object type
price is set to 0.0; // default for numeric type
pages is set to 0; // default for numeric type
binding is set to 'P'; // specified in the declaration
inStock is set to true. // specified in the declaration
  
3. The constructor is called with arguments "Noel Kalicharan" and "DigitalMath"; this
sets author to "Noel Kalicharan" and title to "DigitalMath", leaving the other fields
untouched. When the constructor is finished, the fields will have the following values:

author "Noel Kalicharan"


title "DigitalMath"
price 0.0
pages 0
binding 'P'
inStock true

2.3.1 Overloading a Constructor


Java allows us to have more than one constructor, provided each has a different signature. When several
constructors can have the same name, this is referred to as overloading the constructor. Suppose we want to be able
to use the no-arg constructor as well as the one with author and title arguments. We can include both in the class
declaration like this:

public class Book {


private static double Discount = 0.25;
private static int MinBooks = 5;

private String author = "No Author";


private String title;
private double price;
private int pages;
private char binding = 'P'; // for paperback
private boolean inStock = true;

public Book() { }

public Book(String a, String t) {


author = a;
title = t;
}
} //end class Book
  

36
Chapter 2 ■ Introduction to Objects

Observe that the body of the no-arg constructor consists of an empty block. When the following statement is executed,
the instance variables are set to their initial values (specified or default), and the constructor is executed. In this case,
nothing further happens.

Book b = new Book();

Be warned that when we provide a constructor, the default no-arg constructor is no longer available. If we want to
use a no-arg constructor as well, we must write it explicitly, as in the previous example. We are free, of course, to write
whatever we want in the body, including nothing.
As a final example, we provide a constructor that lets us set all the fields explicitly when an object is created. Here
it is:

public Book(String a, String t, double p, int g, char b, boolean s) {


author = a;
title = t;
price = p;
pages = g;
binding = b;
inStock = s;
}
  
If b is a variable of type Book, a sample call is as follows:

b = new Book("Noel Kalicharan", "DigitalMath", 29.95, 200, 'P', true);

The fields will be given the following values:

author "Noel Kalicharan"


title "DigitalMath"
price 29.95
pages 200
binding 'P'
inStock true

2.4 Data Encapsulation, Accessor, and Mutator Methods


We will use the term user class to denote a class whose methods need to access the fields and methods of another class.
When a class’s field is declared public, any other class can access the field directly, by name. Consider the
following class:

public class Part {


public static int NumParts = 0; // class variable
public String name; // instance variable
public double price; // instance variable
}
  
Here, we define one static (or class) variable and two instance variables as public. Any user class can access the
static variable using Part.NumParts and can include statements such as this:

Part.NumParts = 25;

37
Chapter 2 ■ Introduction to Objects

This may not be desirable. Suppose NumParts is meant to count the number of objects created from Part. Any
outside class can set it to any value it pleases, so the writer of the class Part cannot guarantee that it will always reflect
the number of objects created.
An instance variable, as always, can be accessed via an object only. When a user class creates an object p of
type Part, it can use p.price (or p.name) to refer directly to the instance variable and can change it, if desired, with
a simple assignment statement. There is nothing to stop the user class from setting the variable to an unreasonable
value. For instance, suppose that all prices are in the range 0.00 to 99.99. A user class can contain the following
statement, compromising the integrity of the price data:

p.price = 199.99;

To solve these problems, we must make the data fields private; we say we must hide the data. We then provide
public methods for others to set and retrieve the values in the fields. Private data and public methods are the essence
of data encapsulation. Methods that set or change a field’s value are called mutator methods. Methods that retrieve
the value in a field are called accessor methods.
Let’s show how the two problems mentioned can be solved. First, we redefine the fields as private:

public class Part {


private static int NumParts = 0; // class variable
private String name; // instance variable
private double price; // instance variable
}

Now that they are private, no other class has access to them. If we want NumParts to reflect the number of
objects created from the class, we would need to increment it each time a constructor is called. We could, for example,
write a no-arg constructor as follows:

public Part() {
name = "NO PART";
price = -1.0; // we use –1 since 0 might be a valid price
NumParts++;
}

Whenever a user class executes a statement such as the following, a new Part object is created and 1 is added
to NumParts:

Part p = new Part();

Hence, the value of NumParts will always be the number of Part objects created. Further, this is the only way to
change its value; the writer of the class Part can guarantee that the value of NumParts will always be the number of
objects created.
Of course, a user class may need to know the value of NumParts at any given time. Since it has no access to
NumParts, we must provide a public accessor method (GetNumParts, say; we use uppercase G for a static accessor, since
it provides a quick way to distinguish between static and non-static), which returns the value. Here is the method:

public static int GetNumParts() {


return NumParts;
}

The method is declared static since it operates only on a static variable and does not need an object
to be invoked. It can be called with Part.GetNumParts(). If p is a Part object, Java allows you to call it with
p.GetNumParts(). However, this tends to imply that GetNumParts is an instance method (one that is called via an

38
Chapter 2 ■ Introduction to Objects

object and operates on instance variables), so it could be misleading. We recommend that class (static) methods be
called via the class name rather than via an object from the class.
As an exercise, add a field to the Book class to count the number of book objects created and update the
constructors to increment this field.

2.4.1 An Improved Constructor


Instead of a no-arg constructor, we could take a more realistic approach and write a constructor that lets the user
assign a name and price when an object is created, as in the following:

Part af = new Part("Air Filter", 8.75);

We could write the constructor as:

public Part(String n, double p) {


name = n;
price = p;
NumParts++;
}
  
This will work except that a user can still set an invalid price for a part. There is nothing to stop the user from
writing this statement:

Part af = new Part("Air Filter", 199.99);

The constructor will dutifully set price to the invalid value 199.99. However, we can do more in a constructor
than merely assign values to variables. We can test a value and reject it, if necessary. We will take the view that if an
invalid price is supplied, the object will still be created but a message will be printed and the price will be set to –1.0.
Here is the new version of the constructor:

public Part(String n, double p) {


name = n;
if (p < 0.0 || p > 99.99) {
System.out.printf("Part: %s\n", name);
System.out.printf("Invalid price: %3.2f. Set to -1.0.\n", p);
price = -1.0;
}
else price = p;
NumParts++;
} //end constructor Part
  
As a matter of good programming style, we should declare the price limits (0.00 and 99.99) and the “null” price
(-1.0) as class constants. We could use the following:

private static final double MinPrice = 0.0;


private static final double MaxPrice = 99.99;
private static final double NullPrice = -1.0;

These identifiers can now be used in the constructor.

39
Chapter 2 ■ Introduction to Objects

2.4.2 Accessor Methods


Since a user class may need to know the name or price of an item, we must provide public accessor methods for name
and price. An accessor method simply returns the value in a particular field. By convention, we preface the name of
these methods with the word get. The methods are as follows:

public String getName() { // accessor


return name;
}

public double getPrice() { // accessor


return price;
}
  
Note that the return type of an accessor is the same as the type of the field. For example, the return type of
getName is String since name is of type String.
Since an accessor method returns the value in an instance field, it makes sense to call it only in relation to a
specific object (since each object has its own instance fields). If p is an object of type Part, then p.getName() returns
the value in the name field of p and p.getPrice() returns the value in the price field of p.
As an exercise, write accessor methods for all the fields of the Book class.
These accessors are examples of non-static or instance methods (the word static is not used in their
declaration). We can think of each object as having its own copy of the instance methods in a class. In practice,
though, the methods are merely available to an object. There will be one copy of a method, and the method will be
bound to a specific object when the method is invoked on the object.
Assuming that a Part object p is stored at location 725, we can picture the object as shown in Figure 2-2.

725

name getName()

725 price getPrice()


p

Figure 2-2. A Part object with its fields and accessors

Think of the fields name and price as locked inside a box, and the only way the outside world can see them is via
the methods getName and getPrice.

2.4.3 Mutator Methods


As the writer of the class, we have to decide whether we will let a user change the name or price of an object after it
has been created. It is reasonable to assume that the user may not want to change the name. However, prices change,
so we should provide a method (or methods) for changing the price. As an example, we write a public mutator method
(setPrice, say) that user classes can call, as in the following:

p.setPrice(24.95);

40
Chapter 2 ■ Introduction to Objects

This sets the price of Part object p to 24.95. As before, the method will not allow an invalid price to be set. It will
validate the supplied price and print an appropriate message, if necessary. Using the constants declared in Section
2.4.1, here is setPrice:

public void setPrice(double p) {


if (p < MinPrice || p > MaxPrice) {
System.out.printf("Part: %s\n", name);
System.out.printf("Invalid price: %3.2f; Set to %3.2f\n", p, NullPrice);
price = NullPrice;
}
else price = p;
} //end setPrice

With this addition, we can think of Part p as shown in Figure 2-3.

725
name getName()
price getPrice()
725
p
setPrice()

Figure 2-3. Part object with setPrice() added

Observe the direction of the arrow for setPrice; a value is being sent from the outside world to the private field
of the object.
Again, we emphasize the superiority of declaring a field private and providing mutator/accessor methods for it
as opposed to declaring the field public and letting a user class access it directly.
We could also provide methods to increase or decrease the price by a given amount or by a given percentage.
These are left as exercises.
As another exercise, write mutator methods for the price and inStock fields of the Book class.

2.5 Printing an Object’s Data


To verify that our parts are being given the correct values, we would need some way of printing the values in an
object’s fields.

2.5.1 Using an Instance Method (the Preferred Way)


One way of doing this is to write an instance method (printPart, say), which, when invoked on an object, will print
that object’s data. To print the data for Part p, we will write this:

p.printPart();

Here is the method:

public void printPart() {


System.out.printf("\nName of part: %s\n", name);
System.out.printf("Price: $%3.2f\n", price);
} //end printPart
  
41
Chapter 2 ■ Introduction to Objects

Suppose we create a part with this:

Part af = new Part("Air Filter", 8.75);

The expression af.printPart() would display the following:

Name of part: Air Filter


Price: $8.75

When printPart is called via af, the references in printPart to the fields name and price become references to
the fields of af. This is illustrated in Figure 2-4.

name: Air Filter


725
price: 9.50
af

printPart()

System.out.printf("\nName of part: %s\n", name);


System.out.printf("Price: $%3.2f\n", price);

Figure 2-4. name and price refer to the fields of af

2.5.2 Using a Static Method


We could, if we want, write printPart as a static method, which will be called with p as an argument in order to print
its fields. In this case, we will write the following:

public static void printPart(Part p) {


System.out.printf("\nName of part: %s\n", p.name);
System.out.printf("Price: $%3.2f\n", p.price);
}

The field names have to be qualified with the object variable p. Without p, we would have the case of a static
method referring to a non-static field, which is forbidden by Java.
If c is a Part object created in a user class, we will have to use the following to print its fields:

Part.printPart(c);

This is slightly more cumbersome than using the instance method, shown previously. By comparison, you can
use, for instance, Character.isDigit(ch) to access the static method isDigit in the standard Java class Character.

2.5.3 Using the toString() Method


The toString method returns a String and is special in Java. If we use an object variable in a context where a string is
needed, then Java will attempt to invoke toString from the class to which the object belongs. For example, suppose
we write the following, where p is a Part variable:

System.out.printf("%s", p);

42
Chapter 2 ■ Introduction to Objects

Since it is not clear what it means to print an arbitrary object, Java will look for guidance in the class itself.
Presumably, the class will know how to print its objects. If it provides a toString method, Java will use it. (If it
doesn’t, Java will print something generic like the name of the class and the address, in hexadecimal, of the object, for
instance: Part@72e15c32.) In our example, we could add the following to the class Part:

public String toString() {


return "\nName of part: " + name + "\nPrice: $" + price + "\n";
}

If af is the Air Filter part, then the following statement would invoke the call af.toString():

System.out.printf("%s", af);

In effect, the printf becomes this:

System.out.printf("%s", af.toString());

af.toString() will return this:

"\nName of part: Air Filter \nPrice: $8.75\n"

The result is that printf will print this:

Name of part: Air Filter


Price: $8.75

2.6 The Class Part


Putting all the changes together, the class Part now looks like this:

public class Part {


// class constants
private static final double MinPrice = 0.0;
private static final double MaxPrice = 99.99;
private static final double NullPrice = -1.0;
private static int NumParts = 0; // class variable

private String name; // instance variable


private double price; // instance variable

public Part(String n, double p) { // constructor


name = n;
if (p < MinPrice || p > MaxPrice) {
System.out.printf("Part: %s\n", name);
System.out.printf("Invalid price: %3.2f; Set to %3.2f\n", p, NullPrice);
price = NullPrice;
}
else price = p;
NumParts++;
} //end constructor Part

43
Exploring the Variety of Random
Documents with Different Content
33. delta of the Irawaddy, was annexed, but Upper
A Garrison Burma round Mandalay remained independent.
Family. The last king of Mandalay was Thebaw, a
notorious tyrant, guilty of the most horrible atrocities. Being anxious
to maintain his independence, he intrigued with the French in the
lands of Tonkin and Annam to the east of Burma, and as a result
brought upon himself the conquest of his country in the time when
Lord Dufferin was Viceroy of India. It took fully ten years to reduce
Burma to order, for the land was infested with dacoits or robbers, as
it is still in some of the remoter districts. Every village in those days
was defended by a palisade. Here we have two views of a party of
troops in Fort Dufferin, with the King’s Palace in the background, and
then a family scene in the married quarters of the garrison. The
Burman does not make a good soldier, for he has very little sense of
discipline. Even the police of the province are for the most part
Gurkhas, Sikhs, and Punjabi Musulmans.

34. The Bazaar or market of Mandalay, as in every


The Bazaar, other Indian city, is the centre of public life.
Mandalay. Externally it is of little interest, having been
35. constructed since the conquest, but internally it is
The Flower and
Seed Market,
an epitome of the varied peoples who have
Mandalay thronged of late into the growing centres of
Bazaar. Burmese trade. Here is a scene in the fruit
market; but it is the silk market which delights
the Burmese lady, who will be seen there accompanied by her maid,
making purchases and enjoying the touch of more than she buys, as
in similar places in Europe. The most striking contrast which is
presented by Burma to one accustomed to Indian life is the freedom
of the women, who move about unveiled. In Burma, under the
Buddhist religion, we have neither seclusion of women nor the
distinctions of caste. The city of Mandalay has a population of about
190,000, so that it is now smaller than the upstart Rangoon.
36. Let us make a voyage up the Irawaddy to the
Ferryshaw border of the Chinese Empire. This is a river
Siding, near scene a short way above Mandalay, with a group
Mandalay.
of white pagodas conspicuous on the bank, and
37.
Mora.
here is a village scene. There follows a view at
38.
Katha, a large straggling village on the Irawaddy,
Katha. remarkable for its many pagodas, most of them
ruined. The majority of the Burmese pagodas are
thus dilapidated for the reason that there is considered to be no
merit in merely restoring an existing Buddhist shrine. The wealthy
devotee prefers therefore to erect a new pagoda. The Shwe Dagon
is an exception, for it contains sacred relics.

39. Here we have a raft of bamboos and teak logs


Raft on the floating down the river, and then a typical river
Irawaddy. craft with a great oar for a rudder. Our steamer
40. must progress with care, measuring the depths
On the
Irawaddy.
with bamboo poles at either bow. None the less,
41.
navigation extends for more than nine hundred
In the defile miles from the sea. From Mandalay to Katha the
between Katha bank of the river is in most places low and sandy,
and Bhamo. but between Katha and Bhamo there are striking
42. defiles, where the ground rises with wooded
The Same. fronts from the water’s edge. There is population
43. along the banks the whole way, as is evidenced
Burmese by the pagodas amid the vegetation. Here are
Children.
three little Burmese villagers, and then a rustic
44.
Cart with solid
cart with solid wheels, and here a picture
Wheels. showing the process of the famous lacquer work
45. of Burma. A “shell” is first made of very thin and
Lacquer finely plaited bamboo, and this is covered with a
Workers. pigment which, when dry, is softened on a
primitive lathe. Then red lacquer is put on by
hand, and the bowl is dried in the sun. When dry it is buried for
some days in order that it may harden. Finally it is engraved, and
often inlaid with gold.

46. We approach Bhamo, at the head of the


Bhamo from Irawaddy navigation, lying low along the bank of
the Irawaddy. the river, twenty miles from the Chinese frontier.
47. There are naturally many Chinese at Bhamo. This
China Street,
Bhamo.
is China Street. Here, on the other hand, is a
group of Kachin women, heavy-faced, in
48.
Kachin Women, picturesque costume. The Kachins are the hill
Bhamo. tribes of the northern frontier of Burma, as the
49. Shans are of the eastern frontier and the Chins of
Houses at the western. Until quite recently the Kachins
Bhamo. often raided the caravans passing from Bhamo to
China. They are now becoming civilised under British rule. The
Burmese people proper, of ancient civilisation, are a relatively small
population confined to the valley and the delta. Here we see a row
of houses at Bhamo, raised high upon piles. The change which has
come over Burma since the British occupation may be appreciated
from the fact that twenty years ago it was no uncommon sight on
the voyage up from Katha to Bhamo to see along the river banks,
and on rafts floating down the river, the dead bodies of Kachins who
had been tortured to death under the terrible rule of the kings of
Mandalay.

50. From Mandalay a railway runs eastward into


The Gokteik the Shan country. At one point this line crosses a
Gorge and gorge by a steel bridge, nearly half a mile long
Bridge.
and over 800 feet above the water of the stream.
51.
Native House,
The bridge is so light in design that its great size
Hsipaw. and real solidity are difficult to grasp. Beyond this
52. bridge we come to the chief place of the Shans,
The Bazaar, Hsipaw. Here are a couple of scenes in Hsipaw,
Hsipaw.
the one of a Shan house, the other of a Shan market.

53. To realise the antiquity and the splendour of


Pagan. early Burmese civilisation, we must descend the
54. Irawaddy below Mandalay to a place called
The Ananda Pagan. There, for some ten miles beside the river,
Temple,
Pagan.
and for three miles back from its bank, are the
55.
ruins of a great capital which flourished about the
The Ananda time of the Norman Conquest of England. From
Temple, nearer the centre of the ruined city it is impossible to
view of the point in any direction in which a pagoda or a
west side. temple is not visible. We have here a general
56. view of the remains, and then the Ananda
Buddha Image Temple, seen in the midst of a bank of
at Pagan.
vegetation, from which at various points rise
other smaller red and white ruins. The Ananda Temple was built
more than eight hundred years ago by the Thatons, the original
inhabitants of the country, who were overcome by the invading
Burmans. Some thirty thousand of these Thatons were brought to
Pagan as slaves, and set to build the pagodas and temples, just as
during the captivity in Egypt the Israelites were employed in building
the pyramids. Here is the Ananda Temple close at hand, white and
glittering in the sunshine, as though built of sugar. If we enter the
great portal—there are three other portals similar, for the plan of the
building is that of a cross—we find facing us a huge image of the
Buddha, over ten yards in height.
Buddhism was developed from Hinduism. It originated as a revolt
from the excessive ritualism of the Brahmans. We have seen that
Hinduism became an all-embracing system of religious ritual and
social organisation, but that alongside, as it were, of this process
there was evolved a philosophical system based upon two theories:
the belief in a Universal Soul as the centre of reality, and the belief in
the ultimate identity of the Individual and the Universal Soul. In the
sixth century before Christ India was seething and fermenting with
spiritual thought. A great teacher was called for, and such a one was
given to the world in Gautama, the Buddha, that is to say, the
Enlightened or Awakened One.
Gautama was born on the frontiers of Nepal at the foot of the
great Himalaya range about the year 557 before Christ. He was the
only son of a chief or king. At the age of eighteen he was married to
the daughter of the chief of a neighbouring clan, and a son was born
to him. But the yearnings of a reformer were stirring within
Gautama, and he could not rest. So one night in secret he left his
wife and infant and went out into the world a wanderer in search of
“that inward illumination on ‘great matters,’ which was the cherished
dream of every thinker in that memorable era.” He followed to no
purpose the paths of metaphysical speculation, of mental discipline,
and of ascetic rigour, and at last on one eventful night, as he sat
under the Bodhi Tree at Gaya, in Behar, “he reaped the fruit of his
long spiritual effort, the truth of things being of a sudden so clearly
revealed to him that from henceforth he never swerved for a
moment from devotion to his creed and to the mission that it
imposed upon him.”
The truth which Buddha discovered and preached to humanity
was that the salvation of man lay not in sacrifices and ceremonial,
nor in penances, but in spiritual effort and a holy life, in charity,
forgiveness, and love. The sages of Hinduism had taught as a
doctrine for the few that the Universal Soul is the only reality, and is
therefore the real self of every man. Buddha gave to the world a
system by which the truth of this doctrine could be realised in the
life of an ordinary man.
The four-fold truth on which Buddha’s whole scheme hinges may
be expressed as follows:—Life on earth is full of suffering; suffering
is generated by desire; the extinction of desire involves the
extinction of suffering; the extinction of desire, and therefore of
suffering, is the outcome of a righteous life. But how is desire with
the suffering which it generates to be extinguished? The answer of
Buddhism is that the eightfold path which leads to the extinction of
suffering is by “Right Belief, Right Thought, Right Speech, Right
Action, Right Effort, Right Means of Livelihood, Right Remembrance
and Self-discipline, Right Concentration of Thought.” In Buddha’s
system, as he himself gave it to the world, doctrines and beliefs are
of secondary importance. Fully alive to the truth that “what we do,
besides being the outward and visible sign of our inward and
spiritual state, reacts naturally and necessarily on what we are, and
so moulds our character and controls our destiny,” he formulated for
his followers a simple system of moral rules, obedience to which
would set them on the path which leads to salvation. On this path
there are successive stages, and each of these stages is marked by
the breaking of some of the fetters which bind man to earth and to
self, and when all the fetters are at last broken then the Holy One,
as he is now called, has reached his goal. In other words, he has
attained to that state which Buddhists call Nirvana, a state of
“perfect knowledge, perfect love, perfect peace, and therefore of
perfect bliss.”
The Buddhist system emphasises the importance of education and
discipline. All over Burma there are schools conducted by Buddhist
monastic orders at which instruction is gratuitously given to boys in
the vernacular of the country, and one rarely finds a native of Burma
who cannot read and write his own language. It is also part of the
religious discipline of every Burman boy that he should become a
novice in a monastic order and live for a time the life of a monk. The
aim of this training is to teach obedience and self-control, and thus
in these days of change, when strange and disintegrating influences
are at work in the East, the Burman retains, to a certain extent at all
events, his simplicity and his kindly faith. To appreciate the influence
of Buddhism in Burma let us remember that a Buddhist priest is
supported entirely by gifts in kind, and never touches a coin.
For some centuries Buddhism made great progress in India, the
land of its birth; but in the end Hinduism re-asserted itself, and to-
day there are very few Buddhists in India proper, though in Burma
nearly all the people are of that faith. This is the chief cause of the
difference in almost every respect between Burma and India. In the
Ananda Temple, as we have seen, there are four images of Buddha,
for it is the tradition of the religion that before Gautama there were
in former ages of the world three other teachers who reached
enlightenment and were therefore called Buddha.

57. Here, still at Pagan, is the so-called Wilderness


The Wilderness of Bricks, with the Ananda Temple in the distance
of Bricks, to the right. Then we have the entry to one of
Pagan.
the other temples, and then yet another Pagan
58.
Gadawpalin
ruin with vultures on the summit. Finally we have
Temple, a scene of tall cactus growth, also at Pagan, for
Pagan. this city stands in what is known as the Dry Belt
59. of Burma. The map shows us that two ranges of
Vultures on a mountains extend northward, respectively to east
ruined Temple and west of the Irawaddy valley. The winds of
at Pagan.
summer and autumn blow from the southwest,
60. from the sea, bringing moisture which falls in
Cactus at
Pagan. heavy rains on the west sides of the mountains
Repeat Map
and over the delta. At Rangoon there is an
No. 6. annual rainfall of over one hundred inches, or
more than three times the rainfall of London. To
the east of the western range, however, as we leave the delta on our
journey up the river, there is a low-lying district near Pagan, which is
screened from the sea winds by the continuous mountain ridge, and
here the rainfall is small, as little as twenty inches in the year, but
the climate is hot and evaporation is rapid. In this district, therefore,
cactus is the typical vegetation, but elsewhere in Burma are rich
crops or the most luxuriant forests of leafy trees. These forests
supply the teak wood, which is floated down the river. They are full
of game, and the haunt of poisonous snakes. Wild peacocks come
from the woods to feed on the rice when it is ripe, and tigers are not
unknown in the villages. Only a few years ago a tiger was shot on
one of the ledges of the Shwe Dagon Pagoda in the midst of
Rangoon.
Notwithstanding the age of some of its temples and pagodas,
Burma is in the main a new country, in which Nature is still
masterful. It is the largest of the provinces under the Government of
India, but all told it contains but ten million people—Burmese,
Chinese, Hindus, and the Hill Tribes.
LECTURE III.

BENGAL.

THE MONSOONS.

1. From Burma we take steamer again and cross


Map of the sea to Bengal, the Metropolitan Province of
Bengal.
India. The heart of Bengal is one of the largest
deltas in the world, a great plain of moist silt brought down by the
rivers Ganges and Brahmaputra from the Himalaya mountains. But
along the borders of the Province, and especially to the west, much
hill country is included.
The map shows to the north the high tableland of Tibet, edged by
the Himalaya range, whose southern slopes descend steeply, but
with many foot hills, to the level, low-lying plains of the two great
river valleys. Eastward of Bengal there is a ridge, rising to heights of
more than six thousand feet, densely forested, which separates the
Irawaddy valley of Burma from the plains of India. This ridge throws
out a spur westward, which near its end rises a little into the Garo
hills. The deeply trenched narrow valley of the Brahmaputra, known
as the Assam Valley, lies between the Garo hills and the Himalayas.
Away in the west of Bengal is another hill spur, bearing the name of
Rajmahal, which forms the northeastern point of the plateau of
Southern India. The Ganges flows through the plain bounded
southward by this plateau and northward by the Himalayas. A broad
lowland gateway is left between the Garo and the Rajmahal hills,
and through this, on either hand, the Brahmaputra and Ganges
rivers turn southward and converge gradually until they join to form
the vast Megna estuary. The country which lies west of the Megna is
the Ganges delta, traversed by many minor channels which branch
from the right bank of the river before it enters the Megna. East of
the Megna is another deltaic land whose silt is derived in the main
from the Garo hills. It is said that the highest rainfall in the world
occurs in these hills, when the monsoon sweeps northward from the
Bay of Bengal and blows against their southern face. The rainfall on
a single day in the rainy season is often as great as the whole
annual rainfall of London. Little wonder that there is abundance of
silt for the formation of the fertile plains below.
The approach to the coast, as may be concluded from this
geographical description, presents little of interest. As you enter the
Hooghly river, the westernmost of the deltaic channels, you see
broad grey mud banks, with here and there a palm tree. From time
to time, as the ship passes some more solid ground, there are
villages of thatched huts surrounded by banana plantations with tall
broad green leaves.

2. Calcutta, the chief port and capital of India, is


Approaching placed no less than eighty miles up the Hooghly,
Calcutta. on the eastern bank. As we approach it we pass
3. mills and factories with tall chimneys throwing
Coolie Emigrant
Ship on the
out black smoke. A steamer crosses us, outward
Hooghly. bound, carrying, as we are told, coolies going to
4. work in South Africa; for the basin of the Ganges,
The Hooghly at unlike Burma, is one of the most densely peopled
Calcutta, lands in the world, and sends forth annually
showing the some thousand emigrants. At last we find
High Court.
ourselves amid a throng of shipping, and our
5. steamer ties up to a buoy in the turbid river, with
The Same. the great city of Calcutta on the eastern bank,
and the large industrial town of Howrah on the western bank, and
not a hill in sight round all the horizon, only the great dome of the
Post Office rising white in the sunshine.

6. Let us examine the plan of this mighty city with


Plan of more than a million inhabitants, second in the
Calcutta. Empire in population, and one of the twelve
7. largest towns in the world. The Hooghly flows
Palm Avenue,
Calcutta
southward. On its eastern bank stands Fort
Botanical William, a fortress which with its outworks
Gardens. occupies a space of nearly a thousand acres.
Around, to the north, the east, and the south of
the fort, is a wide green plain, the Maidan, separating the fort from
the city. From north to south the Maidan extends for some two
miles, and it is about a mile broad from east to west. In its southern
end is the racecourse, where are held at Christmas time the races,
the principal social event of Calcutta life. To the east of the Maidan is
the European quarter, with its hotels, and clubs, and private houses.
To the north, in a garden, is Government House, the residence of
the Viceroy of India. Beside Government House, and also facing the
Maidan, are the High Court of Justice and the Town Hall. Behind
Government House is Dalhousie Square, occupied by a green, in the
centre of which is a large tank. Facing this square is the Bengal
Government Secretariat, between which and the river are the Post
Office and the Customs House. Away to the north is the great native
city. One bridge only connects Calcutta with the industrial town of
Howrah, where are jute mills and great engineering works. In
Howrah also is the terminus of the East Indian Railway. A hundred
years ago Howrah was but a small village; to-day it contains some
160,000 people. Finally to the south of Howrah on the west bank of
the river are the celebrated Botanical Gardens, containing many
great palms, and most notable of all a banyan tree whose
circumference measures nearly a thousand feet. North of Calcutta,
and on the east bank of the Hooghly, is Barrackpur, with the country
house of the Viceroy of India. There is a military cantonment at
Barrackpur, and also a garrison in Fort William.

8. Nothing impresses the stranger in Calcutta


The Howrah more than the density of life in this populous city,
Bridge, the focus of a great and fertile province. At no
Calcutta.
spot is it more evident than on the Howrah
9.
Scene from the
Bridge, where from morning to night a close
Howrah throng crosses and re-crosses. From the
Bridge. approach to the bridge we look down on a crowd
bathing in the muddy but sacred water. Cheek by
jowl with the busy commercial traffic of the bridge, we have here the
religion of the East. Purified by the bath, and clothed again, the
bather sits in the crowd while for a few pies, or say a farthing, his
sect mark is painted afresh on his forehead.

10. The buildings of Calcutta are worthy of the


Calcutta from capital rank of the city, but they are of European
Howrah across design, for Calcutta is a modern city. Fort William
the Hooghly.
was so named from King William III., in whose
reign, little more than two centuries ago, Job Charnock, a factor or
commercial representative of the East India Company, bought the
little village Kalikata, probably so named from a local shrine of the
goddess Kali. There he built, on the site of the present Customs
House, the first Fort William. Within ten years the population had
grown to some ten thousand, and it has never ceased growing to
this day, although at one time, in the middle of the eighteenth
century, there was an episode in the history of the place which for a
time somewhat checked its advance. Suraj-ud-Daulah, the Nawab of
Bengal, quarrelled with the English at Fort William, and finally
attacked them. Most of them escaped down the river, but a hundred
and forty-six were taken prisoners when Fort William fell, and were
confined for a night in a small cell measuring 22 feet by 14 feet, and
some 18 feet high. It was at the end of the hot season, and only
twenty-three of the prisoners came out alive the next morning. This
tragedy is known in history as the Black Hole of Calcutta. Soon
afterwards Colonel Clive, the same Clive who as a Captain defended
Arcot in the south of India, arrived with reinforcements and
recaptured Calcutta. Fort William was rebuilt on a larger scale, and
in a position a little south of the original site.
Suraj-ud-Daulah quarrelled with the East India Company again,
and Clive led an army against him into the north of Bengal, and
defeated him and his French allies in the famous battle of Plassey.
The British force amounted to only three thousand men, of whom
but two hundred were English, whereas the Nawab had an army of
nearly forty thousand. In 1765 the whole of Bengal was annexed by
the East India Company, and from 1772 was ruled from Calcutta.
Suraj-ud-Daulah’s capital had been at a place called Murshidabad, a
hundred miles to the north of Calcutta.

11. Here, at the corner of Dalhousie Square, is the


Black Hole Black Hole Monument, erected by Lord Curzon
Monument, when Viceroy of India, in the year 1902, upon the
Calcutta.
site of the original monument which was set up
12.
The Marble
by one of the twenty-three survivors; and here is
Pavement, a marble pavement marking the exact position of
Black Hole, the Black Hole.
Calcutta.

13. We have next the great red brick building in


Bengal Dalhousie Square known as the Bengal
Government Secretariat. Not far away are the public offices of
Office,
Calcutta. the Government of India, but most of the staff
14.
are removed to Simla in the hills during the hot
The High Court, and rainy seasons. Here, facing the Maidan, is
Calcutta. the frontage of the Supreme Court of Justice,
15. with a fine tower nearly two hundred feet high,
Eastern which we saw just now from the Hooghly. Next is
Gateway, the eastern gateway to the grounds of
Government Government House, and here is Government
House,
Calcutta.
House itself, with the Union Jack flying above it,
16.
and Indian sentries on guard. It was built a little
Government more than a hundred years ago, and contains the
House, throne of Tippu Sultan, the tyrant of Mysore, of
Calcutta. whom we heard in the first lecture. Opposite
17. Government House, on the Maidan, is the Jubilee
The Same. Statue of Victoria, the Queen-Empress of India,
18. which was unveiled in the year 1902. Here we
Imperial have a more distant view of Government House,
Museum,
Calcutta.
as seen from the Maidan, with a statue of one of
the Viceroys in the foreground. Next, in
Chowringhee road, is the Imperial Museum, a fine building with a
valuable Gallery of Antiquities.

19. Let us walk round the Maidan, and note the


Musulmans at curiously mingled life upon it. Here, for instance,
Prayer in the are Musulmans at prayer, an impressive sight that
Maidan.
may be witnessed every evening. Here we are at
20.
Ochterlony
the foot of the Ochterlony monument, a column
Monument, erected in honour of Sir David Ochterlony, a
Calcutta. successful general in the wars with Nepal. From
21. the top of it we have a fine view over the city.
Calcutta from Notice Government House and the High Court. At
the Ochterlony the other end of the Maidan is the racecourse
Monument.
and polo ground, to which we have already
22. referred, and here amid the trees in the
Race Course,
Calcutta. southeastern corner, beside the tank, is the spire
23.
of the English Cathedral. Here, in contrast, is a
St. Paul’s view in the native city. The streets are with a few
Cathedral, exceptions very narrow, as in most southern
Calcutta. cities where the sunshine is dreaded and where
24. shade is essential to comfort.
Tiretta Bazaar
Street, Now we cross to Howrah, to the great jute
Calcutta. mills, where the jute fibre grown up country is
25. spun and woven in competition with the jute
Jute Mills,
Howrah.
manufacture of Dundee. In these mills you will
find that the machinery bears the names of
26.
A Workshop in Dundee and Leeds makers, for the industry is
Iron Foundry at relatively new in India, and has not yet reached
Howrah. the stage of manufacturing its own machinery.
27. Next we pass into the engineering works of
The same, Plate Messrs. Burn and Co., where some five thousand
Girders. natives and some sixty Europeans are employed
28. in the steel industry. Here are plate girders made
Workpeople
bathing at
in these works for railway bridge building, and
Howrah. here in this same industrial town of Howrah are
people bathing after work in the jute mills.
Let us recount the essence of what we have seen—the Hooghly
channel from the ocean, bearing inward the European ships; the
Shrine of the Goddess Kali; the Fort which protected the factory of
the East India Company; the Monument of the Black Hole;
Government House and the Secretariat, whence the vast empire is
ruled; the Cathedral and the Racecourse of the white rulers; the
Courts of Justice, which, more than any military power, betoken the
essence of British rule in India; the Native City with its narrow ways
and crowded life drawn from the surrounding agricultural plain; the
Howrah Bridge with the steel and jute mills beyond, which imply a
vast incoming change in the economic life of this eastern land; and
the Botanic Gardens with their wealth of vegetation typifying the
ultimate resources of India—the tropical sunshine and the torrential
rains.

Repeat Map Now let us run northward by the East Bengal


No. 1. Railway for some three hundred miles to
Darjeeling, the hill station of Calcutta, as Ootacamund is the hill
station of Madras. We traverse the dead level of the plain with its
thickly set villages and tropical vegetation. There are some seven
hundred and fifty thousand villages in India, and these village
communities are the real India, for only about ten per cent. of the
total population is contained in the cities. Yet Bengal in its present
limits, which exclude Eastern Bengal, has a population of more than
fifty millions, on an area slightly smaller than that of the United
Kingdom. Now the total population of the United Kingdom is only
some forty-four millions, and of these forty-four millions fully one-
third inhabit some forty large cities. Britain is therefore mainly
industrial, whereas India is mainly agricultural, nine-tenths of all the
people in India being supported by occupations connected with
agriculture. From such statistics some idea may be gained of the
density of the agricultural population of Bengal, a Province with one
great city only, as greatness of cities is measured in our British
Islands.
The rule of these village-dotted plains is the main daily business of
the Indian Government. A great Province like Bengal is divided into
Districts, each of them about as large as the English county of
Lincolnshire or a little larger. On the average each of them contains
from half a million to a million and a half of population. There are
some 250 of such Districts in British India, that is to say in that
greater part of India which is administered directly by British
officials. In each District there is a chief executive officer, styled the
Collector or Deputy Commissioner. He is the head of the District
administration, and he is also the principal Magistrate in the District.
Under the Collector there is a staff of Executive Officers, British and
Indian, of whom the chief are the Assistant Collector, the Deputy
Collector, the Superintendent of Police, the Engineer, and the Civil
Surgeon. The Collector is so called because in the days of the old
East India Company his main function was to collect revenue. In his
other capacity of Magistrate, he is the head of the Magisterial Courts
of the District. The laws which he and his assistants administer are
made by the Viceroy in Council, and in a subordinate way by the
Lieutenant-Governors and their Councils in the various Provinces.
The Collector does not decide civil suits. These, as well as all serious
criminal cases, come before Civil Judges of different grades, who are
independent of the Collector.
Therefore we find in India that essential division of the
Legislature, Judicature, and Executive which is the chief security of
freedom in all British communities. Subject to the law and to the
instructions of the superior Provincial Officers, the District Collector
is, however, supreme, except in the Civil Courts of his District. He it
is who alone for the vast majority of the Indian population
represents the Raj or Rule of the King-Emperor. Between the
Collectors and the Lieutenant-Governors are intermediate controlling
officers known as Commissioners, who superintend Divisions or
groups of several Districts.
The Higher Civil Service of India, recruited by competitive
examination in England, consists of some twelve hundred officials—
the Commissioners, the Collectors of the Districts, and some of the
Assistant Collectors. The seniors of the Civil Service man the
Provincial and Supreme Governments of India. Only the Governor-
General and the Governors of Madras and Bombay are selected from
outside the Indian Civil Service and sent out from Britain.
The Collector is constantly touring his District, in order that he
may know it from personal investigation. A good Collector may
become very popular, and may do much to make his District
prosperous. It is a great position which may thus be held by young
Englishmen of, say, thirty years of age. They are rulers of a million
people at an age when their brothers of the professional classes at
home are struggling to establish themselves as young barristers or
doctors or clergymen.
It must not be thought, however, that the Government of India,
either in its Legislative, Judicial, or Executive capacities, is wholly
British, and alien from the subject population. The Legislative
Councils of the Governor-General and also of the Lieutenant-
Governors in the Provinces contain elected Indian representatives,
both Hindu and Musulman. The provincial Councils have, in fact,
non-official majorities. Only in the Council of the Governor-General is
there an official majority. Many of the Judges even of the High
Courts are Indian, either Hindu or Musulman. In the Executive some
of the Collectors of Districts are Indian, and also the great majority
of the assistant officials, who in the aggregate are an immense
number.

29. As we think over these things we are


Darjeeling continuing our journey northward. We must
Railway, change from train to steamer as we cross the
Chinbatti
Loop. Ganges. The passage of the river occupies about
30.
twenty minutes from one low-lying bank to the
Darjeeling other. Then, as we traverse the endless rice fields
Railway, Loop with their clumps of graceful bamboo, the hills
No. 4. become visible across the northern horizon. We
31. run into a belt of jungle, and change to the
Darjeeling. mountain railway, which carries us up the steep
hill front with many a turn and twist. There is tall forest on the lower
slopes, of teak and other great trees, hung thickly with creepers.
Presently the wood becomes smaller, and we enter the tea
plantations with their trim rows of green bushes. Far below us, at
the foot of the steep forest, spreads to the southern horizon the vast
cultivated plain. Trees of the fir tribe now take the place of leafy
trees, and we rise to the ridge top on which is placed Darjeeling, a
settlement of detached villas in compounds or enclosures, hanging
on the steep hill slopes. Darjeeling is about seven thousand feet
above sea level, on a ridge overlooking northward the gorge of the
Rungeet River.

32. In the early morning, if we are fortunate in the


Kinchinjunga, weather and rise before the sun, we may see
from from Darjeeling, over the valley to north of the
Darjeeling.
hill ridge on which we stand, and over successive
33.
The Himalaya.
ridge tops beyond, the mighty snow range of the
Himalayas, fifty miles away, with the peak of
34. Kinchinjunga, more than five miles high,
Mount dominating the landscape. Behind it, a little to
Everest. the west, and visible from Tiger Hill near
Darjeeling, though not from Darjeeling itself, is Mount Everest, the
highest mountain in the world, five and half miles high. The
glittering wall of white mountains, visible across the vast chasm and
bare granite summits in the foreground, seems to hang in the sky as
though belonging to another world. The broad distance, and the
sudden leap to supreme height, give to this scene a mysterious and
almost visionary grandeur. It is, however, only occasionally that the
culminating peaks can be seen, for they are often veiled in cloud.

35. The people of Sikkim in the hills beyond


Tibetan Darjeeling are Highlanders of Mongolian stock
Woman. and not Indian. They are of Buddhist religion like
36. the Burmans, and not Hindu or Musulman like
Nepali Ladies.
the inhabitants of India. They are small, sturdy
folk, with oblique cut eyes, and a Chinese expression, and they have
the easy-going humorous character of the Burmans, though not the
delicacy and civilization of those inhabitants of the sunny lowland.
They and the kindred and neighbour Tibetans rarely wash, and the
women anoint their faces with a mixture of pigs’ blood, which gives
them a dark and mottled appearance. Here we have in colour a
portrait of a Tibetan woman, and then a group of Nepali ladies, with
various head ornaments.

37. It is an interesting fact that these hill people


Political Map of should belong to the race which spreads over the
India, vast Chinese Empire. That race here advances to
distinguishing
Bengal, Eastern the last hill brinks which overlook the Indian
Bengal and lowland. The political map of this portion of India
Assam, Nepal, illustrates a parallel fact. While the plains are
and Bhutan. administered directly by British officials, the
mountain slopes descending to them are ruled by native princes
whose territories form a strip along the northern boundary of India.
North of Assam and Bengal we have in succession from east to west,
in the belt of hill country, the lands of Bhutan, Sikkim, and Nepal.
From Nepal are recruited the Gurkha Regiments of the Indian army,
the Gurkhas being a race of these same hill men, of small stature
and sturdy agility, of Hindu religion, but of more or less Mongolian
stock, and therefore intermediate between the Tibetans and the
Hindus.

38. Here we have a typical market scene in


The Bazaar, Darjeeling. Notice the women doing coolie work.
Darjeeling. Next are vegetable sellers in the Darjeeling
39. Bazaar, and here is a man carrying fodder. The
The same—
Nepali
man with his back turned is a Lepcha of Sikkim.
Vegetable Then we have a group of Sikkim peasants
Sellers. drinking the native beer, made from marwa, a
40. kind of millet. They draw it up through straws
Man carrying from cups made of bamboo. Next we see a native
Fodder, working a hand loom, and then a village in
Darjeeling.
Sikkim. Here in the same village we see a woman
41. carrying baggage.
Sikkim
Peasants.
42. Near Darjeeling there is a small Buddhist
Native Loom,
Darjeeling.
monastery, a two-storey building of which we
have here a view. Notice the semi-circle of tall
43.
Village in poles, with linen flags, on which prayers are
Sikkim. inscribed. By the entrance are a number of
44. prayer-wheels fastened to the wall. Outside the
The same. monastery are men wearing the costumes of
45. devil dancers, such as are used in Buddhist
Lama religious ceremonies of these parts. There are
Monastery, long trumpets placed against the door post. Let
near
Darjeeling.
us glance for a moment within this monastery,
and see the hideous wooden masks, and the silk
46. dresses of the priestly dancers. Two scenes
The same— follow, from Darjeeling itself, of an elaborate
Devil Dancers. dance by Tibetan peasants called the Amban
47. dance. The lions and dragons are each made of
The same—
interior.
two men, whose bodies are hung with white yak
48.
hair and tails. They have grotesque heads, with
The Amban enormous eyes and gaping mouths, from which
Dance, hang large scarlet tongues. So we obtain some
Darjeeling. idea of the stage of barbarism in which the hill
49. tribes remain.
The same—
another view.
50. In contrast with these scenes are now two
North Bengal slides illustrating the volunteer service of the
Mounted Rifles, white tea planters. Of these the second shows
Lebong.
tent-pegging on the Lebong parade ground,
51.
The same—
above the Rungeet river. This form of tent-
Sword pegging is with a sword, and not with the more
Pegging. usual lance. Here is a scene showing Darjeeling
52. coolies returned from work in the tea gardens.
Coolies at
Darjeeling.
53. Finally we have two views in the gorge of the
The Rungeet Rungeet river, between Darjeeling and Sikkim,
Gorge. with precipitous sides, and then a glimpse of the
54. Rungeet bridge. The Rungeet drains from the
The same. hills of Darjeeling, and from the snow mountains
55. beyond, into a tributary of the Ganges. Several
The Rungeet
hundred such torrents burst in long succession
Bridge,
Sikkim. through deep portals in the Himalayan foot hills
56.
and feed the great rivers of the plain, the
A Himalayan Brahmaputra and the Ganges. They are perennial
Glacier. rivers, for they originate in the melting of the
57. glaciers, and the Himalayan glaciers cover a vast
Glacier-fed area, being fed by the monsoon snows. Nearly all
Torrent in the
Himalaya.
58. the agricultural wealth of Northern India owes its
Cane Bridge in origin to the summer monsoon.
the Himalaya.

59. To understand the fundamental conditions


Map of the governing the Indian climate let us examine the
Himalayan two concluding maps of this lecture. On the first
River System.
of them all the country with an elevation of more
than fifteen hundred feet is coloured with a dark brown, and that
with a lower elevation is coloured a light brown. A great angle of the
Indian lowland is seen to project northward into the Asiatic upland.
For fifteen hundred miles the Himalaya limits the lowland with a
gracefully curving mountain edge, and from this edge there flow the
series of tributaries which gather to the rivers Indus, Ganges, and
Brahmaputra. Beyond, to the south, are seen in dark brown the
higher portions of the Deccan plateau.

60. Now compare with this the succeeding map,


Map of South- which shows the winds of the summer time and
West the average rainfall. The winds sweep in from the
Monsoon.
southwest, but as they cross Bengal they bend so
as to blow from the south and then from the southeast. The dark
arrow with the broken shaft striking northwestward through the
heart of India represents the usual track of the storms which prevail
in the Central Provinces during the summer season, producing the
havoc along the Madras coast and northward, of which we spoke in
the second lecture. The maximum rainfall, it will be seen, occurs in
three regions—first on the west face of the Western Ghats, and on
the west face of the mountains of Ceylon; secondly in the east of the
Indian Peninsula near the track of the storm centres; and thirdly
along the south face of the Garo hills and of the Himalayas north of
Bengal, and on the west face of the various mountain ranges of
Burma. In other words, in the first and third cases the rain is due to
the winds striking the mountain ranges, and is great only on the
windward faces of those ranges. In the second case the rainfall is
mainly the result of the storms. On the other hand, there is drought
at this season under the lee of the mountains of Ceylon and of the
Western Ghats, and again in a comparatively small belt, near Pagan,
along the Irawaddy river, between the western and the eastern
ridges of Burma. Tibet, which is under the lee of the Himalayas, and
northwestern India, which is out of the track of the southwest winds,
are wide deserts. This map explains the exceptional fertility and
density of population of the Province of Bengal.

Repeat Map India is so vast a country, and so varied, that


No. 1. no traveller can hope to visit all parts of it. On
our journey from Calcutta to Darjeeling, we have left the province of
Assam away to the east of us. Assam is a through road nowhither,
for high and difficult mountains close the eastern end of its great
valley. Moreover, though it has vast natural resources, Assam is a
country which throughout history has lain for the most part outside
Indian civilisation, and, even to-day, has but a sparse population and
a relatively small commercial development. Let us, then, just
remember in passing that this remote province of India has a
geography which, though simple, is built on a very grand scale.
The San-po river rises high on the plateau of Tibet northward of
Lucknow. For more than 700 miles it flows eastward over the
plateau in rear of the Himalayan peaks; then it turns sharply
southward and descends steeply through a deep gorge little known,
for it is tenanted by hostile tribes. Where it emerges from the
mountains the river has a level not a thousand feet above the sea,
and here, turning westward, it forms the Brahmaputra—that is to
say, the Son of Brahma, the Creator. The Brahmaputra flows for 450
miles westward through the valley of Assam, deeply trenched
between the snowy wall of the Himalayas on the one hand and the
forested mountains of the Burmese border and the Khasia and Garo
hills on the other hand. The river “rolls down the valley in a vast
sheet of water,” depositing banks of silt at the smallest obstruction,
“so that islands form and re-form in constant succession. Broad
channels break away and rejoin the main river after wide
divergences, which are subjected to no control. The swamps on
either hand are flooded in the rainy season, till the lower reaches of
the valley are one vast shining sea, from which the hills slope up on
either side.” The traffic on the river is maintained chiefly by exports
of tea and timber, with imports of rice for the labourers on the tea
estates. Some day, when great sums of money are available for
capital expenditure, the Brahmaputra will be controlled, and Assam
will become the seat of teeming production and a dense population.
The Indian Empire contains some 300 million people; but, as we
learn, it also contains some of the chief virgin resources of the
world.
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!

ebookgate.com

You might also like