programming in java 1 · programming in java 1 david masters january 27, 2007 1a work in...

254
Programming in Java 1 David Masters January 27, 2007 1 A work in progress. My father David passed away in 2005 with this book almost finished. I felt that the book should not just disappear, so I am attempting to self-publish the book here. The book is currently complete in Word form, but in need of tidying up. I’m therefore working on getting it into L A T E X to help with typesetting in a professional format. The book hasn’t been proofread yet, so feel free to make comments and report any errors you find. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 License.

Upload: others

Post on 24-Sep-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Programming in Java 1

David Masters

January 27, 2007

1A work in progress. My father David passed away in 2005 with this bookalmost finished. I felt that the book should not just disappear, so I am attemptingto self-publish the book here. The book is currently complete in Word form, butin need of tidying up. I’m therefore working on getting it into LATEX to help withtypesetting in a professional format. The book hasn’t been proofread yet, so feelfree to make comments and report any errors you find. This work is licensed undera Creative Commons Attribution-NonCommercial-ShareAlike 2.0 License.

Page 2: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2

Page 3: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Contents

1 Computer Structure 91.1 The background to modern computers . . . . . . . . . . . . . 91.2 The nature of algorithms . . . . . . . . . . . . . . . . . . . . 111.3 The Java language . . . . . . . . . . . . . . . . . . . . . . . . 151.4 Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . 151.5 A complete program . . . . . . . . . . . . . . . . . . . . . . . 16

2 Elements of Java Programs 192.1 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.2 Integer types . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.3 Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.4 Floating point (real) numbers . . . . . . . . . . . . . . . . . . 232.5 Truth values - boolean . . . . . . . . . . . . . . . . . . . . . . 242.6 Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252.7 Type conversions . . . . . . . . . . . . . . . . . . . . . . . . . 282.8 Control statements . . . . . . . . . . . . . . . . . . . . . . . . 292.9 The ’if’ statement . . . . . . . . . . . . . . . . . . . . . . . . 292.10 The ’switch’ statement . . . . . . . . . . . . . . . . . . . . . . 312.11 A larger example - Zeller’s congruence . . . . . . . . . . . . . 332.12 Lexical requirements and program layout . . . . . . . . . . . 362.13 The ’while’ loop . . . . . . . . . . . . . . . . . . . . . . . . . . 402.14 The ’for’ loop . . . . . . . . . . . . . . . . . . . . . . . . . . . 402.15 The ’do while’ loop . . . . . . . . . . . . . . . . . . . . . . . 412.16 Worked example - golden ratio . . . . . . . . . . . . . . . . . 422.17 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

3 Simple input and output 473.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473.2 A simple example of I/O . . . . . . . . . . . . . . . . . . . . . 473.3 Worked example - grade average . . . . . . . . . . . . . . . . 493.4 Reading numbers . . . . . . . . . . . . . . . . . . . . . . . . . 513.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

3

Page 4: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

4 CONTENTS

4 Introduction to methods 554.1 Subprograms . . . . . . . . . . . . . . . . . . . . . . . . . . . 554.2 Methods with no result . . . . . . . . . . . . . . . . . . . . . 574.3 Scope of names . . . . . . . . . . . . . . . . . . . . . . . . . . 584.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

5 Making Applets 615.1 Applet basics . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

5.1.1 Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625.2 Basic graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

5.2.1 Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635.3 Getting input to an applet . . . . . . . . . . . . . . . . . . . . 645.4 Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

6 Introduction to Arrays 736.1 Array basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736.2 Worked example - standard deviation . . . . . . . . . . . . . 73

6.2.1 Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756.3 Initialising Arrays . . . . . . . . . . . . . . . . . . . . . . . . 766.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

7 Simple graphics 777.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777.2 Graphics objects . . . . . . . . . . . . . . . . . . . . . . . . . 777.3 Drawing lines . . . . . . . . . . . . . . . . . . . . . . . . . . . 777.4 Drawing shapes . . . . . . . . . . . . . . . . . . . . . . . . . . 787.5 Drawing strings . . . . . . . . . . . . . . . . . . . . . . . . . . 817.6 Color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

8 Mousing around 878.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 878.2 Basic mousing . . . . . . . . . . . . . . . . . . . . . . . . . . . 878.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90

9 Putting it all together 919.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 919.2 Know your mathematics . . . . . . . . . . . . . . . . . . . . . 919.3 If you repeat yourself you need to restructure . . . . . . . . . 929.4 Solve problems away from the computer . . . . . . . . . . . . 979.5 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

Page 5: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

CONTENTS 5

10 Files 9910.1 File basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9910.2 Security in Java . . . . . . . . . . . . . . . . . . . . . . . . . . 9910.3 Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10010.4 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

11 Strings 10511.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10511.2 Manipulating Strings . . . . . . . . . . . . . . . . . . . . . . . 10511.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

12 Manipulating information from files 11112.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11112.2 Tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11112.3 The StringTokenizer class . . . . . . . . . . . . . . . . . . . . 11312.4 Converting numbers . . . . . . . . . . . . . . . . . . . . . . . 114

13 Arrays 11513.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11513.2 Arrays of Strings . . . . . . . . . . . . . . . . . . . . . . . . . 11513.3 Searching a list of values . . . . . . . . . . . . . . . . . . . . . 11613.4 Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12113.5 Two dimensional arrays . . . . . . . . . . . . . . . . . . . . . 12313.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

14 A hint of HTML 12714.1 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12714.2 The big idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

15 A touch of class 13115.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13115.2 A new data type - a football team . . . . . . . . . . . . . . . 13115.3 Adding a constructor (a class method) . . . . . . . . . . . . . 13215.4 Multiple constructors . . . . . . . . . . . . . . . . . . . . . . . 13315.5 More methods . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

16 Loads of class 13716.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13716.2 What is a league? . . . . . . . . . . . . . . . . . . . . . . . . . 13716.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

17 Binary chop suey and orders of difficulty 14117.1 Orders of difficulty . . . . . . . . . . . . . . . . . . . . . . . . 14117.2 Searching revisited . . . . . . . . . . . . . . . . . . . . . . . . 142

Page 6: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

6 CONTENTS

18 Data structures - Vectors 14518.1 The nature of vectors . . . . . . . . . . . . . . . . . . . . . . 14518.2 The idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14518.3 Vectors versus arrays . . . . . . . . . . . . . . . . . . . . . . . 15218.4 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

19 Merging sorted lists - A fundamental algorithm 15519.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15519.2 Merging lists . . . . . . . . . . . . . . . . . . . . . . . . . . . 155

20 Recursion 15720.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15720.2 Worked example - Euclid’s algorithm . . . . . . . . . . . . . . 15720.3 The Tower of Hanoi . . . . . . . . . . . . . . . . . . . . . . . 160

21 Quicksort 16321.1 Divide and conquer algorithms . . . . . . . . . . . . . . . . . 16321.2 The Quicksort algorithm . . . . . . . . . . . . . . . . . . . . . 16321.3 Choosing pivots . . . . . . . . . . . . . . . . . . . . . . . . . . 16521.4 Performance of Quicksort . . . . . . . . . . . . . . . . . . . . 16621.5 Further improvements . . . . . . . . . . . . . . . . . . . . . . 166

22 Linked lists 16722.1 Dynamic data structures . . . . . . . . . . . . . . . . . . . . . 16722.2 A simple linked list . . . . . . . . . . . . . . . . . . . . . . . . 167

23 Binary search trees 17123.1 Tree terminology . . . . . . . . . . . . . . . . . . . . . . . . . 17123.2 Binary search trees . . . . . . . . . . . . . . . . . . . . . . . . 17223.3 Building binary search trees . . . . . . . . . . . . . . . . . . . 17223.4 Traversing trees . . . . . . . . . . . . . . . . . . . . . . . . . . 17423.5 Writing that in Java . . . . . . . . . . . . . . . . . . . . . . . 17423.6 Another way of representing trees . . . . . . . . . . . . . . . . 177

24 Hash tables 17924.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17924.2 The Dictionary abstract class . . . . . . . . . . . . . . . . . . 17924.3 Hash tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18024.4 Hash functions . . . . . . . . . . . . . . . . . . . . . . . . . . 18124.5 The Java class Hashtable . . . . . . . . . . . . . . . . . . . . 18224.6 Hash table implementations . . . . . . . . . . . . . . . . . . . 184

Page 7: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

CONTENTS 7

25 The bridge problem 18725.1 Stating the problem . . . . . . . . . . . . . . . . . . . . . . . 18725.2 Analysing the problem . . . . . . . . . . . . . . . . . . . . . . 189

25.2.1 Representing a Hand . . . . . . . . . . . . . . . . . . . 18925.2.2 Reading and Deciphering a Hand . . . . . . . . . . . . 19525.2.3 Printing the Hand . . . . . . . . . . . . . . . . . . . . 19725.2.4 Making the Bid . . . . . . . . . . . . . . . . . . . . . . 19825.2.5 The main program . . . . . . . . . . . . . . . . . . . . 199

26 Exceptions and Defensive programming 20326.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20326.2 The idea . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20326.3 Using standard Java exceptions . . . . . . . . . . . . . . . . . 20526.4 Defining your own exceptions . . . . . . . . . . . . . . . . . . 207

27 Binary numbers and representation in a computer 21127.1 Conversion between number systems . . . . . . . . . . . . . . 21127.2 Negative numbers . . . . . . . . . . . . . . . . . . . . . . . . . 21227.3 Bitwise operations . . . . . . . . . . . . . . . . . . . . . . . . 21327.4 Shift operations . . . . . . . . . . . . . . . . . . . . . . . . . . 214

28 Timing programs - Instrumenting your code to improve per-formance 21528.1 Introduction: a brief history of time . . . . . . . . . . . . . . 21528.2 Measurements . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

28.2.1 Measuring small quantities with tools that can onlyhandle large quantities. . . . . . . . . . . . . . . . . . 216

28.2.2 Repeat all measurements several times. . . . . . . . . 21628.2.3 Errors may be random or consistent. . . . . . . . . . . 21628.2.4 Distinguish between accuracy and precision. . . . . . . 217

28.3 The clock classes . . . . . . . . . . . . . . . . . . . . . . . . . 21728.4 Simple use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22128.5 Timing machine instructions . . . . . . . . . . . . . . . . . . 22228.6 Summary of simple optimizations . . . . . . . . . . . . . . . . 22428.7 Using instruments to help optimization . . . . . . . . . . . . . 22428.8 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

29 Sets 22929.1 The set concept . . . . . . . . . . . . . . . . . . . . . . . . . . 22929.2 The class BitSet . . . . . . . . . . . . . . . . . . . . . . . . . 23029.3 Creating a CharSet class . . . . . . . . . . . . . . . . . . . . . 23129.4 Using the CharSet class . . . . . . . . . . . . . . . . . . . . . 234

Page 8: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

8 CONTENTS

30 Stacks 23730.1 Stack basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23730.2 Benefits of abstraction . . . . . . . . . . . . . . . . . . . . . . 23730.3 Applications of stacks . . . . . . . . . . . . . . . . . . . . . . 23830.4 Java’s stack implementation . . . . . . . . . . . . . . . . . . . 239

31 Threads 24131.1 Thread basics . . . . . . . . . . . . . . . . . . . . . . . . . . . 24131.2 Threads in Java . . . . . . . . . . . . . . . . . . . . . . . . . . 24131.3 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

A Glossary of terms 245

B Writing about your work 249B.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249B.2 Reading is the best way to learn to write . . . . . . . . . . . . 249B.3 Nitty gritty . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250B.4 Writing the stuff . . . . . . . . . . . . . . . . . . . . . . . . . 251B.5 Technical reports . . . . . . . . . . . . . . . . . . . . . . . . . 252B.6 User manuals . . . . . . . . . . . . . . . . . . . . . . . . . . . 253B.7 Research reports . . . . . . . . . . . . . . . . . . . . . . . . . 253B.8 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254

Page 9: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 1

Computer Structure

1.1 The background to modern computers

Attempts to make calculating machines have a long history going back tothe abacus, calculating rods and Blaise Pascal’s calculating machine. Allthese are machines/devices for making arithmetic calculations. The moderncomputer is more than that. It can handle representations of many types ofdata (I am writing this on a word-processor which understands characters,paragraphs, pages etc.). The fundamental idea behind the modern com-puter is a processor (which can manipulate data and obey instructions), amemory which holds both the instructions to be obeyed (the program) andthe data to be manipulated (my word-processor is the instructions, my textis the data) and peripherals such as keyboards, printers, disc drives and soforth. The first attempt to construct such a machine was made by the greatEnglish mathematician Charles Babbage (1791-1871). He was professor ofmathematics at Cambridge between 1828-39. He designed a mechanicaldevice which had:

• A mill. This is what we now call the processor or CPU. It was toobey instructions and perform calculations. The term ’mill’ hascontinued in use until the last 20 years in some circles.

• A memory. This is what we now call RAM. Do not confuse it withdisc space.

• An input system based on punched cards then used to controlweaving looms.

• A printer. This was important because Babbage wanted to producetables (tides, artillery, mathematics etc) which, at that time, werecursed by the need to use humans to transcribe them.

Clearly then, Babbage had the whole idea but never got it working. Hewas using cogs and wheels, but the current view is that he could have still

9

Page 10: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

10 CHAPTER 1. COMPUTER STRUCTURE

got the thing to work if he had concentrated on getting a ’good enough’model working; instead he kept seeing better ways of achieving his ends;and so he kept changing the design. Eventually his financial backers gottired and pulled the plug (as they would not have known to say). Let thisbe a lesson.

Babbage’s work was pretty well forgotten and had to be reinvented. Thenext great step was the work of another English mathematician, Alan Turingin the 1930s. He was concerned with a particular problem.

Turing was concerned with the question ”can we always find an algorithmthat can solve any given problem?”. If you want a fancy name for it this isthe entscheidungsproblem. In 1937 (a good decade before the first electroniccomputer) Alan Turing answered this question for all computer models (i.e.2000 models and for all time to come), even before computers had come intoexistence. The answer is no. There exist problems which have a solution butfor which one cannot devise algorithms to find that solution1. Turing devisedan imaginary machine, a completely impractical device, and showed that hismachine could solve any problem that could be solved by any machine thatcould be created. It is, perhaps, best to look at that statement the otherway round: no computer, even your fanciest 10,000 MHz PowerPentium 100cannot solve a problem that Turing’s little plodder cannot. There may beother computer models, quantum computers come to mind, which may beable to transcend Turing’s model. For the moment these are fairly far in thefuture as practical devices.

While this places limits on the algorithmic approach to problem solvingit leaves us an enormous territory to explore. This is the turf of computerscience. WELCOME. So, what is this structure? Well it’s Babbage’s ma-chine:

Peripherals:

Disc/CD DrivesI/O Devices

Mouseetc.

Central Processing Unit

(CPU)

Memory:

Random Access Memory

(RAM)

There are some machines with multiple CPUs in order to improve per-formance.

1The same conclusion was also reached by the American mathematician Alonzo Churchusing a completely different approach from Turing’s. Church invented a system called thelambda calculus. If you want to see how Church and Turing could reach such a conclusionan excellent source is Penrose’s book mentioned earlier.

Page 11: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

1.2. THE NATURE OF ALGORITHMS 11

1.2 The nature of algorithms

There are three principal areas in computer science: hardware, algorithmsand programming methodologies. In this course we are mainly concernedwith algorithms with an introduction to methodologies and a bit of hard-ware.

The following material on algorithms is unashamedly plagiarised fromPenrose2. The word ”algorithm” comes from the 9th century Persian math-ematician Abu Ja’far Mohammed ibn Ms al-Khowrizm who wrote a text-book around 825 A.D. called ”Kitab al jabr w’all-muqabala” (note the wordalgebra).

Algorithms long predate our friend with the short name. The algorithmfor calculating highest common factors, known as Euclid’s algorithm, datesfrom about 300 B.C. To illustrate Euclid’s algorithm consider the numbers1365 and 3654. The HCF is the biggest number that exactly divides both3.

Euclid’s recipe: divide the larger number by the smaller and get theremainder. Replace the larger by the remainder and repeat the whole processuntil the result is zero. The last divisor is the HCF. e.g.

3654 ÷ 1365 gives remainder 9243654 ÷ 924 gives remainder 441924 ÷ 441 gives remainder 42441 ÷ 42 gives remainder 2142 ÷ 21 gives remainder 0

Therefore the HCF of 1365 and 3654 is 21.

Euclid’s algorithm is a systematic procedure for solving the problem.The most important activity in computer science is devising such algorithmsfor problems in a wide and growing set of problems. There are algorithmsfor mathematical problems, searching text, encryption, compressing infor-mation, constructing 3-D images, medical diagnosis, voice recognition, anal-ysis of chemical structures, planetary orbits etc., etc., etc. There are manybooks containing algorithms in a vast number of areas.

Figure 1.1 shows how we can represent Euclid’s algorithm as a flow chart.You won’t see too many of these, but they can help at first. The middle stepassumes we know how to calculate remainders. This is another algorithm.As an example, to calculate the remainder of 17 divided by 5 imagine 17stones; keep removing 5 until fewer than five remain. The number of stones

2Roger Penrose, ”The Emperor’s New Mind”, Oxford University Press, Chapter 23It doesn’t matter whether, on the first step, you divide the larger by the smaller.

Page 12: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

12 CHAPTER 1. COMPUTER STRUCTURE

Take two numbers A and B

Divide A by B and put the remainder

in C

C = 0?

Stop and print B

Replace A by BReplace B by C

No

Figure 1.1: A flowchart showing Euclid’s algorithm.

left is the remainder:

oooooooooooooooooremove 5 ooooooooooooremove 5 oooooooremove 5 ooresult is 2

Figure 1.2 shows how we can express this in a flowchart. When we sub-

Take two numbers A and B

B > A?

Stop and give result A

Replace A by A-B

No

Figure 1.2: A flowchart showing the calculation of the remainder.

stitute one algorithm in another we refer to the substituting algorithm as asubroutine (the terms subprogram, procedure and function are also used for

Page 13: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

1.2. THE NATURE OF ALGORITHMS 13

the same purpose, although there may be subtle differences about the use ofthese terms in different languages). In real life programs there are usuallymany subroutines, most of which are supported by other subroutines, whichin turn are supported by other subroutines, which in turn, as Jonathan Swiftsaid. . .

So, naturalists observe, a fleaHath smaller fleas that on him prey;And these have smaller fleas to bite ’em,And so proceed ad infinitum,Thus every poet, in his kind,Is bit by him that comes behind.

In fact, not ad infinitum. In programming we come to a point where wehave statements in our programming language that can perform certainstatements for us. When we have reduced our algorithms to these basicstatements we have programs.

So what is a programming language? It is an invented, artificial languagedesigned to allow the expression of algorithms. Like natural languages, com-puter languages have grammars and vocabulary but the grammars are gen-erally very regular and the vocabularies tend to be very small (about 40words in Pascal, for example); much simpler than natural languages. Acomputer is able to follow the description of an algorithm in such a lan-guage but as with all languages the challenge is not in learning the languagebut in learning to express one’s own ideas in the language (may it be toomischievous to suggest that the hardest bit is getting ideas to express in thefirst place?).

The most influential computer language was Algol4 (for ALGOrithmicLanguage) and its designers made an important distinction: a program cancommunicate an algorithm to a computer but it also, and equally impor-tantly, serves to communicate an algorithm from one human to another in anunambiguous way. Various languages have placed the emphasis at differentpoints on the continuum between instructing the machine (a strength of C)to informing a human (Algol, Pascal and Lisp are strong here). When dis-cussing algorithms it is best initially to ignore hardware and pay attentionto ideas and fundamental concepts. Transferring the algorithm to somethingthat runs on some manufacturer’s flakes of silicon is called implementation.

Once one has devised an algorithm, as we did with Euclid’s, we may needto make adaptations to get it working in some particular language on someparticular hardware. For example, we say in Fig 1 ”Take two numbers Aand B” and blithely assume that A and B are natural numbers in the range0 → ∞. But real hardware is not infinite. We have limits on the largestinteger we can represent, often as low as 32,767 (don’t ask why just yet).To get the idea of what a computer language looks like, figure 1.3 shows

4It is no longer used.

Page 14: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

14 CHAPTER 1. COMPUTER STRUCTURE

Pascal: function euclid(a, b : integer): integer;var c : integer;beginrepeat

c := a mod b;if c <> 0 then begin

a := b;b := c

enduntil c = 0;euclid := b

end;

Java:public static int euclid(int a,int b) {

int c;do {

c = a % b;if ( c !=0) {

a = b;b = c;

}} while (c != 0);return b;

} // euclid

Scheme/Lisp:(define (euclid a b)

(if (= b 0) a (euclid b (remainder a b))))

Figure 1.3: The Euclid algorithm in the languages Pascal, Java and Scheme.

Page 15: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

1.3. THE JAVA LANGUAGE 15

implementations of the Euclid algorithm in the languages Pascal, Java andScheme. Each of these programs expresses the same algorithm althoughyou may find some easier to understand than others. Pascal is intended tobe a language for teaching programming, C for experienced programmerswho have no problems with strange syntax but want to be able to controlthe machine at a low level in order to gain maximum efficiency, Java forInternet and embedded applications and Lisp for those who wish to explorealgorithms and worry little about the underlying hardware.

1.3 The Java language

Computer languages provide very formal representations of algorithms. Thefirst language that tried to express algorithms in a way that could be used forcommunicating with humans as well as machines was Algol (1960). This wasthe most influential computer language of all time and was the direct parentof the languages Pascal, Algol68 and C. C (invented by Kernighan andRitchie) was then the parent of Bjarne Stroustrup’s language C++ (whichwas also partly derived from Simula, another Algol offspring, and Algol68).Java was developed as a ’better’ C++ by a team at Sun Microsystems leadby James Gosling.

The Sun team wanted to be able to program consumer electronic devices(set-top boxes etc.) but in fact its greatest influence so far has been relatedto the Internet. We will later look at how this is so but for the time beingwe will concentrate on getting a Java program going. At the time of writingthe original aim of Java seem to be returning; Java is being used to putintelligence into consumer devices including signet rings.

Java is a new language and has a lot of buzzwords associated with it. Forthe time being it will be hard to understand all these but some you mightfind are covered in the following which is an edited down version from Sun’sJava pages.

The Java language provides a powerful addition to the tools thatprogrammers have at their disposal. Java makes programmingeasier because it is object-oriented and has automatic garbagecollection. In addition, because compiled Java code is architecture-neutral, Java applications are ideal for a diverse environment likethe Internet. For more information, visit the web site, http://java.sun.com/.

1.4 Getting started

To run your first Java program now work through the example in Appendix1. This covers the mechanics of running Java on the system we shall usein this course. Other Java systems do things differently. You can download

Page 16: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

16 CHAPTER 1. COMPUTER STRUCTURE

various free versions of Java from the Internet; they all look different fromthe system we use here; you’ll just have to cope with the mechanics.

1.5 A complete program

/*** Important: remember that the file must match the public* class name of the class containing the main method.*/

public class FirstApplication {public static void main(String args[]) {

System.out.println( "Hello World!" );}

}

Figure 1.4: A first Java program.

Figure 1.4 shows a first Java program. There are a number of points tonote about this.

• It starts with a section between the symbols /* and */. This is calleda comment and is intended to provide explanatory material for ahuman being reading the program. Here it is a reminder to theprogrammer of something easily forgotten.

• The section starting public and ending } is a class definition. At thisstage you don’t need to know too much about classes except that fora while all your programs will consist of just one class that containsjust one method.

• Words such as class and public are reserved words and have a specialmeaning in the language. The other reserved words in this exampleare static and void. A complete listing of reserved words will appearlater.

• There are other words here which are not reserved. In this case theyare TrivialApplication, main, String, args, System, out, println. Someof these have special meanings but they are not reserved because aprogrammer can redefine them but it best not to do so.

• The section that starts public static void and which ends } is amethod definition. For a while all your programs will contain onemethod called main. Execution of your program begins at the mainmethod.

Page 17: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

1.5. A COMPLETE PROGRAM 17

• The line System.out.println(”Hello World!”); is a statement. Thisparticular main method is very unusual in that it has only onestatement. Most methods contain many statements which areexecuted in sequence.

• The println bit in the above is a method belonging to System.out.Don’t worry about the technicalities here; the meaning will beexplained carefully later but should be fairly clear by now.

• The part in quotes, ”Hello World!” is called a string. A string is asequence of characters in double quotes. It is the way one writes atext value.

• In the example the string is an argument to the println method.Arguments are in parentheses after the method name. In effect thissays ’invoke the println method with ”Hello World!” as anargument’. An argument passes a value to a method.

Later you will write applications and applets which contain many methodsand use many classes. For the time being all your programs will take thefollowing form:

public class SomeName {public static void main(String args[]) {

// Your program statements go here.}

}

Much of the above can be regarded as ’boiler plate’; just take it on trustand always type it the same way.

Where it says SomeName you must give a name which can be any identifierthat is not a reserved word.

The name of the file in which you put your program must be whateveryou gave as SomeName followed by .java.

You put your own statements at the point indicated. Execution of yourprogram begins at the first of these statements and proceeds through themone at a time up to the end. Later you will see how to change the order ofexecution of your program statements by using control statements.

The first programs you will see are rather artificial and are just forshowing basic ideas (like five-finger exercises for the piano). Once we havegot over those we will start to write more realistic applications and applets.

Page 18: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

18 CHAPTER 1. COMPUTER STRUCTURE

Page 19: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 2

Elements of Java Programs

2.1 Data types

Some languages are typeless (Lisp/Scheme and some Basics); this meansthat a variable can, at one instant hold a string (say), and later it holdsan integer or a floating point number or whatever. Whilst this promiscuitycan be convenient it can also make programs hard to understand or debug.Java, like all the languages in its family, requires strict types;: every variablebelongs to one type. Java does, however, allow a little loophole that is handyin some circumstances. We shall see this later; for the moment let’s keep itsimple.

Some languages, for example C and Pascal, only allow variables to becreated from primitive types (or collections of them) which have a naturalrepresentation on a computer. Some other languages, such as Smalltalk,only allow variables that are objects; these are variables which have bothvalues (possibly collections of values) and methods which manipulate thoseobjects. If this distinction is not clear then don’t worry; it will be later.

Other languages, such as C++ and Java allow a mixing of fundamentalcomputer types and objects. Whilst Java tends to lean toward objects itdoes acknowledge primitive types. For the first part of these notes we shalluse only primitive types because they are simple to handle and allow manyprogramming concepts to be introduced.

All values in a computer are represented as sequences of ones and noughts(bits, Binary digITs). The hardware of a computer does not distinguish be-tween integers (whole numbers), real numbers (those with a decimal point),characters (a, b, c,. . . ) or anything else. It just represents them all as se-quences of ones and zeros. So the character ’A’ is also the integer 65 (onmost machines) and what it would be as a floating point number I can’t bebothered to ascertain.

Computers (like mathematics) make a distinction between integers andreal numbers. Integers are whole and exact (1, 2, 3, 4 etc.) whereas reals are

19

Page 20: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

20 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

approximate and hold fractional parts (1.32, 0.000000001, 999.213). Integerarithmetic is exact (5 + 7 = 12, exactly, no error) but the real calculation 5.0+ 7.0 could give 12.0, or 12.00000001, or 11.999999999 or some such closevalue. This distinction is not an artifact of computers; the world makes thesame distinction (although the great mathematician Kronecker did say ”theintegers are the work of God, all else is the work of man”).

To make this more concrete: the number of eggs in my fridge is aninteger (unless I break one and remove part of it). The number of childrenin a family is an integer. The average number of children per family in agiven population is a real number (for example, 2.4 children).Some itemsare naturally countable, and so are integers (apples, children, protons ina nucleus) whilst others are real and uncountable (temperature, weight,height). There is only one integer between 1 and 3 (2) but there are aninfinite number of reals between 1.0 and 3.0.

Because of these distinctions computers must distinguish between realsand integers and they are represented in quite different ways. Java, and itsrelated languages, require that variables be declared to have a certain type.

An example of some declarations is:

• float velocity, acceleration;

• int numberOfBodies;

• char initial, terminator;

Here velocity can hold a floating point number, but numberOfBodies mustbe an integer and initial must be a character.

2.2 Integer types

As we saw above, we can declare a variable to be an int; Java, however,allows several different types of integer of which int is only one. This mayseem unnecessary complication but is for efficiency reasons. If a numberis small, such as my bank balance, then we can use an integer type thatdoes not require much computer memory. On the other hand, if we want torepresent Bill Gates’s wealth in Italian lira then we must use an integer typethat can hold a large value but which also requires more computer memory.It is an engineering decision choosing which integer type is appropriate butwhen in doubt it is probably better to be generous and choose a type whichcan hold larger values (technically these are called wider types). This wayyou avoid problems such as the famous year 2000 bug (or at least postponeit).

The smallest of the integer types is a byte, which can hold values between-128 to 127. It occupies 1 byte (8 bits) of memory and so is quite cheap. In

Page 21: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.3. CHARACTERS 21

most languages (but not Java) it also corresponds to a character. A bytevariable can be declared in a statement of the style:

byte littleNumber;

The next smallest integer type is short, variables of which can take the values-32,768 to 32,767. They occupy 2 bytes (16 bits). Next we get the type intwhich allows -2,147,483,648 to 2,147,483,647 and finally, if you really wantto calculate Bill Gates’s wealth in lira, there is long which allows values inthe range -922,337,203,685,475,808 to 922,337,203,685,475,807.

To summarise, we have:

byte -128 to 127short -32,768 to 32,767int -2,147,483,648 to 2,147,483,647long -922,337,203,685,475,808 to 922,337,203,685,475,807

When we want to write values of any of these integers in programs there arethree choices: we can use the decimal (or denary, base 10) system with whichwe are all familiar, or octal (base 8) or hexadecimal (base 16). These lasttwo are used because it is trivial to translate them into the binary systemwhich is actually used inside computers.If you do not know these numbersystems (which probably means you were born before 1955 or after 1970, orwent to a private school) then look at chapter 30.

When we want to write a decimal (ordinary) numbers then just writethem in the usual way such as 27 or -45. Never put a leading zero(e.g 027)as this changes the meaning. In fact it says that the number is octal (base8) so that 027 is decimal 23 (2 * 8 + 7). To indicate that a number ishexadecimal precede it with 0x. The number 0x27 is 39 in decimal (2*16 +7). In summary:

37 the decimal number 37037 the octal value equivalent to the decimal value 310x37 the hexadecimal value equivalent to

the decimal value 55

We shall not be using octal or hexadecimal for quite some time (when theywill be explained more carefully); they are included here for completenessand for those readers who already understand number systems and just wanta quick reference on how to use them in Java.

2.3 Characters

Characters and integers are very closely related in Java and it is easy toconvert from one to the other. However, if you print a character you will geta character output, not its equivalent integer. As an example, the character

Page 22: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

22 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

’A’ is represented by the integer 65 inside your computer, but you willvery rarely need to know this. Most languages use a character encodingcalled ASCII (American Standard Code for Information Interchange) whichuses one byte (8 bits) to represent a character and so allows 128 possiblecharacters (of which 32 are ’invisible’). Alert readers will be saying ”but 8bits allows 256 possibilities”. Well, for historical, technical reasons one bitis wasted.

Java does not use ASCII; instead it uses a scheme called Unicode whichuses 2 bytes (16 bits) per character, allowing over 65,000 possible values.This allows non-Roman alphabets such as Cyrilic, Thai and so on. Thismeans that Java programs can handle pretty well all alphabets in the world.

As with ASCII, there are some ’invisible’ characters, which we shall lookat shortly. For ordinary, printable characters it is easy to write them; forinstance ’A’ represents capital A. Therefore given the declaration:

char ch;

we can put a value into ch by writing:

ch = ’A’;

Novices sometimes confuse the terms character, letter and digit. Rememberthat a character is anything which is covered by Unicode ( 65, 000 values),a letter is any of the alphabetic symbols ’A’ to ’Z’ and ’a’ to ’z’. A digit isany of the ten characters ’0’ to ’9’. There are also punctuation charactersand control characters, some of which are covered in the next paragraph.Finally novices often do not regard the space character as a character ”itdoesn’t print anything”. Well it does, it prints a little empty gap on yourscreen. To get it you use the character value ’ ’.

All the letters, digits and most of the punctuation characters are allwritten the same way, enclosed in single quotes: ’a’, ’z’, ’6’, ’?’ and so on.Often, though, we need to print a character to move to the next line orsome such. These characters require a special technique to represent themand Java (as C or C++) uses what is known as an ’escape character. Thisis a character which does not represent itself (unlike ’A’) but modifies thecharacter following it. In Java this character is ’ ’ (usually called backslash).As an example, ’n’ is just the ordinary character n, but ’ n’ represents thenewline character we mentioned above and causes printing to move to thenext line when we are printing text This use of an escape sequence is theonly time we can put more than one symbol between ’ and ’.

Warning A char can only hold a single character; if you want to representwords, sentences or anything else involving multiple characters you need astring, which we shall see a little later.

The escaped characters used to effect printing are:

\n newline; move to next line

Page 23: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.4. FLOATING POINT (REAL) NUMBERS 23

\t tab; move to the next tab stop\b backspace; move back one character\f form feed; move to next page

(used on old style printers)\r carriage return; move to start of line

It is unlikely that we shall need any of these except ’ n’.Advanced Topic (Inexperienced programmers can ignore this)

As was mentioned, all characters are internally represented byintegers. It is sometimes, but very rarely, necessary to use thosenumbers rather than the actual character. This arises if we needone of the invisible characters which are not covered by the es-caped characters above (some of these can produce useful effectson certain printers or old fashioned displays). To do this youneed to know the number representing the character you want(in octal).

Suppose you wish to produce the character ’A’ by this method(this would be very bad practice but it makes it easy to see theidea). ’A’ is represented by 65 in decimal which is 101 in octal.Therefore ’A’ is equivalent to ’ 101’. The three digits are in octaleven though there is no leading zero.

2.4 Floating point (real) numbers

The integers, which were covered in the last section, are used to representcountable quantities (the number of pages in a book, the number of coinsin your pocket) and integer arithmetic is exact (27/9 is exactly 3). Betweenany two integers there are a finite number of other integers so that between1 and 3 there is one integer (2). Because of these properties integers are saidto be discrete.

Floating point (more often called ’real’) numbers represent continuousquantities such as a temperature, the weight of a book, the average size ofa family in a population (e.g. 2.4 children).Between any two floating pointnumbers there is an infinity of floating point values. So between 1.0 and2.0 there are infinitely many floating point values. At least, this is howmathematicians put it.

In fact, because we cannot build infinite computers, floating point num-bers are just quite good approximations to the mathematician’s concept ofreal numbers. They are not quite continuous but are near enough for manypractical purposes (pure mathematicians don’t have practical purposes).

Writing floating point numbers is done in a style which is frequently usedby scientists and which you probly know as it is used on almost all pocketcalculators except those which come free with a packet of corn flakes. For

Page 24: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

24 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

example, the number of stars in our galaxy is roughly 1011. The age ofthe Universe is roughly 1.5x1010 years old and so on. Writing that latterwithout the power of ten (exponent) would be 15,000,000,000 which is veryhard to read. Very small numbers are written with a negative exponent suchas 5x10-7 metres, which is the wavelength of light close to the centre of thevisible spectrum. In that last number we say that 5 is the mantissa and -7is the exponent.

Most computer languages use this system to represent real values butwith a slight change to accomodate simple editors and displays which cannothandle superscripts or subscripts. In Java, as in many languages, the lettere represents ’x 10 to the power’ so that the above values would be writtenas:

1011 → 1e11

1.5x1010 → 1.5e10

5x10− 7 → 5e−7

Most calculators have a key equivalent to the e.

Java has two types to represent real numbers: float and double. You choosewhich to use according to the precision (the number of digits in the mantissa)you need in your calculations (remember that computers are finite and sothere must be a limit to the precision as well as the ultimate size of a realnumber).

To find the largest and smallest values that float and double can supportthere are the pre-defined constants Float.MAX_VALUE, Float.MIN_VALUE,Double.MAX_VALUE, Double.MIN_VALUE. Although you never need to usethe numbers directly it can be interesting to see them so that you get a feelfor the magnitudes and precisions involved, so here they are:

Float.MAX V ALUE 3.4028235e38

Float.MIN V ALUE 1.4e45

Double.MAX V ALUE 1.7976931348623157e308

Double.MIN V ALUE 4.9e32

2.5 Truth values - boolean

There is a type boolean which is named after the nineteenth century mathe-matician George Boole. Boole studied logic in a formal way and then wrotea book called ”The Laws of Thought” explaining his discoveries. In partic-ular he described an algebra, later named after him, where quantities canhave only two values which we can conveniently call true and false. In Javawe can write statements such as:

boolean tall, handsome;tall = true;handsome = false;

Page 25: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.6. OPERATORS 25

We shall see later how these types of variables can be combined into expres-sions which are used to make decisions in programs, but first we have tostudy operators.

2.6 Operators

Like C, Java has many operators which are used to calculate, select andassign values. We can’t cover all of them at this stage, but we can coversome of the basic ones. As an example, consider the statement:

x = (-b + Math.sqrt(b*b - 4*a*c))/(2*a);

This contains the operators +, -, *, / and =. The - occurs in two forms whichare regarded as distinct; in -b it is monadic (has one operand) and gives aresult that is the negative of the current value of b, but in b*b - 4*a*c it isdiadic (has two operands) and gives a result that is the difference betweenthe value of b*b and the value of 4*a*c. Here the multiplying operator *and the dividing operator / are also diadic.

Almost all operators yield a result; thus in 5 + 5 the operator + yieldsthe value 10. The assigning operator = is no exception and yields a resultas well as assigning a value. It takes the value of the expression on its right-hand side and copies it to the variable on its left-hand side but it also yields,as a result, the value copied. For example:

y = 2*x + 3;

multiplies x by 2 and adds 3, putting the result in y. Thus if x is 3 then ybecomes 9. Now consider:

z = 5*(y = 2*x + 3);

Here the value of y is also delivered as the result of the inner = . The valueof y is multiplied by 5 in order to produce the value ultimately assigned toz. If x were 3 before the statement, then afterwards x would still contain 3,y would contain 9 and z would contain 45. The above is a short form for:

y = 2*x + 3;z = 5*y;

All operators have a priority (or precedence) and an associativity which, be-tween them, decide the order in which operations are performed. Operatorswith a higher priority will be performed before operators of a lower priority,and operators of equal priority will be performed according to whether theyassociate left-right or right-left. The highest priority arithmetic operatorsare * and / (multiply and divide) and the lower ones are + and - (add andsubtract). This is just like algebra. The expression 24/6 ∗ 2 contains the

Page 26: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

26 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

operators / and * which have equal priority and associate from left to rightso that the result of the expression is 8.

Associativity is concerned with how expressions are evaluated when theoperators in them have the same priority. For example, 27/3 ∗ 2 gives 18;work from the left with 27/3 giving 9 and then multiplying by 2. Hence wesay that * and / associate left to right. All the arithmetic operators (*, /,%, +, -) associate this way.

The normal priority and associativity can be overcome by use of paren-theses; thus 24/(6*2) yields the value 2. Because there are so many levels ofpriority in Java it is a good idea, when in doubt, or when writing complicatedexpressions, to use parentheses to make your intention explicit.

Most operators associate left-right but there are some, in particular theassigning operators (=, + =, − =, ∗ =, / = and a few others), whichassociate right-left:

a = b = c = 4;

puts the value 4 into c, then into b then into a. We discuss + =, − = etc.below.

The operators below represent only a part of the full list. In the de-scriptions l represents a left operand, r a right operand and m a middleoperand.

The simple diadic arithmetic operators are:

∗ Multiply, highpriority/ Divide, highpriority% Modulus(remainder27%5is2), highpriority+ Add, lowpriority− Subtract, lowpriority

If both operands of / are integer, then the division will be integer divisionbut if either operand is of type float (or double) then floating point divisionis used. For example 7/2 gives the result 3 but 7.0 / 2 gives the result 3.5.The operator % can only be used between integer operands and gives theremainder. For example, 27%6 gives the value 3.

Because expressions such as l = l + r are very common, a special set ofoperators is available which provide a shorthand. Thus the example abovecan be written l += r. This shorthand version, apart from being easierto write, is more explicit and will often be be faster, especially if l is acomplicated expression. Analogous to += there are the operators -=, *=,/= and. These are examples of the assignment (or mutating) operators.Examples of the arithmetic ones are:

l += r equivalent to l = l + rl -= r equivalent to l = l - rl *= r equivalent to l = l * r

Page 27: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.6. OPERATORS 27

l /= r equivalent to l = l / rl %= r equivalent to l = l % r

Operators are classed as postfix (used after an operand, e.g. p++), prefix(used before an operand, e.g. ++p), diadic (used between two operandse.g. p + q) or triadic (used with three operands. There is only one triadicoperator, :?. It is used in expressions of the form (a ¿ 0) ? a : -a where thefirst operand is (a ¿ 0), the second is a and the third is -a).

When adding to, or subtracting from a value it is common to need to addor subtract unity (one). In these cases it is convenient to use the incrementand decrement operators, ++ and –. These can be used as prefix or postfixoperators, the difference between them lies is in the value delivered by theoperator, not in the effect on the left operand.

Use of the post-increment operator is illustrated by l++. l is incrementedby one, but because it is the post-increment version of ++ the value deliveredby the operator is the original value of l; the incrementing takes place afterthe value has been delivered. Thus, after

b = 27;a = b++;

the value of b would be 28 and a would be 27.

The pre-increment version of the same operator takes the form ++r. Withthis operator incrementing takes place before the value is delivered. Thusafter the statements

b = 27;a = ++b;

a and b will both equal 28.

The decrement operators are similar, for instance

b = 27;a = --b;

leaves b equal to 26 and a equal to 26 and

b = 27;a = b--;

leaves b equal to 26 and a to 27.

There are operators for comparing values. These all give boolean results(trueor false) described in section 2.1. The operators are:

Page 28: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

< less than 2 < 3 gives true> greater than 2 > 3 gives false<= less than or equal 2 <= 3 gives true>= greater than or equal 2 >= 3 gives false== equal 2 == 3 gives false!= not equal 2 != 3 give true

2.7 Type conversions

We frequently need to convert from one type to another: we may want toconvert an int to a float for example. This is called casting and is sometimesautomatic. The types described above have different widths and the order,from the narrowest to the widest, is: byte, int, long, float, double. Thetype of a value will be automatically widened if the context demands. Forexample, given the declarations:

byte bVar;int iVar;long lVar;float fVar;double dVar;

then:

lVar + iVar // converts iVar to long before the// addition.

fVar = Ivar // converts iVar to float before// assignment.

dVar * bVar // widens bVar three times before// multiplying.

bVar + iVar + lVar // widens bVar to int, performs the// first addition,then widens the// result to long and performs the// second addition.

Type conversion from a wider to narrower type is trickier because informa-tion must be discarded, and it is essential to understand how this will occur.If you want to convert a float to an int there will be loss of the fractionalpart; for example, 3.7 is converted to 3. Because of the loss of informationyou have to write a cast explicitly. In this case you write something like:

iVar = (int) fVar;

Notice that the fractional part is simply discarded. If you want to round upor down you need some methods from the module Math which we shall seelater.

Page 29: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.8. CONTROL STATEMENTS 29

2.8 Control statements

All the programs we have seen so far just follow a sequence of steps withoutchanging direction. The control statements of a language are those state-ments which allow choices to be made or which express repetition. Java hastwo statements for making choices: the if and switch statements. Repetitionis provided by the while, do - while and for statements. Most of the descrip-tions of syntax below indicate where a statement can occur. In these placesthis may be a simple statement terminated with a semicolon but often onewishes to include several statements. A sequence of statements can be madeinto a compound statement or block by enclosing them in curly brackets .For example

{System.out.println("Dave\’s amazing program:");System.out.println(" never accept anything else");

}

The part enclosed in curly brackets above can appear anywhere where astatement is required.

2.9 The ’if ’ statement

This takes either the form:

if (expression) statement

or

if (expression) statementelse statement

The expression must be one that gives the value true or false (see above). Inthe first case statement will only be executed if the expression yields true. Ifit yields false then statement is skipped. In the second case, if the expressionis false then the statement after the else will be executed. For example,

if (discriminant < 0)System.out.println("There are no real roots "

+ "for this equation.");else {

CalculateRoots();PrintRoots();

}

Page 30: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

30 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

Here, if discriminant is negative then the first limb of the if (that’s the bitstarting System. . .) will be obeyed. If not then both statements after theelse will be obeyed (both because they are inside and and so constitute acompound statement).

if statements with else parts can be chained together to provide multiplechoices in statements of the form

if (exp1)statement1

else if (exp2)statement2

For example:

if (age > 30)System.out.println("Too old.");

else if (age < 18)System.out.println("Too young.");

elseSystem.out.println("Just right.");

This can be shown as a flowchart:Programmers used to other languages should note that the parentheses

around the condition which follows if are mandatory, there is no reservedword then, and there is a semicolon between the statement in the first partand the else section. In Java semicolons act as statement terminators andmust be included even before else or }.

The next fragment could be used to print a ruled line automatically after30 lines have been printed:

if (lines == 30) {System.out.println("______________________________");lines = 0;

}else

lines++;

Notice here how { and } are used to group statements. All the parts in thefirst section of the if statement can be treated as one statement, but noticealso that the } is not followed by a semicolon.

There is a trap for the unwary in the so called ’dangling else’. Lookcarefully at the statement below:

b = 2;if (a < 0)

if (a == -1)

Page 31: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.10. THE ’SWITCH’ STATEMENT 31

b = 3;else

b = 4;

After this statement, what would be the value in b if a contained 1? Theindentation implies that the fragment is intended to set b to 4 but in factit will leave it unchanged. The else associates with the closest preceding ifbefore it and the indentation should be:

b = 2;if (a < 0)

if (a == -1)b = 3;

elseb = 4;

If the true intention is to assign 4 to b, the fragment could be rewritten:

b = 2;if (a < 0) {

if (a == -1) b = 3;} else {

b = 4;}

It is important to use semicolons correctly. A compound statement (i.e.statements enclosed in and ) should not be followed by a semicolon, but allother statements should be. Common errors are:

if (a == 37); // WRONG. The ; ends the if statement sob += 1; // that b += 1 is obeyed irrespective of

// the value of a.if (a == 37) {

b += 1;}; // WRONG. No ; after }else

b += 2;

The reserved word break is a statement which forces the termination of thestatement in which it is contained. Its most popular uses are to force loopstatements to terminate or to exit switch statements (see the next section).

2.10 The ’switch’ statement

The switch statement is used when it is necessary to check an integer valueagainst a list of possible values and to take different actions in each case.As an example:

Page 32: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

32 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

switch (ch) {case ’y’:case ’Y’:

System.out.println("Yes.");break;

case ’n’:case ’N’:

System.out.println("No.");break;

default:System.out.println("Please reply Y, y, N or n.");break;

}

Here the value in the variable ch is compared with each of the constantvalues after the reserved word case. If a match is found then executionswitches to the start of the section marked by the matching case from whereexecution continues until either the } at the end of the switch statement, ora break statement is reached. If no match is found in one of the cases thenthe section labelled default is taken. The effect of the above statement isthus equivalent to:

if (ch == ’y’ || ch == ’Y’ )System.out.println("Yes.");

else if (ch == ’n’ || ch == ’N’)System.out.println("No.");

elseSystem.out.println("Please reply Y, y, N or n.");

The following points should be noted:

• Usually each section ends with a break statement, but this is notalways so. If break is omitted on any section, then after execution ofthat section control will flow into the next case. For example, if thebreak after case’Y’ were omitted, the output, if ch were ’y’ or ’Y’,would be:

YesNo

This effect can sometimes be useful, as it is above for ’n’ and ’y’, butshould be treated cautiously; it should be carefully commentedbecause the intended action may be obscure to an unwary reader ofthe program1.

1The author knows a competent programmer who spent several days trying out why

Page 33: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.11. A LARGER EXAMPLE - ZELLER’S CONGRUENCE 33

• The default section is optional; if it is omitted and no case matchesthe expression following switch then no action will be taken. In theexample the break in the default section is not necessary because it isthe last section, but it has been included because it helps preventmistakes if new sections are added later.

• case must be followed by a constant or constant expression. Therules for what constitutes a valid constant expression arecomplicated, but for our purposes will be treated as expressionscontaining only constants, simple operators and parentheses.Assigning operators, the sequence operator, increment and decrementoperators and function calls are not allowed, either because theywould not make sense, or because they would make the life of acompiler writer too difficult. All the constant expressions in a switchstatement must have different values.

• The expression in the parentheses after switch must be one of byte,char, short or int. longs, floats or doubles are not allowed.

2.11 A larger example - Zeller’s congruence

We are now ready to look at a more realistic program. There is an algorithmfor calculating the day of the week of any given date. It was inventedby the Reverend Zeller and so is called Zeller’s congruence. It is not forus here to explain why it works but it involves carrying out a sequenceof arithmetic operations and uses many operators and statements, so it ishandy as something upon which to hang a demonstration. A program thatillustrates it is shown below.

package pij.elementsofjava;

/*** Calculate the day on which any date falls using Zeller’s congruence*/public class Zeller {

public static void main(String args[]) {int day = 23;int month = 6;int year = 1997; // The day I’m writing this.int yearInCentury = year % 100;int century = year / 100;

someone else’s program, which appeared wrong, actually worked. She then realised that amissing break was deliberate. An appropriate comment by the original programmer wouldhave taken 10 seconds to type; its omission cost someone several days work.

Page 34: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

34 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

int adjustedMonth, dayOfWeek;

// Adjust the month so that March is month 1// and February 12adjustedMonth = month - 2;if (adjustedMonth <= 0) {

adjustedMonth += 12;--yearInCentury;

}

// Calculate the day of the week with// Sunday = 0, Monday = 1 etc.dayOfWeek = ((13 * adjustedMonth - 1) / 5 + day

+ yearInCentury + yearInCentury / 4 + century/ 4 - 2 * century) % 7;

// Print the resultSystem.out.print("Date " + day + "/" + month + "/"

+ year + " is ");switch (dayOfWeek) {case 0:

System.out.println("Sunday");break;

case 1:System.out.println("Monday");break;

case 2:System.out.println("Tuesday");break;

case 3:System.out.println("Wednesday");break;

case 4:System.out.println("Thursday");break;

case 5:System.out.println("Friday");break;

case 6:System.out.println("Saturday\n");break;

}}

}

Page 35: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.11. A LARGER EXAMPLE - ZELLER’S CONGRUENCE 35

The output from this was:

Date 23/6/1997 is Monday

While this program does not use Java in the way that an experienced pro-grammer necessarily would regard as the ’best way’ (the switch statementis not a good way of printing the names of the days), it uses many of thefacilities of the language, in particular:

• The two conditional statements in Java are both used in thisprogram. The first is the if statement illustrated by:

if (adjustedMonth <= 0) {adjustedMonth += 12;-yearInCentury;

}

which will obey the two statements between and only if thecondition in parentheses (AdjustedMonth <= 0) is true. It may helpto expand this so that it doesn’t use any of the contracted forms (+=etc.). It is equivalent to:

if (adjustedMonth <= 0) {adjustedMonth = adjustedMonth + 12;yearInCentury = yearInCentury - 1;

}

• The second conditional statement used is:

switch(dayOfWeek) {case 0: System.out.println("Sunday"); break;case 1: System.out.println("Monday"); break;case 2: System.out.println("Tuesday"); break;case 3: System.out.println("Wednesday"); break;case 4: System.out.println("Thursday"); break;case 5: System.out.println("Friday"); break;case 6: System.out.println("Saturday\n"); break;

}

which compares the integer value dayOfWeek with each of theconstants 0, 1, 2 etc. If a match is found the statements between thecase label (the number before the colon) and the break statement areobeyed. If no match is found then no action is taken.

Page 36: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

36 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

• This program uses many operators, most of which have obviousmeanings, but a few need a little explanation:

% is the modulus operator. It gives the remainder when the value ofits left-hand operand is divided by the value of its right-handoperand. Hence 27%5 is 2.

/ is the division operator. As we are here dealing with integers thenit is the integer version of / that is used. This means that 27/5 gives5, not 27.4.

– causes its operand to be decremented by one. For example, if xholds the value 27 then –x will leave x holding the value 26.

+= adds the value of the expression on its right to the variable on itsleft. Thus, adjustedMonth += 12 is an abbreviation for:adjustedMonth = adjustedMonth + 12.

• The line that reads

System.out.print("Date " + day + "/" + month+ "/" + year + " is ");

uses a new method print. Like println this prints a string, but doesnot move the printing position to a new line. In this way it ispossible to build up a line of output by adding to the end of it byusing print repeatedly. When the line is finished use println.

2.12 Lexical requirements and program layout

Now that we have seen a largish program you will notice that it is not laidout in a random way. There is very clearly some structure in the way theprogram appears on the page. It is important to realise that this has nosignificance as far as the computer is concerned; programs are laid out care-fully to make them easy for people to read. Professional programmers layout their programs very carefully and do it all the time they are program-ming. Careful layout is not something to be left until the program works.There are various styles of typographical presentation of programs, somevery formal, others less so. The style described below is one style and onlybroaches this topic.

An identifier is a name chosen by a programmer to represent a variable,type, function, etc. An identifier can contain letters, digits and the under-score character but must start with a letter. The underscore character istreated as a letter. Java distinguishes the case of letters in identifiers; inother words Capital and CAPITAL are distinct, although it is bad practiceto use two identifiers which are distinguished only by the case of some oftheir component characters. An identifier can be any length.

Page 37: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.12. LEXICAL REQUIREMENTS AND PROGRAM LAYOUT 37

It is a common practice to type variable names in lower case and con-stants in capitals; for example, don juan might be used for a variable, PENE-LOPE for a constant. Here we shall not use underscores in variable namesas we prefer to write names such as the above in the style: donJuan.

Words which have special significance in the language such as while, int,do, for etc. must be written in lower case and may not be used as identifiers.The reserved words are:

abstract do implements package throwboolean double import private throwsbreak else inner protected transientbyte extends instanceof public trycase final int rest varcast finally interface return voidcatch float long short volatilechar for native static whileclass future new sureconst generic null switchcontinue goto operator synchronizeddefault if outer this

You must not use these words for your own symbols. To assist you inavoiding these the editor you use may put them in a different color from therest of the program.

All professional programmers claim that programs should be clear andreadable (and of course claim that theirs always are); that Java permits pro-grams to be obscure, tricky and arcane is, unfortunately, also true. However,by adopting a disciplined approach to layout, style, commenting and choiceof programming constructs, it is possible to write Java programs that are asreadable as programs in any other language. The following points may helpindicate approaches to good style:

White space, meaning use of spaces, tabs and blank lines, improves read-ability. For example

(sum+=term/=2)<=epsilon

is a little less readable than:

(sum += term /= 2) <= epsilon

In general, it is a good idea to surround assigning operators by space charac-ters. Blank lines should be used to separate functions and logically distinctsections of a program.

Indentation and statement separation can be used to show the scope ofa control statement. Thus the following program fragment, which printsFibonacci numbers,

Page 38: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

38 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

fib1 = fib2 = 1;System.out.println(" " + fib1 + fib2);do {

fib = fib1 + fib2;fib1 = fib2;fib2 = fib;System.out.println(" " + fib);

} while (fib < 1000);

is more readable than:

fib1=fib2=1;System.out.println(" " + fib1 + fib2);;do {fib=fib1+fib2;fib1=fib2;fib2=fib;System.out.println(" " + fib);} while (fib<1000);

The first version uses indentation to show which statements belong inside thedo . . . while loop, there is only one statement per line, and space charactersseparate the components of a statement.

In general it is a good idea to use only one statement per line, but thisrule can be broken if the statements are very simple and related, such asassignments initialising a few variables. For example, instead of:

i = 2;j = 4;k = 6;

it can be just as clear to use:

i = 2; j = 4; k = 6;

where the statements are separated by several spaces rather than a new line.Part of the purpose of indentation is to distinguish statement blocks and

to show which symbols are intended to match. Two styles are commonlyused for this. The first is illustrated by:

if (ch == ’\n’){

++Lines;CharPosition = 0;

}else{

++CharPosition;if (CharPosition > MaxLength){

System.out.println("Line too long.");return 1;

}}

Page 39: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.12. LEXICAL REQUIREMENTS AND PROGRAM LAYOUT 39

where each { and } is on a separate line and each } is directly beneath itsmatching {. The second method would write this fragment as:

if (ch == ’\n’) {++Lines;CharPosition = 0;

}else {

++CharPosition;if (CharPosition > MaxLength) {System.out.println("Line too long.");return 1;

}}

where each } is below the reserved word introducing a section of a controlstatement. The examples in these here use the second form because it ismore concise.

Meaningful identifier names help comprehension enormously: lineNum-ber is better than L, or even linNo. Programmers should not be undulydeterred by length when choosing a good name although over-zealous appli-cation of this principle can look a little ridiculous. For example,

lineNumberOfTheSourceCodeOfTheTestProgram

has a well explained purpose but it would be confusing if it were to appearin a complicated expression. It is common practice always to start variableand method names with a lower case letter and class names with a capitalletter. For example, iAmAVariable and IAmAClass.

Comments should be used at the start of a function (method) to describeits parameters and purpose and at the start of each logically separate sectionof a program. Comments should also be used to clarify code which may notbe immediately transparent, as in the case:

if ((n / 2) * 2 == n) // test for even n

Some inexperienced programmers find it difficult not to over-comment orgive trivial comments; well-meaning beginners often produce the followingstyle of comment:

i = 1; // assign 1 to i

However, this is not helpful and it is perfectly proper to giggle at the per-petrators of this type of thing while making tapping gestures with a fingeron the side of one’s head. Eye rolling is also allowed.

Page 40: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

40 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

2.13 The ’while’ loop

The pre-condition loop (i.e. the loop which tests its condition before execu-tion) is the while loop. The general form is: while (expression) statement.

The effect is to execute the statement part repeatedly for as long asthe expression is true (non-zero). As an example, the following completeprogram calculates the sum 1 + 1/2 + 1/4 + 1/8 ... accurately to sixdecimal places (the result should be close to 2.0):

public class Series {public static void main(String args[]) {

double sum = 0.0, term = 1.0;

while (term > 1e-6){sum += term;term /= 2;

}System.out.println("The sum is " + sum);

}}

2.14 The ’for’ loop

The for loop takes the form:

for ( initial statement ; condition ; update statement ) {statement

}

where:

• initial statement will be obeyed only once before the loop begins.

• condition is tested before each trip through the loop.

• update statement is obeyed after each trip through the loop.

For example, the following program prints the squares of the numbers from1 to 10:

int i;for (i = 1; i <= 10; ++i)

System.out.println(" " + i + " " + i*i);// At this point i will have the value 11

The loop above could be written as a while loop:

Page 41: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.15. THE ’DO WHILE’ LOOP 41

i = 1;while (i <= 10) {

System.out.println(" " + i + " " + i*i);++i;

}

These loops are identical in effect; in particular notice that the variable ihas a defined value, in this case 11, at the end of both loops. In fact a forloop is just a shorthand notation for a while loop. It is good to bear thisin mind because the conditional expression in a for loop, as in a while loop,gives the condition under which the loop should keep running. This is theopposite of the behaviour of for loops in most other languages.

The initial and update statements (more strictly they are expressions)can consist of more than one statement if the constituent statements areseparated by the sequence (comma) operator. The loop below would printa table of powers of two up to the sixteenth.

for ( i = 1, j = 2; i <= 16; i++, j *= 2)System.out.println(" " + i + " " + j;

SAQ. Work through each step of the executing program by hand and producethe output.

Here the initial and update parts each comprise two statements, sepa-rated by commas. In general, these parts can contain any number of state-ments, with commas in between, or even none at all since any of the threeparts can be omitted. Omitted initial or update statements are ignored.Omitted condition parts are treated as being always true. As an example ofthe effect of leaving out all three sections, the endless loop

for ( ; ; )System.out.print("$");

will print more dollars than anyone could need.

2.15 The ’do while’ loop

The post-condition loop takes the form:

do statement while (expression);

statement is executed first and then expression is evaluated; if expressionyields a non-zero (true) value then statement is repeated, and this sequencecontinues until expression yields zero (false). For example, assuming twovariables x and \verbsqrtx— of type double, the program fragment:

Page 42: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

42 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

double x = 144, sqrtx;sqrtx = 1.0;do {

sqrtx = 0.5 * (sqrtx + x/sqrtx);} while (Math.abs((sqrtx * sqrtx - x)) > 1e-6);System.out.println("The square root of " + x + " is " + sqrtx);

will calculate the square root of x accurately to six decimal places by usingNewton’s method. The function Math.abs is a standard function whichcalculates the absolute value of a double value. Of course, the standardfunction Math.sqrt would be a much more practical way of calculatingsquare roots.

2.16 Worked example - golden ratio

To show how we can develop a program to solve a problem we will look atthe Fibonacci series and its relationship to the Divine Proportion (GoldenRatio). Fibonacci’s series is:

1 1 2 3 5 8 13 21 34 55 \ldots

and comes from a study of rabbit populations. It also appears in sea-shells,plants and lots of other places. Now if you take the ratio of successivenumbers in this series you find it gets closer and closer to:

1.61803 39887 49894 84820 45868 34365 63811 77203 09179 80576 \ldots

This is the Golden ratio of the Greeks and can be shown to be equal to (v5+ 1)/2 . We are going to write a program to calculate the ratio of successivenumbers in Fibonacci’s series. To do this we need to:

1. Calculate successive numbers in the FS.

2. Calculate the ratio of succeeding numbers.

3. Stop when we have gone far enough.

We break this into a number of steps required.

1. We need to start off with the numbers 1 (in fib1) and 1 (in fib2).

2. Calculate the sum of fib1 & fib2 and put the result in fib.

3. Move fib2 into fib1.

4. Move fib into fib2.

5. Print fib.

Page 43: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.16. WORKED EXAMPLE - GOLDEN RATIO 43

6. Go back to step 2 if we haven’t finished.

We take each step and turn it into Java.

1. fib1 = fib2 = 1;

2. fib = fib1 + fib2;

3. fib1 = fib2;

4. fib2 = fib;

5. System.out.println(” ” + fib);

6. Put a loop around steps 2 to 5. For now we stop when fib passes1000.

This turns into:

/*** Calculate the Golden Ratio from Fibonacci’s series.*/public class Golden {

public static void main(String args[]) {double fib, fib1, fib2;

fib1 = fib2 = 1;System.out.println(" " + fib1);System.out.println(" " + fib2);

do {fib = fib1 + fib2;fib1 = fib2;fib2 = fib;System.out.println(" " + fib);

} while (fib < 1000);}

}

The result of running this is:

11235813

Page 44: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

44 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

213455891442333776109871597

Now we need to start calculating the ratios. In this case we want to printthe ratio. We can turn our program into:

/*** Calculate the Golden Ratio from Fibonacci’s series.*/

public class Golden {public static void main(String args[]) {

double fib, fib1, fib2;

fib1 = fib2 = 1;System.out.println(" " + fib1);System.out.println(" " + fib2);

do {fib = fib1 + fib2;fib1 = fib2;fib2 = fib;System.out.println(" " + (fib2/fib1));

} while (fib < 1000);}

}

This gives the output:

1121.51.666671.61.6251.615381.61905

Page 45: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

2.17. EXERCISES 45

1.617651.618181.617981.618061.618031.618041.618031.61803

Notice how quickly the value tends to the value we expect. Now this wasn’ta very satisfactory terminating condition; why stop after the Fibonacci num-ber passes 1000? A better way would be to remember the last golden num-ber, compare it with the current one and stop when the value doesn’t changemuch. This gives us:

/*** Calculate the Golden Ratio from Fibonacci’s series.*/public class Golden {

public static void main(String args[]) {double fib, fib1, fib2, golden = 0, lastGolden;

fib1 = fib2 = 1;

do {fib = fib1 + fib2;fib1 = fib2;fib2 = fib;lastGolden = golden;golden = fib2/fib1;System.out.println(" " + golden);

} while (Math.abs(golden - lastGolden) > 1e-8);}

}

This stopped in 21 steps when I tried it. Notice how I set golden to be 0to begin with. This is in order that the statement lastGolden = golden;will work the first time round.

2.17 Exercises

1. Write a program which finds the larger of two numbers.

2. Write a program which finds the largest of three numbers.

Page 46: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

46 CHAPTER 2. ELEMENTS OF JAVA PROGRAMS

3. Write a program which takes the co-ordinates of two points and adistance r. One of the co-ordinate pairs is the centre of a circle ofradius r. Your program should print a message acccording to whetheror not the other point is inside the circle.

4. The numbers on my telephone are arranged as below:

7 8 94 5 61 2 3

0

Write a program that takes the horizontal and the vertical positions ofa button and which outputs the corresponding number. For example,button (1, 3) produces 7.

5. In the land of Fredonia the currency is the zing. The tax system worksas follows: on one month’s salary the first 5,000 zings are tax free, thenext 4,000 are taxed at 10%, the next 5,000 at 20% and anything moreis taxed at 40%. Write a program to take a pretax salary and outputthe post-tax payment.

6. The factorial of a number n is written n! and is the product of all thenumbers from 1 to n. Thus, 5! = 1.2.3.4.5

Write a program to calculate the factorial of a number n.

7. Numbers can be arranged in a rectangular spiral in the manner shownbelow. Write a program to take a co-ordinate pair and to output thenumber in the corresponding cell.

For example, (-3, 2) produces 38. Your program should have no arbi-trary size limits and will not use any loop statements. This questioncan be attempted for extra credit.

Page 47: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 3

Simple input and output

3.1 Introduction

We have used the print and println methods for outputting text from anapplication. So far, however, we have not managed to read text into aprogram. That is the main burden of this chapter.

Java provides ways by which applications and applets can read or writeinformation via keyboards, screens, disc files, networks and graphic inter-faces. All character based input/output is done in terms of characters whichare two bytes representing Unicode characters. Methods for reading andwriting groups of characters (strings) are also available. However, Java im-poses a little work on the part of the programmer to read numbers (say, inthe style 12.34e-5). It is first necessary to read the characters as a string”12.34e-5” and then convert that string to the internal representation of thefloating point number we are after. Fortunately Java provides methods fordoing this. However, be aware, if you have used other languages, that Javaoften requires the programmer to do a bit more typing than most. Thereare no hard concepts, just more boiler plate.

3.2 A simple example of I/O

A very simple application to read text and print what it reads is the follow-ing:

import java.io.*;

/*** Makes a greeting*/

class Greet {public static void main(String[] args) throws IOException {

47

Page 48: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

48 CHAPTER 3. SIMPLE INPUT AND OUTPUT

BufferedReader myReader =new BufferedReader(new InputStreamReader(System.in));

String yourName;

System.out.println("What is your name?");yourName = myReader.readLine();System.out.println("Hello " + yourName);

}}

When I run this I get:

What is your name?DavidHello David

I know it’s not much but not everyone could do it. Note that the middleline is my response to the question after which it prints the final line.

Although it is a short program it raises many complicated points. For-tunately most of it is boiler plate but I shall try to explain it as best Ican.

• The import statement instructs Java that it will need the java.iopackage. The * is a wild card and tells Java to allow all the classesin java.io. Without it you would have to import each class, one byone, in separate import statements.

• The first line of the main method has throws IOException. Thisinforms Java that this method may possibly cause an error. Regardthis as boilerplate for now, we will see the full meaning in a laterchapter.

• The two lines beginning BufferedReader create an input stream; ameans for reading input. There is a lot of boilerplate here; just copyit into your own programs for the time being.

• The next line declares a String variable called yourName.

• The line yourName = myReader.readLine(); is the way of readingan entire line from the console window and storing it in a string. Inapplications it is necessary to read a whole line and then split it intopieces.

• The part "Hello " + yourName is not the arithmetic use of +. When+ is used between strings it is called concatenation. If s1 contains”Paris ” and s2 contains ” in spring” then the expression s1 + s2returns the string ”Paris in spring”.

Page 49: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

3.3. WORKED EXAMPLE - GRADE AVERAGE 49

There are quite a lot of complications here - what you don’t understandtreat as boilerplate for now. We’ll get to detailed explanations later. Totry it I strongly recommend that you copy the project and then modify ityourself.

3.3 Worked example - grade average

The problem is to write a program to read 10 letter grades and produce thecorresponding GPA (Grade Point Average). Letter grades can be A, B, C,D or E which are worth 4, 3, 2 or 1 respectively. Here goes:

import java.io.*;/*** Example of simple I/O to calculate a GPA*/public class GradeAverage {

public static void main(String args[]) throws IOException{BufferedReader myReader =new BufferedReader(new InputStreamReader(System.in));

int counter, grade, total, average;total = 0; counter = 1;while (counter <= 10) {System.out.print("\nEnter letter grade: ");System.out.flush();grade = myReader.read();if (grade == ’A’)total = total + 4;else if (grade == ’B’)total = total + 3;else if (grade == ’C’)total = total + 2;else if (grade == ’D’)total = total + 1;else if (grade == ’F’)total = total + 0;

myReader.skip(1);counter++;}average = total/10;System.out.println("Class average is " + average);}

Page 50: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

50 CHAPTER 3. SIMPLE INPUT AND OUTPUT

}}

When I run this I get:

Enter letter grade: AEnter letter grade: BEnter letter grade: CEnter letter grade: DEnter letter grade: AEnter letter grade: BEnter letter grade: CEnter letter grade: DEnter letter grade: AEnter letter grade: AClass average is 2.0

Note:

• The statement System.out.flush(); is to make sure that the outputhas actually been printed; this is because some system don’t print stuffimmediately but save it until a complete line has been made. This iscalled buffering.

• The read method used in grade = myReader.read(); reads a sin-gle Unicode character. In a case like this it is easier to read singlecharacters than to read a whole line and then break it down.

• The skip method ignores one character from the input stream myReader.Every line ends with a newline character, which is like any other char-acter except that we don’t want to see it. skip ignores the next char-acter.

• The answer is an integer, which is a little odd for an average.

• This version of the program assumes that there are exactly 10 grades.

This program is not a very typical example of style; it doesn’t make good useof the operators in Java, the extended if else stuff is long winded. . . A morerealistic and professional version of the inner part of this program would be:

int counter = 1, grade, total = 0;while (counter <= 10) {System.out.print("\nEnter letter grade: ");System.out.flush();grade = myReader.read();if (grade >= ’A’ && grade <= ’F’)

Page 51: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

3.4. READING NUMBERS 51

total += ’E’ - grade;myReader.skip(1);counter++;}System.out.println("Class average is " + total/10.0);

Note:

• counter and total are initialised at declaration. This is often a goodidea.

• average has disappeared. Its purpose is now rolled into the printlncall.

• The line if (grade >= ’A’ && grade <= ’F’) checks to see if thegrade is valid. Remember that characters are stored in the computeras integers; you don’t need to know what the numbers are but youshould know that ’A’ is one less than ’B’ which is one less than ’C’and so on. That’s why we can replace that horrible if else nonsensewith the single line total += ’E’ - grade;. Suppose that ’A’ is 1 ( itisn’t, but it doesn’t matter) then ’E’ will be 5. So the grade ’B’ willgive 5 - 2 -¿ 3, which is what we want.

• The use of the operator ++ in counter++ is much more natural to aJava programmer. By writing total/10.0 we ensure that we get afloat result because 10.0 is a float.

• The unnecessary variable average has been removed.

3.4 Reading numbers

Java treats all input as strings. If you want to deal with numbers you mustread the characters as a string and then convert the string to the numbertype you want. Special methods are provided for this. As an example, thefollowing program reads two integers and prints their product:

import java.io.*;

/*** Example of reading numbers.*/public class ReadNumber {public static void main(String args[]) throws IOException{

BufferedReader myReader =new BufferedReader(new InputStreamReader(System.in));

Page 52: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

52 CHAPTER 3. SIMPLE INPUT AND OUTPUT

int first, second;String line;

System.out.println("First number");line = myReader.readLine();first = Integer.parseInt(line);System.out.println("Second number");line = myReader.readLine();second = Integer.parseInt(line);System.out.println("Product is: " + (first*second));}}

Note the method parseInt, which belongs to the class Integer, takes aString as an argument and converts to an Integer (if it is a valid number).Notice how line is used to hold the string that is typed.

The output is:

First number27Second number34Product is: 918

3.5 Exercises

1. Write a program that reads ten numbers and prints the largest.

2. Write a program that reads ten numbers and prints the differencebetween the largest and the smallest.

3. Write a program that reads an integer N and then a list of N numbers.It should then print the average of the numbers in the list.

4. Write a program that reads an integer N and then a list of N numbers.It should print a message if the value of numbers in the list is alwaysascending.

5. Write a program that reads two strings (one to each of two lines) andwhich then joins them and prints them as one line with the first stringfirst and then the second string repeated twice. For example, on theinput:

RinTin

Page 53: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

3.5. EXERCISES 53

The output should be Rin Tin Tin.

Further tests could produce DA DOO RON RON or BE BOP A LOOLOO.

These latter two can be produced with the program specified. Makesure to provide spaces where necessary in the output (this does notaffect your program, it’s a question of suitable input).

6. A one armed bandit has three dials that show integers in the range1..9. The payout is as follows:

(a) All wheels the same → 40

(b) Three wheels are consecutive numbers (but not necessarily inorder) → 15

(c) Two wheels the same → 4

Write a program that takes the three numbers and outputs the payout.

Page 54: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

54 CHAPTER 3. SIMPLE INPUT AND OUTPUT

Page 55: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 4

Introduction to methods

4.1 Subprograms

As was mentioned in the introduction it is usual to split large programsinto smaller subprograms. Various terms are used to describe subprograms:procedures in Algol, functions in C and methods in Java. We’ll start with atrivial example.

import java.io.*;

/*** Example of a trivial method.*/public class MethodDemo {

static int multiply(int a, int b) {int dontReallyNeedThis;

dontReallyNeedThis = a*b;return dontReallyNeedThis;}

public static void main(String args[]) throws IOException{BufferedReader myReader =new BufferedReader(new InputStreamReader(System.in));int first, second, result;String line;

System.out.println("First number");line = myReader.readLine();first = Integer.parseInt(line);System.out.println("Second number");

55

Page 56: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

56 CHAPTER 4. INTRODUCTION TO METHODS

line = myReader.readLine();second = Integer.parseInt(line);result = multiply(first, second);System.out.println("Product is: " + result);}}

The dialogue on my computer was:

First number123Second number456Product is: 56088

This is a silly way to multiply two numbers but it’s only for illustration.Note:

• We have introduced a method called multiply. Notice the syntax: itis inside the class MethodDemo and I chose to put it ahead of main,but I don’t have to. All methods must be inside a class.

• It has a similar layout to main.

• In the line static int multiply(int a, int b) the first int says ”thisfunction is going to have an int as an result”. If a method doesn’t givea result then its return type is void.

• After that we give the name of the function; in this case I chose to callit multiply.

• The part between brackets is the list of arguments. Each argument(two here) passes information into the method.

• The first argument is an int which we choose to call a. The second isalso an int called, with characteristic originality, b.

• The argument names are completely private to the inside of multiply.They do not exist outside it and the names used are irrelevant. Wecan use these names elsewhere outside multiply with no worry.

• The body of the method is enclosed between and . This creates aclosed, private region.

• The line int dontReallyNeedThis; creates (declares) a variable calleddontReallyNeedThis.

• This variable only exists inside multiply. When we reach , dontReal-lyNeedThis disappears. Its name is said to be local to multiply.

Page 57: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

4.2. METHODS WITH NO RESULT 57

• The line dontReallyNeedThis = a*b; multiplies a and b and stores theresult in dontReallyNeedThis.

• The last line in the method is return dontReallyNeedThis; the returnsays to the method ”ok, stop now”.

• The expression after return is the result of the method.

• The line result = multiply(first, second); is the call of the method.

• The number of arguments in the call must be the same as in themethod declaration.

• The types of arguments in the call must be the same as in the methoddeclaration.

4.2 Methods with no result

Not all methods return a result; we sometimes want a method that just doesa job. For example, we might, when printing reports, want to produce linesof some character. Suppose we want to produce:

********************

We could, course, write System.out.println("********************");but what if we want different lines, maybe of different characters. What wewant is a statement in the language something like:

printLots(20, ’*’);

Well, there is no printLots statement in the language. You can, however,make one. That’s what methods are for. Here is a suitable one:

static void printLots(int n, char theChar) {for (int i = 1; i <= n; i++)

System.out.print(theChar);System.out.println("");

}

This method (a C programmer would call it a function) can be used exactlyas we showed above. Here is a complete program.

import java.io.*;

/*** Example of function to print characters.*/public class PrintLots {

Page 58: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

58 CHAPTER 4. INTRODUCTION TO METHODS

static void printLots(int n, char theChar) {for (int i = 1; i <= n; i++)System.out.print(theChar);System.out.println("");}

public static void main(String args[]) throws IOException{printLots(20, ’*’);}}

From now on, when I want to give a method or demonstrate a programtechnique, I shall no longer put it in a complete program like the above. Ishall give just the fragment and you can imagine it in a complete program.

4.3 Scope of names

Every name for a variable, class, method etc., has a limited scope. Thatmeans that it is only visible in a certain range of the program code. Takeas an example the following outline of a class:

public class TrivialApplet extends Applet{Label l1, l2;TextField in1, in2;Button theButton;int n, m, hcf;

public static int euclid(int a, int b) {int c;...}

public void init() {l1 = new Label("Number 1?");...}

public boolean action(Event theEvent, Object theObject){n = ...m = ...hcf = ......}

Page 59: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

4.4. EXERCISES 59

public void paint( Graphics g ) {...}}

Notice that the variables n, m and hcf are changed inside action but aredeclared at the outer level of the class. We say that they are global to allthe methods in the class. The same applies to the changing of l1 in init.

The variable c in euclid is different. It is declared inside euclid and onlyexists in that method. We say it is local to euclid. The same applies to aand b.

The region throughout which a name exists is its scope. The scope ofn and m is the whole class, of a, b and c the body of euclid. In effect thescope of a name is the stretch of program between the nearest enclosingcurly brackets where the name is declared.

There can only be one instance of a name in a scope. This means thatinside euclid there can only be one thing called c. However we could perfectlywell declare a different c in paint. Good practice is to declare things aslocally as possible; only make things global if they must be used by severalmethods.

It is also very important to realise that when a method terminates (eitherreaches the } at the end or executes a return) all the variables declared insideit cease to exist. They are actually removed from the computer memory,which is efficient and economical. This is important to understand because avariable declared in a method does not ’remember’ its value from a previouscall. (It can be arranged for that to happen but we will see how later).

4.4 Exercises

1. Early in the notes there is an example of a method for calculatingthe highest common factor of two numbers using Euclid’s algorithm.Write an application that includes that method and which tests it byreading pairs of numbers and printing the HCF.

2. The lowest common multiple (LCM) of two numbers is the smallestnumber that is a multiple of the two numbers. For example the LCMof 9 and 6 is 18. Write an LCM method using the result that:

HCF(m, n) x LCM(m, n) = m x n

Your LCM method will call the HCF method you wrote in 4.1.

3. Write and test a method called block which takes three integer ar-guments rows, cols and indent. The method should print a rectan-gle of asterisks with rows rows, cols columns and indented by indent

Page 60: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

60 CHAPTER 4. INTRODUCTION TO METHODS

character positions from the left hand margin. For example, the callblock( 5, 7, 5) would print:

***********************************

Page 61: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 5

Making Applets

5.1 Applet basics

Java programs can be applications such as we have seen already or applets.An applet is a program that can be run from a server over the Internet andwhich runs in a specially secure environment called the ”sand box”.

To understand the motivation for the special environment, just remem-ber that most Applets are run on the client’s (i.e. your) machine afterbeing downloaded by touching an icon on a web page. If you download aprogram to your machine without knowing who wrote it and having appro-priate guarantees that the program is safe to run then you are taking a verygreat risk. It may be a rogue program that could send information aboutyour files to somewhere, change your files or even delete them. To avoid thisthe Java Virtual Machine (the interpreter for Java) implements a specialenvironment (the sandbox) which does not allow access to memory, discs orother peripherals on the client machine. The applet assumes the existenceof a monitor, keyboard and mouse and nothing else. Therefore if the JavaVirtual Machine is correctly implemented a foreign applet should not beable to do any harm.

There is a certain amount of stuff that you will just have to take on trustfor the moment. Let’s start with a simple applet.

import java.awt.*;import java.applet.Applet;

/*** Trivial applet that displays a string.*/

public class TrivialApplet extends Applet {

public void init() {repaint();

61

Page 62: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

62 CHAPTER 5. MAKING APPLETS

}

public void paint( Graphics g ) {g.drawString( "Hello World!", 30, 30 );

}}

When run, this produces the following:

5.1.1 Note

• The new heading lines:

import java.awt.*;import java.applet.Applet;

• There is no main method.

• The heading of the main class is now public class TrivialApplet extends Applet.The name you choose yourself. It says that you want to make a newclass (TrivialApplet) which inherits from the standard class Applet.

• The Applet class knows how to do various things (draw a little window,for example).

• There are many methods in Applet, two of which are paint and init.In the example we override these two methods. Again you can takethe above as boilerplate.

• The init method is automatically called (run, invoked,. . . ) beforethe applet runs. Here we are just making sure that the window getspainted.

Page 63: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

5.2. BASIC GRAPHICS 63

• We call the standard method drawString giving a string and twonumbers. Everything that goes on the window is drawn. You have toremember your geometry.

• The second argument to drawString is the distance from the left handside of the window where the string is to be drawn.

• The third argument to drawString is the distance from the top of thewindow where the string is to be drawn.

• Co-ordinates are given in pixels. See below for an explanation of pixels.

5.2 Basic graphics

Graphics are drawn in windows. The size of a window can be controlled inthe usual way. The window is organised into pixels in the following way:

0 1 2 3 4 5 6

0

1

2

3

4

5

6

7

5.2.1 Note

• The origin is in the top left corner (very uncartesian).

• Each pixel is defined by a co-ordinate pair.

• Each pixel can be on or off.

• If a pixel is on it may have a color.

Page 64: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

64 CHAPTER 5. MAKING APPLETS

• The actual size of a pixel depends on the screen and computer youare using. Having lots of pixels takes more memory, costs more, takeslonger to draw but give better quality images.

• Large screens (the kind graphics designers use) can be several thousandpixels in each direction and each pixel can be millions of colours.

• More modest screens may be something like 800x600 pixels.

• The number of colours that a pixel can have is very dependent on thehardware and software. Minimum is 2 (black/white), other numbersbeing 8, 256, 64000 and 16000000.

When you are drawing in a window everything must be drawn. You mustplace each element exactly. There is no concept of a line of print as we hadwhen we were using println in the application console. For example, to get:

you can use:

public void paint( Graphics g ) {g.drawString( "Java", 60, 30 );g.drawString( "Programmers", 40, 45 );g.drawString( "Rule", 60, 60 );g.drawString( "OK", 65, 75 );

}

It’s up to you to get the co-ordinates right.

5.3 Getting input to an applet

Now we get to something more realistic. Real applets get input from littleboxes called text fields. Using this is going to get us into some real concepts

Page 65: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

5.3. GETTING INPUT TO AN APPLET 65

of object oriented programming. It is not trivial but it is fundamental towriting real Java applets. I’m going to present an applet that requests anumber and then calculates its factorial. First the whole thing:

package pij.makingapplets;

import java.awt.*;import java.applet.Applet;

/*** Demonstrates placing a label and a text field.*/public class DemoTextFieldApplet extends Applet {

Label prompt;

TextField forInput;

int n, fact;

public static int factorial(int a) {// compute factorial of aint result = 1;

while (a > 0)result *= a--;

return result;} // factorial

public void init() {prompt = new Label("enter a number");forInput = new TextField(10);add(prompt);add(forInput);

} // init

public boolean action(Event theEvent, Object theObject) {String valueAsString = theObject.toString();

forInput.setText("");n = Integer.parseInt(valueAsString);fact = factorial(n);repaint();return true;

} // action

Page 66: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

66 CHAPTER 5. MAKING APPLETS

public void paint(Graphics g) {g.drawString("The factorial of " + n + " is " + fact,

10, 40);} // paint

} // DemoTextField

When you run it you will see something like this:

If you type a number in the box it prints its factorial. It keeps on requestingnumbers until you quit the applet. The first thing to understand is that allapplets have a set of methods which are called automatically. Some of themare paint, init and action. It is important to understand when these arecalled.

• init is called when an applet starts to run. You must provide yourown version of init exactly as shown in the example. Any code youput there can set variables, put things on the applet window or whatyou wish.

• paint is used to display information on the applet. It is sometimesnecessary to force paint to be called. This can be done by callingrepaint. It is not normal for a programmer to call paint directly;repaint is provided for this purpose.

• action is called when something happens caused by the user (pressingthe enter key for example). It is the basis of GUI programming, astyle of programming called event driven programming. In a moresophisticated applet action would need to know what kind of eventhad occurred (mouse click, key press etc.) but for now we will beusing the enter key only, so we don’t need to worry. Note that actionreturns a boolean value. For now we must make it return true.

We’ll now go through parts of this program line by line. Start with thedeclarations at the start:

Label prompt;TextField forInput;int n, fact;

Page 67: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

5.3. GETTING INPUT TO AN APPLET 67

These are variables used throughout the class. The type Label is a standardJava class. Label prompt creates a variable called prompt. It is importantto realise that this doesn’t make the label - that happens a bit later.

A TextField is a little input box. Again this statement doesn’t make thebox, it creates a variable that will later be given a box to hold. You may aswell start getting used to object oriented terminology at this stage: Labeland TextField are classes and forInput and prompt are references to objects.

The init method is:

public void init() {prompt = new Label("enter a number");forInput = new TextField(10);add(prompt);add(forInput);

} // init

The line prompt = new Label(”enter a number”); creates a Label object.When the label is actually placed on the applet window it will carry thetext given in the argument. The special operator new is used to create allobjects. The approach you use is: declare a reference to an object with astatement such as Label prompt, then create the object by calling new.

The line forInput = new TextField(10); creates a text field object andmakes forInput refer to it. The argument 10 is the size (in characters) ofthe TextField. These two lines have created the label and the field in thememory of the computer but they are not yet shown on the applet window.That’s the job of the next two lines:

add(prompt);add(forInput);

These actually draw the objects on the applet window although the windowis not yet visible.

The action method is:

public boolean action(Event theEvent, Object theObject){String valueAsString = theObject.toString();

forInput.setText("");n = Integer.parseInt(valueAsString);fact = factorial(n);repaint();return true;

} // action

For the time being just copy the first line of the action method. The Eventargument can be used to find out what the user actually did; up to now

Page 68: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

68 CHAPTER 5. MAKING APPLETS

it’s just pressing the enter key so we won’t use theEvent in this example.theObject carries more information from the event. In this case it will bethe text in the text field at the time that enter was pressed.

The next line turns that object into a String by using the toStringmethod of theObject. All objects have a toString method. Again Stringis a class, objects of which can hold strings of any length. The object in thiscase is valueAsString.

The line forInput.setText(””); calls the setText method for the TextFieldwe created earlier. It puts an empty string in the little box (i.e. makes itempty).

Remember that all input and output to an applet window is in the formof text. If you want to convert text to an integer you can use the parseIntmethod from the class Integer. This is what is happening in the line thatcomes next: n = Integer.parseInt(valueAsString); It’s similar to what we sawin the earlier examples where we were reading numbers in an application.

Now we want to do a calculation so we do fact = factorial(n);. This isfairly obvious; factorial is a method that I have written earlier in the classdefinition and the result goes into the variable fact.

Now we use repaint to cause the applet window to be redrawn. This willcause the paint method defined earlier to be called.

It is now time to leave action and as we must return a boolean valuewe decide to return true. Later you will see when you might want to dosomething different.

All the methods we have looked at up to here belong to all applet classes.There is one method that is peculiar to this particular case, the factorialmethod. This is our own and reads:

public static int factorial(int a){// Compute factorial of aint result = 1;

while (a > 0)result *= a--;

return result;} // factorial

See if you can work out for yourself how this works.

5.4 Buttons

Another feature of GUIs is buttons, those little regions that you can clickon. Clicking a button counts as an event. The following program calculatesthe highest common factor of two numbers using Euclid’s algorithm fromchapter 1.

Page 69: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

5.4. BUTTONS 69

package pij.makingapplets;

import java.awt.*;import java.applet.Applet;

/*** Applet to demonstrate buttons.*/public class ButtonDemoApplet extends Applet {

Label l1, l2;

TextField in1, in2;

Button theButton;

int n, m, hcf;

public static int euclid(int a, int b) {int c;do {

c = a % b;if (c != 0) {

a = b;b = c;

}} while (c != 0);return b;

} // euclid

public void init() {l1 = new Label("Number 1?");l2 = new Label("Number 2");in1 = new TextField(10);in2 = new TextField(10);theButton = new Button("Calculate");add(l1);add(in1);add(l2);add(in2);add(theButton);

} // init

public boolean action(Event theEvent, Object theObject) {n = Integer.parseInt(in1.getText());

Page 70: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

70 CHAPTER 5. MAKING APPLETS

m = Integer.parseInt(in2.getText());hcf = euclid(n, m);repaint();return true;

} // action

public void paint(Graphics g) {g.drawString("The HCF of " + n + " and " + m + " is "

+ hcf, 30, 100);} // paint

} // ButtonDemoApplet

The running applet looks like this:

Note

• You should, by now, be able to follow Euclid’s algorithm from the firstchapter.

• Notice how the button is created and put on the window.

• It’s very important to remember to repaint; if not the window doesn’tupdate. (Guess how I came to mention this)?

• There is only one event likely to happen, button push, so action as-sumes that’s what has happened.

• The methods pass information between themselves by using variablesdeclared at the outer level of the class. Such variables are global to allmethods in the class and so all the methods in the class can use them.

Page 71: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

5.5. EXERCISES 71

5.5 Exercises

1. Modify the applet in the notes so that it has two buttons marked HCFand LCM. It should calculate the appropriate result when either of thebuttons is pressed.

2. Write an applet with three textfields marked Principal, Rate and Pe-riod. These represent an amount of money deposited, the percentageannual rate of interest and the number of years for which the sum isdeposited. On pressing a button your applet should display the finalamount of money.

Page 72: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

72 CHAPTER 5. MAKING APPLETS

Page 73: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 6

Introduction to Arrays

6.1 Array basics

Arrays are one of the simplest data structures. An array is simply a col-lection of items of the same type. Each element is referred to by an indexor subscript. In mathematics we do this with the notation aj. This is notall that handy in computer languages because we tend to be restricted towriting everything on one line. Most (but not all) languages get round thisby using square brackets in the style a[j]. Java does it this way.

6.2 Worked example - standard deviation

The following program reads a set of n numbers and calculates the average

x̄ =1n

n−1∑i=0

xi

and the standard deviation

sn =

√√√√ 1n

n−1∑i=0

(xi − x̄)2

It could be a grade analysis program. The program is:

import java.awt.*;import java.applet.Applet;

/*** Applet to demonstrate arrays.*/public class ArrayDemoApplet extends Applet {

Label prompt;

73

Page 74: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

74 CHAPTER 6. INTRODUCTION TO ARRAYS

TextField forInput;

int i = 0;

final int n = 10;

int theData[];

double average = 0.0, stdDev;

public void calculate() {double sumDev = 0.0, dev;int j;for (j = 0; j < n; j++) { // get the total

average += theData[j];} // foraverage /= n; // calculate average

for (j = 0; j < n; j++) {// squares of deviationsdev = theData[j] - average;sumDev += dev * dev;

} // forstdDev = Math.sqrt(sumDev / n);

} // calculate

public void init() {theData = new int[n]; // make the arrayprompt = new Label("Give a number");forInput = new TextField(10);add(prompt);add(forInput);

} // init

public boolean action(Event theEvent, Object theObject) {String valueAsString = theObject.toString();int x;

x = Integer.parseInt(valueAsString);theData[i++] = x;if (i == n)

calculate();forInput.setText(""); // empty the text boxrepaint();

Page 75: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

6.2. WORKED EXAMPLE - STANDARD DEVIATION 75

return true;} // action

public void paint(Graphics g) {if (i < n)

g.drawString(" " + i + " of " + n, 10, 40);else {

g.drawString("Average is " + average, 10, 55);g.drawString("Deviation is " + stdDev, 10, 70);

} // if} // paint

} // ArrayDemoApplet

This produces something like:

6.2.1 Note

• The line final int n = 10; creates what is known as a constant vari-able. This is a totally ludicrous name; in fact it’s oxymoronic. Otherlanguages just call these things constants. The effect is that n is giventhe value 10 and it cannot be changed.

• int theData[]; creates a reference to an array of integers called the-Data. It does not make the array though, that is done in the line thatreads:

• theData = new int[n]; This generates an array of n integers.

• theData[i++] = x; is the statement that puts a value into an ele-ment of the array and sets the index for the next element. This use ofan extra variable x is not normal style. I’m just doing it to make thestatements easier to follow but if you feel patronised it’s because youare being. A real programmer would write all this as one statement:theData[i++] = Integer.parseInt(valueAsString); Try to under-stand this; it’s an important style to grasp.

• Work through the method calculate and make sure you understand it.

Page 76: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

76 CHAPTER 6. INTRODUCTION TO ARRAYS

• Notice how scope is being used to make certain variables visible through-out the class whereas others, such as sumDev, are local to particularmethods.

If you need to know the size of an array use length. For example, in theprogram above the length of theData can be found by referring to the-Data.length. It is an error to use an index outside the bounds of the array.So if the bounds of an array are 0..9 then any index to the array must be inthe range 0..9; if it is not then ArrayOutOfBoundsException will be thrownand you will get an appropriate error message.

Later on we will look at how to sort and search arrays. The algorithmsfor this are very important but let’s do something more amusing first.

6.3 Initialising Arrays

Sometimes we need an array to hold particular values; for example, we maywant an array that holds the numbers of days in each month (thirty dayshath September etc.). This can be done with a special construction:

int daysIn[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

This is especially useful for making tables of special values. If an array isnot initialised it will be filled with zeros if it is a numeric array, false if it isan array of booleans or null if it is an array of references (don’t worry, youaren’t expected to understand that last bit).

6.4 Exercises

1. Write an applet which takes a number representing a month and whichoutputs the number of days in the month. Assume February has 28days.

2. Adapt 6.1 so that it correctly takes care of leap years. The rule isthat if the number of the year is divisible by 4 it is a leap year unlessit is divisible by 100, in which case it is not leap. This rule is itselfmodified if the year is divisible by 400 in which case it is leap.

3. Write an applet to read a list of 10 numbers and to print the largestand smallest in the list.

4. Write an applet to read a number n and then n numbers. It shouldthen print the average of the numbers. An average is a floating pointvalue.

Page 77: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 7

Simple graphics

7.1 Introduction

This book is not about computer graphics so we can’t go too far in to thesubject, but it isn’t hard to learn enough to make interesting applets. Wehave already gone over the co-ordinate system used in Java but to review itbefore going on may be helpful.

7.2 Graphics objects

There is a class Graphics with methods for drawing, selecting fonts andcolours etc. You have already used the class when you wrote your own paintmethods. The argument to paint is a Graphics and notice how, to draw astring, we wrote g.DrawString(...).

The Graphics class is the same on all implementations of Java. Thisis important because graphics aspects of programming are not normallyportable across different types of computers. Macintoshes use the MacintoshQuickdraw toolkit, Windows any of a number of different libraries (althoughthe Microsoft Foundation Classes, MFC, is now pretty widely accepted)and Unix offers even more. The Graphics class in Java is implemented oneach platform using the appropriate underlying routines, but by providingGraphics as an abstract layer above the operating system you can writeprograms which will work on any computer.

7.3 Drawing lines

Graphics provides a method drawLine for drawing lines. It is called withfour arguments defined as follows:

/*** Applet to demonstrate drawing lines.

77

Page 78: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

78 CHAPTER 7. SIMPLE GRAPHICS

*/public class LinesDemoApplet extends Applet {

public void paint(Graphics g) {int offset = 10;int startX = 10;int startY = 10;int endX = 250;int endY = 250;int noLines = 25;

for (int i = 1; i <= noLines; i++) {g.drawLine(startX, startY, endX, endY);startX += offset;endX -= offset;

}}

}

produces the output:

7.4 Drawing shapes

The following methods belong to Graphics and draw various other shapes.I don’t explain them at length because they are pretty obvious.

drawRect(x, y, width, height) // (x, y ) is top left cornerfillRect(x, y, width, height) // solid rectangleclearRect(x, y, width, height) // draws in background colordrawRoundRect(x, y, width, height, arcWidth, arcHeight)fillRoundRect(x, y, width, height, arcWidth, arcHeight)draw3DRect(x, y, width, height, Boolean raised)

Page 79: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

7.4. DRAWING SHAPES 79

fill3DRect(x, y, width, height, Boolean raised)drawOval(x, y, width, height) // (x, y) is t.l.c. of bounding rectanglefillOval(x, y, width, height)drawArc(x, y, width, height, startAngle, arcAngle) // degrees from eastfillArc(x, y, width, height, startAngle, arcAngle) // anticlockwise +vedrawPolygon(xPoints, yPoints, numPoints) // xPoints & yPoints are arraysfillPolygon(xPoints, yPoints, numPoints)

These are illustrated in the following program, which claims nothing forartistry but, hopefully, explains the use of the above methods.

package pij.simplegraphics;

import java.applet.Applet;import java.awt.Color;import java.awt.Graphics;

/*** Applet to demonstrate drawing shapes*/public class ShapesDemoApplet extends Applet {

final int xShift = 90, yShift = 60, width = 80, height = 55;

int currX, currY;

public void paint(Graphics g) {currX = 10;currY = 10;

// Two styles of rectangleg.drawRect(currX, currY, width, height);currX += xShift;g.fillRect(currX, currY, width, height);currX += xShift;

// Clear part of a rectangleg.fillRect(currX, currY, width, height);g.clearRect(currX + 10, currY + 10, width, width);currX += xShift;

// Round rectanglesg.drawRoundRect(currX, currY, width, height, 20, 20);currX += xShift;g.fillRoundRect(currX, currY, width, height, 20, 20);currX += xShift;

Page 80: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

80 CHAPTER 7. SIMPLE GRAPHICS

currX = 10;currY += yShift;g.setColor(Color.yellow);

// 3D rectanglesg.draw3DRect(currX, currY, width, height, true);currX += xShift;g.draw3DRect(currX, currY, width, height, false);currX += xShift;g.fill3DRect(currX, currY, width, height, true);currX += xShift;g.fill3DRect(currX, currY, width, height, false);currX += xShift;

currX = 10;currY += yShift;g.setColor(Color.black);

// Ovalsg.drawOval(currX, currY, width, height);currX += xShift;g.fillOval(currX, currY, width, height);currX += xShift;

// Arcsg.drawArc(currX, currY, width, height, 20, 230);currX += xShift;g.fillArc(currX, currY, width, height, 20, 230);currX += xShift;

currX = 10;currY += 2 * yShift;

// Polygons - a little houseint xValues[] = { currX, currX + width,

currX + 2 * width, currX + 2 * width, currX,currX };

int yValues[] = { currY, currY - width / 2, currY,currY + height, currY + height, currY };

g.drawPolygon(xValues, yValues, xValues.length);currX += xShift;

Page 81: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

7.5. DRAWING STRINGS 81

for (int i = 0; i < xValues.length; i++)// Shift the x values alongxValues[i] += 3 * width;

g.fillPolygon(xValues, yValues, xValues.length);}

}

This produces the following master(s) piece:

There is a lot more to graphics and applets can be made more interestingfor the user by using animation. It is not part of this book to cover thesefun things because if we do we won’t have time for the boring things thatare regarded as Very Important in computer science.

7.5 Drawing strings

You have already been using drawString to print dull looking text. Nowa-days people expect to see fancy fonts, color and different styles. Basic to thisis the class Font, objects of which can be passed to the Graphics method set-Font. The usual approach is to declare a Font object as an instance variablein one’s applet class. To see how this is done look at the following program:

package pij.simplegraphics;

import java.applet.Applet;import java.awt.Font;

Page 82: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

82 CHAPTER 7. SIMPLE GRAPHICS

import java.awt.Graphics;

/*** Applet to demonstrate drawing strings.*/

public class DrawingStringsApplet extends Applet {private Font f1, f2, f3;

public void init() {f1 = new Font("TimesRoman", Font.BOLD, 18);f2 = new Font("Courier", Font.ITALIC, 18);f3 = new Font("Helvetica", Font.PLAIN, 18);

}

public void paint(Graphics g) {g.setFont(f1);g.drawString("Do you want", 60, 20);g.setFont(f2);g.drawString("to", 95, 40);g.setFont(f3);g.drawString("Java, cherie?", 55, 60);

}}

PLAIN, BOLD and ITALIC are integer constants and so can be addedtogether. So, for example, you could use:

myFont = new Font("TimesRoman", Font.ITALIC+Font.BOLD, 26);

This would produce bold, italic text.The thing that looks like a method call is called a constructor. A con-

structor is a method that is used to construct an object of a class. It hasthe same name as the class e.g the class Font has a constructor Font(...).There can be several constructors for a class but they all have the samename, the class name. They are distinguished by the argument lists. Lateryou will see how to write your own constructors.

Page 83: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

7.6. COLOR 83

7.6 Color

Color is controlled by the Graphics method setColor which you saw in theexample in section 8.4. Note that the people at Sun don’t know how tospell ’colour’. There is also a class Color which is used for the arguments ofsetColor. The following constants are predefined values of class Color:

black blue cyan darkGraygray green lightGray magentaorange pink red white yellow

Note that Sun also can’t spell ’grey’.Colours are made up from different amounts of the primary colours red,

green and blue (referred to as RGB). You can make your own colours bymixing different amounts of these three. The colours above are premixedbut are by no means the limit (provided your monitor is up to it). There aretwo Color constructors for making tints. Each takes three arguments butone takes floats in the range 0.0 → 1.0 and the other integers in the range0 → 255. Examples:

g.setColor(new Color(100, 50, 150); // int constructorg.setColor(new Color(0.5, 0.0, 0.75); // float constructor

The following program demonstrates how these can be used:

package pij.simplegraphics;

import java.applet.Applet;import java.awt.Color;import java.awt.Graphics;

public class ColoursDemoApplet extends Applet {

final int xShift = 90, yShift = 60, width = 80, height = 55;

int currX, currY;

float rr, gg, bb;

public void paint(Graphics g) {currX = 10;currY = 10;

// Use the preset coloursg.setColor(Color.yellow);g.fillRoundRect(currX, currY, width, height, 20, 20);

Page 84: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

84 CHAPTER 7. SIMPLE GRAPHICS

currX += xShift;g.setColor(Color.cyan);g.fillRoundRect(currX, currY, width, height, 20, 20);currX += xShift;g.setColor(Color.magenta);g.fillRoundRect(currX, currY, width, height, 20, 20);currX += xShift;g.setColor(Color.blue);g.fillRoundRect(currX, currY, width, height, 20, 20);currX += xShift;g.setColor(Color.red);g.fillRoundRect(currX, currY, width, height, 20, 20);

currX += xShift;currX = 10;currY += yShift;

// Use the integer constructor - shades of redfor (int r = 0; r <= 255; r++) {

g.setColor(new Color(r, 0, 0));g.drawLine(currX, currY, currX, currY + height);currX++;

} // for

currX = 10;currY += yShift;

// Use the integer constructor. Shades of red and blue.for (int r = 0, b = 255; r <= 255; r++, b--) {

g.setColor(new Color(r, 0, b));g.drawLine(currX, currY, currX, currY + height);currX++;

} // forcurrX = 10;currY += yShift;

// Use the integer constructor. Red and blue with a bit of green.for (int r = 0, b = 255; r <= 255; r++, b--) {

g.setColor(new Color(r, 127, b));g.drawLine(currX, currY, currX, currY + height);currX++;

} // for

currY += yShift;

Page 85: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

7.7. EXERCISES 85

// Use the float constructorfor (bb = (float) 0.0; bb <= (float) 1.0; bb += (float) 0.05) {

rr = (float) 0.0;gg = (float) 1.0;for (currX = 10; currX < 450; currX++) {

g.setColor(new Color(rr, gg, bb));g.drawLine(currX, currY, currX, currY + 5);rr += 0.002;gg -= 0.002;

} // forcurrY += 5;

}}

}

This produces rather nice colours:

7.7 Exercises

1. Write a program to draw a set of nested boxes.

2. Write a program to draw a house with the name ”Dunhacking” overthe door and dark windows.

Page 86: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

86 CHAPTER 7. SIMPLE GRAPHICS

Page 87: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 8

Mousing around

8.1 Introduction

Java assumes that all computers have a mouse and provides a standard wayof using one. Mice come with one, two or three buttons, so in order tobe portable Java assumes one button. The Applet class has methods forhandling mice which you can override if you need to. They are automaticallycalled when the mouse does something interesting such as move, click, enterthe applet space and so on.

8.2 Basic mousing

The class Applet has the following methods for dealing with mouse events:

mouseDownmouseUpmouseMovemouseExitmouseEntermouseDrag

By overriding these you can perform your own actions in response to themouse.

Here is a simple demo program:

public class MouseDemoApplet extends Applet {private boolean mouseInApplet, complain;

private Font bigLetters = new Font("TimesRoman", Font.BOLD,40);

public void init() {

87

Page 88: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

88 CHAPTER 8. MOUSING AROUND

mouseInApplet = false;complain = false;resize(300, 300);

}

public void paint(Graphics g) {String message;g.setFont(bigLetters);if (mouseInApplet && complain) {

showStatus("At 2 complain is " + complain);message = "Ouch!";

} else if (mouseInApplet) {message = "Eek - a mouse!";

} else {message = "Whew!";

}g.drawString(message, 20, 150);

}

public boolean mouseMove(Event e, int x, int y) {showStatus("The mouse is at (" + x + ", " + y + ")");repaint();return true;

}

public boolean mouseEnter(Event e, int x, int y) {mouseInApplet = true;repaint();return true;

}

public boolean mouseExit(Event e, int x, int y) {mouseInApplet = false;repaint();return true;

}

public boolean mouseDown(Event e, int x, int y) {complain = true;// showStatus("At 1 complain is " + complain);repaint();complain = false;return true;

}

Page 89: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

8.2. BASIC MOUSING 89

}

Example output (with mouse over and without):

Statements that are important here:

mouseInApplet = false;complain = false;resize(300, 300);

resize resets the size of the applet. The boolean variables are used to ’tell’other parts of the class what the most recent mouse event was. Here theyboth get initialised to false. They change whenever an event occurs. Forexample:

public boolean mouseExit(Event e, int x, int y) {mouseInApplet = false;repaint();return true;

}

mouseExit is called whenever the mouse leaves the applet. So on exit thismethod will set the boolean to false and then repaints the applet. Remem-ber that repaint will call the paint method. It is paint that does most ofthe work:

public void paint(Graphics g) {String message;g.setFont(bigLetters);if (mouseInApplet && complain) {

showStatus("At 2 complain is " + complain);message = "Ouch!";

} else if (mouseInApplet) {message = "Eek - a mouse!";

Page 90: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

90 CHAPTER 8. MOUSING AROUND

} else {message = "Whew!";

}g.drawString(message, 20, 150);

}

Notice that this decides what to do on the basis of the state informationpassed via mouseInApplet and complain. By using this technique you canmake paint present different windows depending on what has happened.

There is an applet method used called showStatus that we have not usedbefore:

public boolean mouseMove(Event e, int x, int y) {showStatus("The mouse is at (" + x + ", " + y + ")");repaint();return true;

}

The status line is at the bottom of the applet window. It’s the place whereyou have seen the message “Applet started” up to now. showStatus printsits argument on the status line. We use it here to show the position ofthe mouse. When the running applet calls mouseMove it passes the mouseposition through x and y. Try this applet and you will see these co-ordinateschange as you move the mouse.

public boolean mouseDown(Event e, int x, int y) {complain = true;// showStatus("At 1 complain is " + complain);repaint();complain = false;return true;

}

Notice how complain is used to pass information to paint. (SAQ: How doesit get to paint?)

8.3 Exercises

1. Modify the program from section 8.2 so that the windows light upwhen the mouse clicks on the door.

Page 91: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 9

Putting it all together

9.1 Introduction

You now know enough to build quite sophisticated applets. You can draw,write, change print styles and control the mouse. It’s time to go througha few principles of style so that you can control the complexity of yourprograms. Style is a mega subject; it involves everything from layout tothe psychology of problem solving. Each of the sections in this chapter isheaded with an exhortation.

9.2 Know your mathematics

To be a good programmer you do not have to be a mathematical genius butthere are things you must know. Can you answer the following questions?If not, pull out your maths notes and revise. There is nothing here beyondhigh school maths.

• Given two points (x1, y1) and (x2, y2), how far apart are they?

• Given two points (x1, y1) and (x2, y2), give the equation of a straightline through the points.

• How can you tell whether that line slopes down or up?

• Given a line and a point, how do you work out how far the point isfrom the line?

• Given two circles, one centred at (x1, y1) of radius r1, one centred at(x2, y2) of radius r2, how do you tell if they overlap?

• You have a point (x, y) and want to draw a line of length l at an angleof radians to the horizontal (anti-clockwise is positive). Where is theend point of the line?

91

Page 92: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

92 CHAPTER 9. PUTTING IT ALL TOGETHER

• You want to draw using a standard Cartesian co-ordinate system (yis positive upwards) where x and y go from -1.0 to +1.0. On a Javaapplet you want the Cartesian origin to be at the pixel (jox, joy) andthe length of each axis to be jl pixels long (in each direction from theorigin). Work out a formula for converting a Cartesian x value to aJava x value. Do the same for y.

• You have n squares that you want to paint on the screen. You want toarrange them as compactly as possible so you want to put them in assquare a pattern as possible. How many rows and columns are there?How many squares are there on the unfinished row?

• You have the equation of two straight lines. How can you tell if theyare parallel? If they are not parallel where do they cross?

• You have a chess board where the ranks and files are numbered 1 to 8.Starting at the first square (rank1, file 1) you write the numbers 1 to64 going along the first rank, then the second and so on. The squarenumbered 64 is at (8, 8). What formula will give you the number on asquare at (r, f)? Given a number n, what formulae give you the rankand the file of the corresponding square?

9.3 If you repeat yourself you need to restructure

If you find you write the same (or similar) code several times then you needto think. There may be a simple, unifying principle such as a formula tobe found. Alternatively you may want to define a method to encapsulatesome repeated action. When you do this make your methods as general aspossible.

Suppose you want to draw lots of bunnies on an applet. To start off yourealise you can make a nice bunny by using ovals. Let’s try that:

package pij.puttingitalltogether;

import java.awt.*;import java.applet.Applet;

/*** A simple Java applet to draw a bunny.*/

public class BunnyDemoApplet extends Applet {

public void paint(Graphics g) {int currX, currY;resize(300, 300);

Page 93: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

9.3. IF YOU REPEAT YOURSELF YOU NEED TO RESTRUCTURE93

currX = 100;currY = 50;

g.setColor(Color.white); // tailg.fillOval(currX + 70, currY + 173, 30, 30);g.setColor(Color.black);g.drawOval(currX + 70, currY + 173, 30, 30);g.setColor(Color.gray);g.fillOval(currX, currY + 60, 100, 150); // bodyg.fillOval(currX + 20, currY + 10, 60, 60); // headg.setColor(Color.black);g.drawOval(currX + 20, currY + 10, 60, 60);g.setColor(Color.gray);g.fillOval(currX + 35, currY - 30, 10, 50); // earsg.fillOval(currX + 55, currY - 30, 10, 50);g.setColor(Color.black);g.fillOval(currX + 38, currY + 30, 5, 5); // eyesg.fillOval(currX + 58, currY + 30, 5, 5);g.fillOval(currX + 40, currY + 50, 20, 3); // mouthg.setColor(Color.gray);g.fillOval(currX - 25, currY + 200, 70, 10); // back feetg.fillOval(currX + 45, currY + 200, 70, 10);g.setColor(Color.black);g.drawOval(currX - 25, currY + 200, 70, 10);g.drawOval(currX + 45, currY + 200, 70, 10);g.setColor(Color.gray);g.fillOval(currX + 25, currY + 105, 20, 100); // front feetg.fillOval(currX + 60, currY + 105, 20, 100);g.setColor(Color.black);g.drawOval(currX + 25, currY + 105, 20, 100);g.drawOval(currX + 60, currY + 105, 20, 100);

}

}

and this gives us:

Page 94: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

94 CHAPTER 9. PUTTING IT ALL TOGETHER

Now it’s a bunny, but the program stinks. It’s full of magic numbers and isuseless if we need to draw a lot of rabbits of different sizes. It would nice tohave a drawBunny method that works like the other Java methods. They allhave the co-ordinates of the top left hand corner, the width and the height,so that seems a good place to start.

Here is a more useful bunny method:

public void drawBunny(Graphics g, int x, int y, int width,int height) {

int midX = x + width / 2;int midY = y + height / 2;int tailX = x + (int) (0.75 * width);int tailY = y + (int) (0.85 * height);int tailSize = width / 5;int bodyHeight = (int) (0.666 * height);int bodyY = y + height - bodyHeight;int headWidth = (int) (height / 5);int headX = midX - headWidth / 2;int headY = y + bodyY - headWidth;int earY = y;int earWidth = headWidth / 5;int earHeight = (int) (1.2 * (headY - y));int leftEarX = headX + (int) (headWidth / 4) - earWidth / 2;int rightEarX = headX + (int) (0.75 * headWidth) - earWidth / 2;int eyeSize = earWidth;int eyeY = headY + headWidth / 3;int leftEyeX = leftEarX;int rightEyeX = rightEarX;int mouthX = midX - headWidth / 4;int mouthY = headY + (int) (0.75 * headWidth);

Page 95: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

9.3. IF YOU REPEAT YOURSELF YOU NEED TO RESTRUCTURE95

int mouthWidth = 2 * (midX - mouthX);int mouthHeight = eyeSize / 2;int bFootWidth = width / 3;int bFootHeight = 2 * earWidth;int bLeftFootX = midX - bFootWidth;int bRightFootX = midX;int bFootY = height - bFootHeight;int fFootY = midY;int fFootWidth = bFootHeight;int fFootHeight = (int) (0.45 * height);int lfFootX = midX - width / 5 - fFootWidth / 2;int rfFootX = midX + width / 5 - fFootWidth / 2;

g.setColor(Color.white); // tailg.fillOval(tailX, tailY, tailSize, tailSize);g.setColor(Color.black);g.drawOval(tailX, tailY, tailSize, tailSize);g.setColor(Color.gray);g.fillOval(x, bodyY, width, bodyHeight); // bodyg.setColor(Color.black);g.drawOval(x, bodyY, width, bodyHeight);g.setColor(Color.gray);g.fillOval(leftEarX, earY, earWidth, earHeight); // earsg.fillOval(rightEarX, earY, earWidth, earHeight);g.fillOval(headX, headY, headWidth, headWidth); // headg.setColor(Color.black);g.drawOval(headX, headY, headWidth, headWidth);g.setColor(Color.black);g.fillOval(leftEyeX, eyeY, eyeSize, eyeSize); // eyesg.fillOval(rightEyeX, eyeY, eyeSize, eyeSize);g.fillOval(mouthX, mouthY, mouthWidth, mouthHeight);// mouthg.setColor(Color.gray);g.fillOval(bLeftFootX, bFootY, bFootWidth, bFootHeight); // back feetg.fillOval(bRightFootX, bFootY, bFootWidth, bFootHeight);g.setColor(Color.black);g.drawOval(bLeftFootX, bFootY, bFootWidth, bFootHeight);g.drawOval(bRightFootX, bFootY, bFootWidth, bFootHeight);g.setColor(Color.gray);g.fillOval(lfFootX, fFootY, fFootWidth, fFootHeight);// front feetg.fillOval(rfFootX, fFootY, fFootWidth, fFootHeight);g.setColor(Color.black);g.drawOval(lfFootX, fFootY, fFootWidth, fFootHeight);g.drawOval(rfFootX, fFootY, fFootWidth, fFootHeight);

}

Page 96: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

96 CHAPTER 9. PUTTING IT ALL TOGETHER

Whew - that was a lot; it took me hours. First look at the drawBunnymethod above. It has the signature:

public void drawBunny(Graphics g, int x, int y, int width,int height) {

...}

This tells drawBunny to draw on Graphics g with a top left-hand corner(TLHC) and width and height working in the usual way. With the call:

drawBunny(g, 10, 10, 120, 200);

this produces:

The power of using methods is illustrated by this program fragment:

public void paint(Graphics g) {int startX = 250, currX, currY = 10, width, height;resize(500, 200);showStatus(" Terracotta Bunny Army");for (int j = 1; j <= 7; j++) {

width = 17;height = 35;currX = startX;

Page 97: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

9.4. SOLVE PROBLEMS AWAY FROM THE COMPUTER 97

for (int i = 1; i <= 10; i++) {drawBunny(g, currX, currY, width, height);currX += width / 2;width = (int) (1.2 * width);height = (int) (1.2 * height);

}startX -= 50;

}}

which draws a Terracotta Bunny Army:

Several points are worth mentioning here:

• It took me ages to get the co-ordinates right. You don’t want to do thisby hand very often. The way it is usually done is to make a drawingor painting with a graphics tool (or scan a paper copy), save it as afile, then use the Java methods for displaying graphics files. This iseasy to do but I won’t cover it here.

• The method drawBunny could be split into smaller methods such asdrawHead drawEar and so on. This is a perfectly reasonable thing todo.

• In deciding on the co-ordinates to use I did all the working as if thewindow was scaled from 0.0 to 1.0 in each direction. Then by multi-plying by the actual width and height I get the integer co-ordinates.This makes sure that things scale properly.

9.4 Solve problems away from the computer

Most of the work involved in solving a problem is the analysis of the problem.This cannot be done at a keyboard.

• Analyse your problem on paper.

• Make sure you can solve it by hand.

• Write out your solution on paper.

Page 98: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

98 CHAPTER 9. PUTTING IT ALL TOGETHER

• Run through it on paper - pretend to be the computer and see if youget the right answer.

• Try it on the computer.

• If you get the wrong results print your program and work through itby hand.

If you spend hours at a computer you get tired and probably do somethingreally stupid like making changes at random. Programming is a logicalactivity; think before you act.

9.5 Exercises

1. Modify the program from section 8.2 so that it draws a street of 7houses, all called ”Dunhacking”, receding into the distance.

Page 99: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 10

Files

10.1 File basics

So far we have looked at programs that have some form of user interface.Many programs are not like this: they read information from a computerfile, perform some operation on it and then put their results in another file.This second file might then be printed. This is what happens at your bankwhen they are processing your account. There is no lovingly crafted graphicinterface that a bank clerk uses to produce each statement by hand: anoperator starts a program running and it reads the files containing accountinformation, analyses the data and then prints the statements.

Java provides many methods for reading and writing data; it can read/writefiles on a local computer, on a distant computer or even read/write directlyto another program. Here we will be concerned with fairly simple file in-put/output.

10.2 Security in Java

One of the principal design features of Java is security: it should not bepossible for an applet downloaded from the Internet to damage the clientmachine or to read or write files on the client machine. This provides protec-tion against viruses and against theft of data. This is why Java distinguishesapplets from applications. The general idea is:

Applets:

• Can be downloaded from another machine.

• They cannot read or write files on the client machine.

• They can read and write files on the server.

Applications:

99

Page 100: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

100 CHAPTER 10. FILES

• Do not download over the Internet - they are usually installed on theclient.

• They can read and write files on the local machine.

Some development environments relax the rule for applets that are runningunder its control: they permit applets to access files on your machines harddisc. This is to make it easier to test the applets you develop. Once youhave developed your applet you can make it available on a Web page andanyone using it will have the full Java protection mechanism.

10.3 Streams

All input and output in Java is via a stream. There are many types ofstreams so that you can handle data of various types and handle varioustypes of devices. The following program shows simple input and output:

package pij.files;

import java.io.*;

/*** Example of reading and writing.*/

public class WritingAFile {public static void main(String args[]) throws IOException {

PrintStream theOutput = new PrintStream(new FileOutputStream("c:\\myOutFile.txt"));

theOutput.print("This is the first bit|");theOutput.println("This is the second bit|");theOutput.print("This is the third bit|");theOutput.println("This is the fourth bit");

}}

This writes the following into the file myOutFile.

This is the first bit|This is the second bit|This is the third bit|This is the fourth bit

Dissecting this in very small pieces:

• The string myOutFile is the name of the file into which output is tobe printed. If it doesn’t exist then it will be created. A string variablecan be used in its place.

Page 101: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

10.3. STREAMS 101

• new FileOutputStream(”myOutFile”) creates a FileOutputStream butthis cannot be used directly. It needs to be converted into a PrintStream,which is done by:

• new PrintStream(new FileOutputStream(”c:myOutFile.txt”)); This creates a PrintStream which is assigned totheOutput.

• To print to myOutFile we use the print and println methods oftheOutput. Notice the difference between these two.

The next example shows input from a file:

package pij.files;

import java.io.*;

public class ReadingAFile {public static void main(String args[]) throws IOException {

BufferedReader theInput = new BufferedReader(new FileReader("c:\\myInFile.txt"));

PrintStream theOutput = new PrintStream(new FileOutputStream("c:\\myOutFile.txt"));

String lineOne, lineTwo;

// Read two lines from the input filelineOne = theInput.readLine();lineTwo = theInput.readLine();

// Write the lines out in reverse ordertheOutput.println(lineTwo);theOutput.println(lineOne);

}}

Before running this program I created the following input file (using a texteditor; any reasonable editor will do) called myInFile:

Isn’t it funny how a bear likes honey?Buzz, buzz, buzz; I wonder why it does.

Running the program produces the output file:

Buzz, buzz, buzz; I wonder why it does.Isn’t it funny how a bear likes honey?

Page 102: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

102 CHAPTER 10. FILES

We use the techniques we used earlier for dealing with numbers:

package pij.files;

import java.io.*;

/*** Example of reading and writing numbers.*/

public class ReadingNumbers {

public static void main(String args[]) throws IOException {BufferedReader theInput = new BufferedReader(

new FileReader("c:\\myInFile.txt"));PrintStream theOutput = new PrintStream(

new FileOutputStream("c:\\myOutFile.txt"));

String line;int first, second;

// Read two lines from the input fileline = theInput.readLine();first = Integer.parseInt(line);line = theInput.readLine();second = Integer.parseInt(line);

// Write the lines out in reverse ordertheOutput.println("Product of " + first + " and "

+ second + " = " + first * second);}

}

The input file for this could be:

123456

producing the output in myOutFile:

Product of 123 and 456 = 56088

10.4 Exercises

1. Create a file which contains the names of Snow White’s seven dwarves(if you don’t know them, make them up - I don’t know them either).

Page 103: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

10.4. EXERCISES 103

Modify the program updated in section 9.5 exercise 1 to put the namesof each of the dwarves over the doors instead of Dunhacking.

Page 104: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

104 CHAPTER 10. FILES

Page 105: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 11

Strings

11.1 Introduction

Strings are collections of characters and can be manipulated, read and writ-ten. Java’s methods for string manipulation are very powerful. In thissection I will show only some of the basic operations.

11.2 Manipulating Strings

There are many methods in the class String for manipulating text. Themost important ones are all illustrated in the following program:

package strings;

/*** Demonstration of making and manipulating strings.*/public class StringDemo {

public static void main(String args[]) {// This is an empty string.String s1 = null;output("At point 1 the string is: <" + s1 + ">");

// Initialised from a string constantString s2 = new String("Pollution is bad today");output("At point 2 the string is: <" + s2 + ">");

// A string initialised from a string object.String s3 = new String(s2);output("At point 3 the string is: <" + s3 + ">");

105

Page 106: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

106 CHAPTER 11. STRINGS

// Concatenation.String s4 = s2 + ": October 1st 1997";output("At point 4 the string is: <" + s4 + ">");

// String length.output("At point 5 the length is: " + s4.length());

// Get a char.output("At point 6 char 8 is: " + s4.charAt(8));

// Compare strings.output("At point 7 equals is: " + s4.equals(s3));

// Compare strings.output("At point 8 equalsIgnoreCase is: "

+ s4.equalsIgnoreCase(s3));

// Compare strings.output("At point 9 compareTo is: " + s4.compareTo(s3));

// Compare regions from char 1 for 5 chars.output("At point 10 regionMatches is: "

+ s4.regionMatches(1, s3, 1, 5));

// Compare regions ignoring case.output("At point 11 regionMatches is: "

+ s4.regionMatches(true, 1, s3, 1, 5));

// Start.output("At point 12 startsWith is: "

+ s2.startsWith("Pollu"));

// End.output("At point 13 endsWith is: "

+ s2.endsWith("today"));

// indexOf char.output("At point 14 indexOf is: " + s2.indexOf(’u’));

// indexOf char.output("At point 15 indexOf is: " + s2.indexOf(’u’, 10));

// Last occurrence.output("At point 16 lastIndexOf is: "

Page 107: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

11.2. MANIPULATING STRINGS 107

+ s2.lastIndexOf(’a’));

// Last occurence of char.output("At point 17 lastIndexOf is: "

+ s2.lastIndexOf(’a’, 10));

// indexOf string.output("At point 18 indexOf is: " + s2.indexOf("tod"));

// indexOf string.output("At point 19 indexOf is: "

+ s2.indexOf("tod", 10));

// lastIndexOf string.output("At point 20 lastIndexOf is: "

+ s2.lastIndexOf("tod"));

// lastIndexOf string.output("At point 21 lastIndexOf is: "

+ s2.lastIndexOf("tod", 10));

// substring.output("At point 22 substring from 10 is: <"

+ s2.substring(10) + ">");

// substring.output("At point 23 substring from 10 to 15 - 1 is: <"

+ s2.substring(10, 15) + ">");

// Concatenation.s3 = s2.concat(" but not as bad as yesterday");output("At point 24 s3 is: <" + s3 + ">");

// Replace characters.s3 = s2.replace(’a’, ’*’);output("At point 25 s3 is: <" + s3 + ">");

// Change case.s3 = s2.toLowerCase();output("At point 26 s3 is: <" + s3 + ">");

// Change case.s3 = s2.toUpperCase();output("At point 27 s3 is: <" + s3 + ">");

Page 108: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

108 CHAPTER 11. STRINGS

// Remove spaces.s1 = " Help, I’m surrounded by white space ";s2 = s1.trim();output("At point 28 s1 is: <" + s1 + ">\n"

+ " and s2 is: <" + s2 + ">");}

/** A simple method to help save space on lines above. */private static void output(String s) {

System.out.println(s);}

}

The output from this is:

At point 1 the string is: <null>At point 2 the string is: <Pollution is bad today>At point 3 the string is: <Pollution is bad today>At point 4 the string is: <Pollution is bad today: October 1st 1997>At point 5 the length is: 40At point 6 char 8 is: nAt point 7 equals is: falseAt point 8 equalsIgnoreCase is: falseAt point 9 compareTo is: 18At point 10 regionMatches is: trueAt point 11 regionMatches is: trueAt point 12 startsWith is: trueAt point 13 endsWith is: trueAt point 14 indexOf is: 4At point 15 indexOf is: -1At point 16 lastIndexOf is: 20At point 17 lastIndexOf is: -1At point 18 indexOf is: 17At point 19 indexOf is: 17At point 20 lastIndexOf is: 17At point 21 lastIndexOf is: -1At point 22 substring from 10 is: <is bad today>At point 23 substring from 10 to 15 - 1 is: <is ba>At point 24 s3 is: <Pollution is bad today but not as bad as yesterday>At point 25 s3 is: <Pollution is b*d tod*y>At point 26 s3 is: <pollution is bad today>At point 27 s3 is: <POLLUTION IS BAD TODAY>At point 28 s1 is: < Help, I’m surrounded by white space >

and s2 is: <Help, I’m surrounded by white space>

Page 109: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

11.3. EXERCISES 109

There are other methods for changing objects to strings, but the exampleabove shows almost all the important ones. Don’t memorise them but doget used to using them.

11.3 Exercises

1. Write a method with the signature insert(s1, i, s2) which returnsa string which is s1 with s2 inserted at position i.

2. According to Douglas Adams’s “Hitch Hikers Guide to the Galaxy”the foulest, filthiest swear word in the galaxy is “Belgium”. Write aprogram which takes a string as an argument and returns the stringwith all occurrences of “Belgium” replaced by *******.

Page 110: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

110 CHAPTER 11. STRINGS

+ String concatenationt.length() Number of characters in a tt.CharAt(i) Return character at i within tt.equals(s) Returns true if s is identical to tt.equalsIgnoreCase(s) Like equals but letter case is ignoredt.compare(s) Returns 0 if s equals t, negative if t

precedes s, positive if t follows st.regionMatches(i, s, j, k) Return true if region of t starting at i

matches s from j for k characterst.regionMatches(true, i, s, j, k) As previous ignoring caset.startsWith(s) Return true if t starts with st.endsWith(s) Return true if t ends with st.indexOf(ch) Returns an int which is the position

of ch in tt.indexOf(ch, i) Returns an int which is the position

of ch in t starting from it.lastIndexOf(ch) Returns an int which is the last

position of ch in tt.lastIndexOf(ch, i) Returns an int which is the last

position of ch in t before position it.subString(i) Return a string that is the substring

of t from i to the end of tt.subString(i, j) Return a string that is the substring

of t from i to j - 1.t.concat(s) Return a string that is t + st.replace(ch1, ch2) Return a string that is t with all

occurrences of ch1 replaced by ch2t.toLowerCase() Return string that is t with uppercase

letters converted to lowercaset.toUpperCase() Return string that is t with lowercase

letters converted to uppercaset.trim() Remove leading and trailing white space

characters

Figure 11.1: String methods and operators.

Page 111: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 12

Manipulating informationfrom files

12.1 Introduction

When reading text files we need to split the text into appropriate chunksand to convert numbers in text format into internal representations of int,long, float and double. Java provides several tools to help do this. To makethings concrete, let us consider the file of data shown below:

actinium, Ac, 89, 227aluminium, Al, 13, 27.0americium, Am, 95, 243antimony, Sb, 51, 122argon, Ar, 18, 39.9arsenic, As, 33, 74.9astatine, At, 85, 210

These data consist of the names of chemical elements, their chemicalsymbols, atomic number and atomic mass. The data are free format andcomma separated.

12.2 Tokens

When reading a file such as that above we often want to split it into unitscalled tokens. actinium, Ac, 89 and 227 are all tokens in the file above. Oncea token has been identified it may then need to be converted to a number:atomic numbers are all integers and atomic masses are floats. Java providesa class for recognising tokens and methods for converting numbers.

The following program reads the file above and stores the data:

111

Page 112: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

112 CHAPTER 12. MANIPULATING INFORMATION FROM FILES

import java.io.*;import java.util.*;

class Element{String name, symbol;int atomicNumber;float atomicMass;} // Element

public class ReadFile {

public static void main(String args[]) throws IOException {DataInputStream theInput= new DataInputStream(new FileInputStream("elements"));Element table[] = new Element[103]; // That’s how many are in my bookString theLine;StringTokenizer tokens;int n;

n = 0;while (true){theLine = theInput.readLine();if (theLine == null || theLine.length() == 1)break;tokens = new StringTokenizer(theLine, " ,"); // comma and spacetable[n] = new Element();table[n].name = tokens.nextToken();table[n].symbol = tokens.nextToken();table[n].atomicNumber = Integer.parseInt(tokens.nextToken());table[n].atomicMass = new Float(tokens.nextToken()).floatValue();n++;} // while

for (int i = 0; i < n; i++){System.out.println(table[i].name+ " " + table[i].symbol+ " " + table[i].atomicNumber+ " " + table[i].atomicMass);} // for i

try {System.in.read(); // prevent console window from going away} catch (java.io.IOException e) {}} // main

Page 113: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

12.3. THE STRINGTOKENIZER CLASS 113

} // ReadFile

Note: The declaration StringTokenizer tokens; creates a StringTokenizerobject called tokens. The statement tokens = new StringTokenizer(theLine, " ,");attaches tokens to the string theLine and states that tokens are separatedby spaces or commas. There are other constructors for StringTokenizerwhich will be described below.

Getting a new token is done by: table[n].name = tokens.nextToken();which returns the next token from theLine. Remember that declaring anarray of a class (Element table[] = new Element[103];) doesn’t create theclass objects. That is why the loop has the line table[n] = new Element();This makes an Element object for table[n] to refer to.

The loop finishes when the end of the input file is reached. readLine isdefined to return null when the end of input is reached. In this case I want toallow for blank lines at the end of the input file. That is why the conditionreads if (theLine == null —— theLine.length() == 1). On a blank linetheLine contains just one character representing the end of line.

12.3 The StringTokenizer class

In the example above we saw one constructor for the StringTokenizer class.There are a few others. They are:

public StringTokenizer(String s, String delims, boolean returnTokens)

Using s this creates a StringTokenizer using the characters in delims asdelimiting characters. If returnTokens is true then the delimiters are alsotreated as tokens.

public StringTokenizer(String s, String delims)

Using s this creates a StringTokenizer using the characters in delims asdelimiting characters. It is the same as the previous constructor with re-turnTokens set to be false.

public StringTokenizer(String s)

Using s this creates a StringTokenizer using the characters tab, newline andspace ( \t\n\r) as the delimiters.

Other methods of StringTokenizer are: public hasMoreTokens() whichreturns true if there are yet more tokens in a StringTokenizer. As an exam-ple,

while (tokens.hasMoreTokens()) ...public String nextToken()

Page 114: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

114 CHAPTER 12. MANIPULATING INFORMATION FROM FILES

You saw this above. If there are no more tokens the exception NoSuchEle-mentException will be thrown. public String nextToken(String delims) be-haves identically to the last method except that it changes the set of de-limiting characters. public int countTokens() gives the number of remainingtokens.

12.4 Converting numbers

In the program above there are examples of converting numbers from strings.For the integer types int and long there are the parsing methods:

Integer.parseInt(String);Integer.parseInt(String, int base);Integer.parseLong(String);Integer.parseLong(String, int base);

Unfortunately floating point values are not handled in the same way. Toconvert float and double values one has to use the methods:

new Float(String).floatValue();new Double(String).doubleValue();

The use of floatValue is illustrated above. While we are at it we may aswell mention the method new Boolean.(String).booleanValue();, whichturns a string to a boolean value.

Page 115: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 13

Arrays

13.1 Introduction

The strings that we looked at in the last section are an example of a collectionclass. A String is a collection of characters. We often need collections ofother things and that is where arrays come in. An array is a collection ofthings which can then be referred to individually by indexing. We startedto look at arrays in chapter 7. There you saw how to declare an array andto initialise one.

At that point we have looked only at simple arrays of integers. It is possi-ble, and indeed necessary, to create arrays composed from more complicatedobjects. Arrays of Strings show the ideas.

13.2 Arrays of Strings

Arrays can have elements of any type. It is common to have arrays ofstrings. As an illustration, look back at the Zeller’s congruence example.This contains the following lines:

System.out.print("Date " + day + "/" + month + "/"+ year + " is ");

switch (dayOfWeek) {case 0:

System.out.println("Sunday");break;

case 1:System.out.println("Monday");break;

case 2:System.out.println("Tuesday");break;

115

Page 116: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

116 CHAPTER 13. ARRAYS

case 3:System.out.println("Wednesday");break;

case 4:System.out.println("Thursday");break;

case 5:System.out.println("Friday");break;

case 6:System.out.println("Saturday\n");break;

}

This is rather awkward and we are tempted to seek a better way. Arraysprovide a much neater solution:

String dayName[] = { "Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday" };

// Print the resultSystem.out.println("The date " + day + "/" + month + "/"

+ year + " is " + dayName[dayOfWeek]);

The array dayName holds strings indexed from 0 to 6. This is just whatwe want because dayOfWeek is a number in the range 0 to 6. Notice thatthe declaration of dayName(String dayName[ ] = ... ) has no array sizespecified in the square brackets. This is because we use an initialiser (the bitin ...) so the compiler just counts the number of elements in the initialiserand voila, it knows the array size.

13.3 Searching a list of values

Searching through a list to see if it holds a value is one of the most commonoperations in programming. The next example shows an applet (I thinkit’s time we saw more applets) which searches an array of numbers for aparticular value. The value is entered from the applet window. The list ofvalues is taken from the previous example:

package pij.arrays;

import java.awt.*;import java.applet.Applet;

/**

Page 117: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

13.3. SEARCHING A LIST OF VALUES 117

* Search through a list.*/public class SearchDemoApplet extends Applet {

Label prompt;

TextField forInput;

int n;

boolean found;

int smallPrimes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,31, 37, 41 };

boolean isInList(int theNumber) {int listEnd = smallPrimes.length - 1;int i = 0;

// Order is important in next expressionwhile (i <= listEnd && smallPrimes[i] != theNumber)

i++;

if (i > listEnd)return false;

elsereturn true;

}

public void init() {prompt = new Label("enter a number");forInput = new TextField(10);add(prompt);add(forInput);repaint();

}

public boolean action(Event theEvent, Object theObject) {String valueAsString = theObject.toString();

showStatus("");forInput.setText("");n = Integer.parseInt(valueAsString);found = isInList(n);repaint();

Page 118: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

118 CHAPTER 13. ARRAYS

return true;}

public void paint(Graphics g) {if (found)

g.drawString("Yes, it’s there", 30, 30);else

g.drawString("No, it’s not there", 30, 30);}

}

Right, so let’s look at the thing in detail:

• Although it looks bigish, most of it is boilerplate taken from the earlierapplet examples.

• The action method is responsible for calling the isInList method tosearch the list for the value and for putting the result in the variablefound, which belongs to the whole class.

• It is important that found belongs to the whole class because it is usedin several methods (action, and paint).

• Variables such as i in isInList, on the other hand, are local to theirown methods; no other method has any business looking at them.

• First: remember how the methods get called: paint happens whenrepaint is called, action when an event occurs (mouse click, pressenter key etc.).

• So, when a number is entered action calls theObject.toString toget the characters entered in the TextField as a string of characters.

• Next we call parseInt to convert the string to an integer value.

• At this point we start the real work: we call isInList using thenumber we have read as an argument. Is it a member of our list?

• Look at isInList: you should be able to get the hang of it, though acouple of points are unusual. We shall discuss it later in mind numbingdetail so try to get the idea.

• The method isInList communicates its result to action which dulyputs it in the global variable found. This may not be the best way todo this so shall look at other approaches later.

• The paint method picks up the result of the call of isInList from thevalue that action has so kindly left in the class variable found. Itthen prints an appropriate message.

Page 119: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

13.3. SEARCHING A LIST OF VALUES 119

From a computer science point of view there is really only one interestingmethod in this class: isInList. Let’s recapitulate:

boolean isInList(int theNumber) {int listEnd = smallPrimes.length - 1;int i = 0;

// Order is important in next expressionwhile (i <= listEnd && smallPrimes[i] != theNumber)

i++;

if (i > listEnd)return false;

elsereturn true;

}

This harmless looking little fragment of a program actually has a Sundayname1: it is called the linear search algorithm. You have now had a formalbit of computer science sprung on you whilst you were asleep (WAKE UP INTHE BACK ROW THERE). It’s linear because it steps from the beginningof the list to the end, it’s a search algorithm because it searches for a par-ticular value and it’s an algorithm for reasons you should well understandby now. It also, despite its brevity, contains at least two opportunities formajor errors and one for greater brevity. IT IS ESSENTIAL THAT YOUUNDERSTAND THESE POINTS. Pay attention for the next half page.

First look at the line:

while (i <= listEnd && smallPrimes[i] != theNumber) ...

The first time round this reads, in effect:

while (0 <= 12 && smallPrimes[0] != theNumber) ...

Two tests are being made: first “have we reached the end of the list?” andthen ”have we found the value we want?” If we haven’t then i is incrementedand we go round again. What happens if theNumber is not in the list? Wewill get a final turn that reads, in effect:

while (13 <= 12 && smallPrimes[13] != theNumber) ...

At first blush this might look as if it should cause an error because there isno element smallPrimes[13]. Will we get the “array index out of bounds”

1If the term ”Sunday name” is not clear, that’s a name one uses when one is dressedup and being very correct. Alternative versions might be Friday or Saturday names.Personally I’m looking for a religion that has six holy days each week; then I can have oneday for shopping.

Page 120: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

120 CHAPTER 13. ARRAYS

exception that was mentioned earlier? The answer is “no” because the firstpart of the test is done first; as 13 <= 12 gives the result false the secondpart of the expression is not evaluated (it is “short-circuited”). However, ifthe two tests had been written the other way round then we would have aproblem. It looks like a small detail but the effect is crucial. Make sure youunderstand this.

Now look at the last part of the search method:

if (i > listEnd)return false;

elsereturn true;

The expression i > listEnd is a boolean expression. Thus it can read oneof two ways:

if (true)return false;

elsereturn true;

or

if (false)return false;

elsereturn true;

So if i > listEnd is true then the method returns false, and if i > listEndis false then the method returns true. So the returned value is the oppo-site of i > listEnd. This can be obtained by using the negation operator!. Therefore the last four lines could be written as one:

return !(i > listEnd);

This use of boolean values is very important. You should get used to manip-ulating boolean expressions with the same ease you manipulate expressionsinvolving integers. Think boolean!

The next point involves the if statement at the end of paint:

if (found)g.drawString("Yes, it’s there", 30, 30);

elseg.drawString("No, it’s not there", 30, 30);

When you see you are writing the same thing (almost) more than once thenthere is probably a better way. Now C/Java has a funny operator. It’s thatweird triadic operator ?: and behaves in the following way:

Page 121: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

13.4. SORTING 121

x = 3; y = 4;z = x > y ? 27 : 37;

After this the value of z is 37. The first part is a boolean expression - if it istrue then the result of the expression is 27; otherwise it is 37. In our casex > y delivers false and so the result of ?: is 37. So what has this to dowith the price of fish? Well, not a lot, but it gives us another way of lookingat that if statement in paint. We could rewrite it as:

g.drawString(found ? "Yes, it’s there": "No, it’s not there", 30, 30);

Notice how the operator ? : is delivering the string we want. This style ofprogramming is very important and is, indeed, the only way of programmingin some languages. It may be argued that it is harder to read, but that isnot so once one is used to it.

Now we get “AUTHOR’S MESSAGE”; there are many ways of program-ming, and by learning many of them you will find novel ways of seeing away to a solution to a problem. It is important to learn all of them thatyou can find; if a method of thinking works then learn it. The great physi-cist Richard Feynman often referred to his “box of tools”. These are thetechniques he knew for solving problems. He found he could solve problemsthat other people could not handle because he had some technique in his“tool box” that many people did not know. Start to prepare your “box oftools” (HINT: buy an exercise book with a marbled cover, and write in itthe things you learn).

13.4 Sorting

There has been a great deal of work on finding methods of sorting data heldin arrays (this is regarded as real computer science). Here we will look atone way, called selection sort, for doing this. It is not a very good method,in fact it’s a very bad method, but it is very simple. Better methods willappear later (If you have heard of bubble sort then forget it; it’s even worse).

To start with suppose we have the following array:

Value: 7 9 10 3 15 6 13 25 19 17 21 27 11 23Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13

The value 27 in position 11 is the largest in the array. Clearly this numberneeds to go to position 13, but what do we do with the number already at13? The easiest thing is to move it to cell 11 so that we have:

Value: 7 9 10 3 15 6 13 25 19 17 21 23 11 27Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13

Page 122: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

122 CHAPTER 13. ARRAYS

Now we have the largest element in its correct position and we need to sortthe remaining 12 elements. We just repeat the process, selecting the largestelement in the unsorted section (25 at position 7) and moving it to the top(position 12). So now we have:

Value: 7 9 10 3 15 6 13 11 19 17 21 23 25 27Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13

Repeating the process will sort the entire array. Here is the program writtenin full:

package pij.arrays;

/*** Example of sorting.*/

public class SelectionSortDemo {

public static void selectionSort(int theList[]) {int top, i, indexOfLargest, swap;for (top = theList.length - 1; top >= 1; top--) {

// Find largest element between 0 and topfor (i = 1, indexOfLargest = 0; i <= top; i++)

if (theList[i] > theList[indexOfLargest])indexOfLargest = i;

// Swap the largest element with the top elementif (indexOfLargest != top) {

swap = theList[indexOfLargest];theList[indexOfLargest] = theList[top];theList[top] = swap;

}}

}

public static void main(String args[]) {int table[] = { 7, 3, 9, 17, 2, 1, 4 };selectionSort(table);for (int n = 0; n < table.length; n++)

System.out.print(" " + table[n]);System.out.println();System.out.flush();

}}

Note:

Page 123: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

13.5. TWO DIMENSIONAL ARRAYS 123

• The argument list to selectionSort: void selectionSort(int theList[]).This tells the compiler that the method takes an array of integers asits argument.

• There is, of course, the problem of how the method is to find out howmany elements there are in the array: every array carries its size withitself. This is shown in the expression: top = theList.length - 1;

• The overall logic of the sort algorithm is shown below.

• Make sure you understand the logic of the main method.

The selection sort algorithm can be summarised as follows:

public static void selectionSort(int theList[]) {...for (top = theList.length - 1; top >= 1; top--) {

// Find largest element between 0 and top...// Swap the largest element with the top element...

}}

SAQs:

• Why does top start at theList.length - 1 ?

• Why is the loop terminating condition top ¿= 1 ?

• Why is the variable swap used? Explain this piece of code.

• The largest variable found up to the current point is indicated by thevariable indexOfLargest; why is the index of the largest value used,rather than the largest value itself?

13.5 Two dimensional arrays

All the arrays we have seen so far are one-dimensional; just a row of values.The mathematical equivalent is a vector. As you will know if you have takena course in linear algebra two dimensional structures called matrices are alsoimportant. Apart from the mathematical uses of matrices, two dimensionalarrays can be used to hold tables such as games results, distances betweentowns etc. Before looking at a real application we will look at the basics of2-D arrays.

Page 124: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

124 CHAPTER 13. ARRAYS

package pij.multidimensionalarrays;

public class ArrayDemo1 {public static void main(String args[]) {

int table[][] = new int[3][3];

for (int row = 0; row < 3; row++)for (int col = 0; col < 3; col++)

table[row][col] = row * col;

for (int row = 0; row < 3; row++) {for (int col = 0; col < 3; col++)

System.out.print(" " + table[row][col]);System.out.println();

}

try {System.in.read(); // Prevent console window from going away.

} catch (java.io.IOException e) {}

}}

The output from this is:

0 0 00 1 20 2 4

Notice how the 2-D array is created: int table[][] = new int [3][3];The statement table[row][col] = row * col; shows how to refer to

an element of the array. If you imagine that verb—][— is equivalent to acomma this notation is very similar to the way we refer to matrix elementsin linear algebra.

The use of two nested for loops is very common when handling 2-Darrays.

13.6 Exercises

1. Write an applet which tracks the mouse by recording, in arrays, theposition at which it is clicked. Allow up to 100 points. The programshould then draw the track that the mouse followed.

2. Write an application which reads any word from the console and whichprints it in the following big style:

Page 125: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

13.6. EXERCISES 125

H H EEEEE L L OOOOH H E L L O OHHHHHH EEE L L O OH H E L L O OH H E L L O OH H EEEEE LLLLLL LLLLLL OOOO

You will need to print in a monospaced font such as Courier. Noticethat each letter is built up from the normal version of itself. You canlimit yourself to one case of characters.

Page 126: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

126 CHAPTER 13. ARRAYS

Page 127: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 14

A hint of HTML

14.1 History

Once upon a time, when the World was young and innocent, scientists of allfields used to exchange information by wrapping very large magnetic tapesin padded boxes which they then posted from Hull University in Englandto McGill University in Canada, or wherever. The clever chaps at the otherend read the handwritten note in the box explaining how the tape wasencoded and so used a standard program to decode it or, more often thanwas desirable, said “strewth, what the Hell is this?”. Either way they workedout how to read the stuff. These heros kept science running.

Later they all acquired networks, so they no longer sent padded boxesto one another; they sent it over the network. The result was the incompre-hensible stuff got there faster. The heros were expected to react faster.

So, the heros came up with protocols with silly names such as FTP. Thenpeople could move files over large chunks of the globe but still had problemsbecause their documents looked, well, like computer printouts. (This is anover-simplification, but please accept the general idea).

At this point, in a centre where this type of nonsense was the stuff ofdaily madness (CERN, the European centre for elementary particle research)a real hero stepped forward: Tim Berners-Lee (pause for dramatic music).Mr. Berners-Lee thought there ought to be a way of presenting informationthat would be independent of the machine receiving it but which mightalso allow more interesting presentation than simple green text on a blackbackground on machines which were capable of being less boring.

14.2 The big idea

T B-L took some ideas from SGML (Standard Generalized Markup Lan-guage), a language for communicating things between newspapers so thatone paper’s personal typographic style could be painlessly imposed on a

127

Page 128: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

128 CHAPTER 14. A HINT OF HTML

document from another paper. What Mister Tim did was create HTML(HyperText Markup Language) which describes a document in a way thatis independent of the recipient computer.

Imagine you want to say:

I am really pleased with your reply.

In HTML you would write:

I am <em>really</em> pleased with your reply.

Do you get the idea? There is a tag called <em> which starts a sectionof emphasised text. The end of the section is marked using </em>.

The HTML language also requires the following tags at the beginning ofa section:

<html><head><title>Write a title here</title></head><body>

and at the end one puts

</body></html>

Do you get the idea? There is a Tag called <B> which starts bold text.The end of bold text is </B>.

The text of the page goes between <BODY> and </BODY>. There are manytags in HTML; they allow you to link to other pages on the World WideWeb, insert pictures and sounds and all those other things we are used toseeing and hearing. It is not our job here to show how to write HTML -if you want to do that then buy a book with a title like “HTML for 21Dummies”. However, we do need to look at how to place a Java applet ona page.

Page 129: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

14.2. THE BIG IDEA 129

The page was produced using the following HTML:

<html><head><title>ButtonDemoApplet</title></head><body><h1>A Web page to demonstrate installing an applet on a Web page.</h1>

<p>Here we are in a Web page about to demonstrate the amazing power ofapplets. Look at this incredible applet using an algorithm so newthat it was only invented 2,500 yrs ago.</p>

<p><applet codebase="./classes"code="pij/makingapplets/ButtonDemoApplet.class"name="ButtonDemoApplet" width="200" height="100"></applet></p>

<p>Well, did that impress you?</p>

Page 130: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

130 CHAPTER 14. A HINT OF HTML

</body></html>

The important part is that between <applet> and </applet>. The codefor the applet is in the file TrivialApplet.class and is generated by thecompiler. It must be in the folder named in codebase= as the web page.The width and height specify the initial size of the applet window. To runthe applet you must look at the page with a Java aware web browser.

Page 131: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 15

A touch of class

15.1 Introduction

The class concept is the most important in the whole of object-orientedprogramming (OOP). In this part of this course we will only use classesas data structures (ways of collecting data together) with a few extra bellsand whistles. However, the classes we create here are perfectly proper Javaclasses and can be extended easily to a more OOP approach.

15.2 A new data type - a football team

We are going to create a new data type in Java: a football team (I meanreal football here, not that strange activity where men in helmets crouch ina group and waggle their Lycra clad bottoms in the air). Each team has aname and a list of results (games won, drawn and lost). It would be nice ifwe could encapsulate all these data on a particular team into a single dataobject. The way this is done is illustrate below:

/** Example of a simple data structure. */public class Team1 {

public String name;

public int won, drawn, lost;

public static void main(String args[]) {Team1 aup = new Team1();aup.name = "All Universal Playboys";aup.won = 5;aup.lost = 2;aup.drawn = 3;System.out.println("Team is: " + aup.name

+ " with results (w, l, d) " + " " + aup.won

131

Page 132: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

132 CHAPTER 15. A TOUCH OF CLASS

+ ", " + aup.lost + ", " + aup.drawn);}

}

This produced the output:

Team is: All Universal Playboys with results (w, l, d) 5, 2, 3

Notes:

• I have defined a new class called Team. A Team object has fourmembers, one String and three ints.

• The Team class is defined outside the ThisApplication class.

• Inside the main method of ThisApplication we create a new Teamcalled aup.

• To refer to the name variable in aup we use the notation aup.name.You can read this backwards as “the name of aup”. A construct such asaup.name is a perfectly good String variable and can be used anywhereand in any way where a String variable can be used. The same goesfor the int members.

I have used a few terms fairly interchangeably. In particular I havecalled name, won, lost and drawn members of objects of class Team. Otherterms that are used for the same thing are fields, data members and instancevariables. Team is a class, aup is an object, aup.won is a data member ofthe object aup.

15.3 Adding a constructor (a class method)

The way we put the values in the instance variables of aup above is clumsy.It took us four lines to fully initialise the object aup. Now classes can alsocontain methods and in particular constructors. A constructor is a methodbelonging to a class that can be used to initialise objects of that class.Enough abstract chat - let’s see one:

/** Example of a simple data structure. */public class Team2 {

public String name;

public int won, drawn, lost;

public Team2(String n, int w, int d, int l) {name = n;won = w;

Page 133: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

15.4. MULTIPLE CONSTRUCTORS 133

drawn = d;lost = l;

}

public static void main(String args[]) {Team2 aup = new Team2("All Universal Playboys ", 5, 2, 3);

System.out.println(" Team is: " + aup.name+ " with results (w, l, d) " + " " + aup.won+ ", " + aup.lost + ", " + aup.drawn);

}}

Notes:

• Notice the constructor method has the same name as the class. Thisis how you indicate it is a constructor.

• The constructor is used at the point where the Team is created. In thiscase it is at the point where new is called at new Team("All Universal Playboys" 5, 2, 3).

• The parameters to the constructor are passed into the method throughthe argument list.

Using a constructor like this has two advantages: it is easier to initialisea Team object and it ensures that a team object is correctly initialised.Forgetting initialisation is a common source of hard-to-detect errors.

15.4 Multiple constructors

The constructor above takes four parameters: a String and three ints. Wesay it has the signature:

Team(String, int, int, int)

Methods must have unique signatures. However, methods can have the samename as long as the signatures are different. This can be useful in the Teamclass. When we create a team object we may know its name but not itsresults. This would be true of all teams at the start of the season. We cantake this into account by adding a new constructor:

/** Example of a simple data structure. */public class Team3 {

public String name;

public int won, drawn, lost;

Page 134: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

134 CHAPTER 15. A TOUCH OF CLASS

public Team3(String n, int w, int d, int l) {name = n;won = w;drawn = d;lost = l;

}

public Team3(String n) {name = n;won = 0;drawn = 0;lost = 0;

}

public static void main(String args[]) {Team3 aup = new Team3("All Universal Playboys ", 5, 2, 3);Team3 psg = new Team3("Paris St Germain");

System.out.println(" Team is: " + aup.name+ " with results (w, l, d) " + " " + aup.won+ ", " + aup.lost + ", " + aup.drawn);

System.out.println(" New team is: " + psg.name+ " with results (w, l, d) " + " " + psg.won+ ", " + psg.lost + ", " + psg.drawn); }

}

producing the result:

Team is: All Universal Playboys with results (w, l, d) 5, 3, 2New team is: Paris St Germain with results (w, l, d) 0, 0, 0

There are now two constructors called Team. We say the method is over-loaded. It has more than one definition. The compiler chooses the correctversion by using the signature; no two methods have the same signature.

Yet another useful constructor may have no arguments. This would behandy to create anonymous teams. The Team class could now be:

/** Example of a simple data structure. */public class Team4 {

public String name;

public int won, drawn, lost;

Page 135: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

15.5. MORE METHODS 135

public Team4() {name = "Undefined";won = 0;drawn = 0;lost = 0;

}

public Team4(String n, int w, int d, int l) {name = n;won = w;drawn = d;lost = l;

}

public Team4(String n) {name = n;won = 0;drawn = 0;lost = 0;

}

public static void main(String args[]) {Team4 anon = new Team4();

System.out.println("Anon team is: " + anon.name +" with results (w, l, d) " +" " + anon.won + ", " + anon.lost + ", " + anon.drawn);

}}

which when executed gices the output:

Anon team is: Undefined with results (w, l, d) 0, 0, 0

15.5 More methods

Making our Team useful could involve a few extra methods. At this pointwe try to decide what things a Team can do: it can win, lose or draw games,it may print its results (it can also sack its manager but that doesn’t seemlikely to help with the kind of things we will want to do). After adding thefollowing methods, a new version of the class is starting to look useful:

public void hasWon() {won++;

}

Page 136: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

136 CHAPTER 15. A TOUCH OF CLASS

public void hasLost() {lost++;

}

public void hasDrawn() {drawn++;

}

public String results() {return "Team " + name + " has results (w, l, d) " + won

+ " " + lost + " " + drawn;}

public void print() {System.out.println(results());

}

After the following lines in the main method:

Team5 aup = new Team5("All Universal Playboys");

aup.print();aup.hasWon();aup.print();

we get the result:

Team All Universal Playboys has results (w, l, d) 0 0 0Team All Universal Playboys has results (w, l, d) 1 0 0

Notes:

• The methods hasWon(), hasLost() and hasDrawn() change the valuesof the instance variables. Such methods are called mutating methods.

• The use of such methods is regarded as good practice. The alternativeof writing aup.won++ seems simpler. In this case the advantage ofhasWon() and its colleagues is not too obvious. The argument infavour of the proposed style is that direct access to instance methodsof an object is dangerous. If all access to instance variables of anobject is though methods defined in the class then the class can checkfor misuse (for example, a team both winning and losing at the sametime).

• The results() method makes inspecting the state of a team veryeasy.

Page 137: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 16

Loads of class

16.1 Introduction

In this section I shall still use the Team class from the last section but I amnow going to use it to build a new class: a football league (if you prefer youcan think of it as a league of teams who play bridge, fencing or competitiveknitting). This will show how we build more advanced data structures fromsimpler ones.

16.2 What is a league?

A league, in the games sense, is a group of teams or individuals who playagainst one another. Look at that definition: we can see that we shall needa “group of teams”. We have a definition for a Team, so what is a group ofthem? Well, we have seen one way of making a group: an array. So we maydefine a class League with an array of Teams in it. This is such a class:

public class League {Team leagueMembers[];

/** Constructor for a League. */public League(int theSize) {

leagueMembers = new Team[theSize];// Make the array to hold teamsfor (int i = 0; i < theSize; i++)

// Must make a new team for league membersleagueMembers[i] = new Team();

}}

It contains an array of Teams and a League constructor. The constructortakes one argument, the size of the league and builds the table one team at

137

Page 138: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

138 CHAPTER 16. LOADS OF CLASS

a time. Let’s go through this one step at a time:

• The statement: leagueMembers = new Team[theSize]; makes anarray of references to teams.

• The size of the array is theSize.

• The elements of the array are references to Team objects, not Teamobjects themselves.

• The loop for (int i . . . is responsible for making the real Team objectsand making the elements of leagueMembers refer to them.

• new Team(); uses the constructor with no arguments to make a newteam. (SAQ: what will be the name of this team? Don’t look at thenext section).

So now we have a new class we can use it. Here is a simple main methodjust to test if everything is working:

public static void main(String args[]) {League firstDivision = new League(8);firstDivision.leagueMembers[0].print();

}

This gives us the following output:

Team Undefined has results (w, l, d) 0 0 0

which answers the question from section 5 of the notes above and shows thatthe constructors are constructing and the methods behaving methodically.

Now we can put a more realistic league together. We would like to buildthe team from a list of names; we can do this if we add a new constructorfor League. Now League is:

public class League2 {Team leagueMembers[];

/** Constructor for a League. */public League2(int theSize) {

// Make the array to hold teams.leagueMembers = new Team[theSize];for (int i = 0; i < theSize; i++)

// Must make a new teamleagueMembers[i] = new Team();

}

/** Another constructor for a League. */

Page 139: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

16.2. WHAT IS A LEAGUE? 139

public League2(String teamList[]) {leagueMembers = new Team[teamList.length];for (int i = 0; i < teamList.length; i++)

leagueMembers[i] = new Team(teamList[i]);// Uses the String-based constructor.

}

}

Now look at this new constructor called League (String []); the name aTeamis not important. It takes an array of Strings and uses the constructorof Team which makes a new Team from an array of Strings. The actualargument (the real list of names) is held in aTeam. So it makes an array ofreferences to the correct number of teams.

The following main method illustrates use of these things:

public static void main(String args[]) {String theTeams[] = { "All Universal Playboys",

"Paris St Germain", "Barnsley","Manchester United", "Chelsea", "Leeds United","Sheffield Wednesday", "Newcastle United" };

League2 firstDivision = new League2(theTeams);

// Now we can have some results.firstDivision.leagueMembers[0].hasWon();firstDivision.leagueMembers[1].hasLost(); // Hooray

firstDivision.leagueMembers[2].hasWon();firstDivision.leagueMembers[3].hasLost(); // Hooray

firstDivision.leagueMembers[4].hasDrawn();firstDivision.leagueMembers[5].hasDrawn(); // Yawn

firstDivision.leagueMembers[6].hasDrawn();firstDivision.leagueMembers[7].hasDrawn(); // Yawn

for (int i = 0; i < theTeams.length; i++)// Print the league.firstDivision.leagueMembers[i].print();

}

producing the result:

Team All Universal Playboys has results (w, l, d) 1 0 0

Page 140: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

140 CHAPTER 16. LOADS OF CLASS

Team Paris St Germain has results (w, l, d) 0 1 0Team Barnsley has results (w, l, d) 1 0 0Team Manchester United has results (w, l, d) 0 1 0Team Chelsea has results (w, l, d) 0 0 1Team Leeds United has results (w, l, d) 0 0 1Team Sheffield Wednesday has results (w, l, d) 0 0 1Team Newcastle United has results (w, l, d) 0 0 1

(Ah! If only life were like that.)

16.3 Exercises

1. Write a program to solve the following problem (all letters representdifferent numbers):

DONALDGERALD +--------ROBERT

Page 141: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 17

Binary chop suey and ordersof difficulty

17.1 Orders of difficulty

A way of searching a list of values for a particular value was shown insection 13.3. This method, called linear search, involves running down thelist from beginning to end and stopping if the desired item is found. Afew seconds of reflection should convince you that if the list has n elementswe shall have to look, on average, at about n/2 values. In formal computerscience speak, because the number of inspected elements grows linearly withn, we say that the linear search algorithm is “of order n” with regard to thenumber of comparisons between the key and the elements of the list. This isabbreviated to saying that the linear search algorithm is O(n). This notationis called “big-oh”.

It is a major area of computer science trying to calculate the big-ohformula for an algorithm. For example, the selection sort algorithm we sawearlier is O(n2). This means that the number of operations grows as thesquare of the length of the array. Strictly speaking, for a sort algorithm,we should calculate the order of both the number of comparisons and thenumber of element swaps. In fact they both turn out to be O(n2).

Common formulae for the order of algorithms are:

constant The time involved is independent of the problem size.

log(n) The logarithm of n. The base of logs is immaterial (SAQ: why?)

n Linear; double the problem size and double the time taken.

n log(n) Not too bad.

n2 Starting to get grim. Double the problem size and quadruple the time.

en Exponential time. Bad news.

141

Page 142: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

142CHAPTER 17. BINARY CHOP SUEY AND ORDERS OF DIFFICULTY

n! Factorial time. Awful news.

Table 17.1: Orders of difficulty for n up to 10log(n) nlog(n) n n2 exp(n) n!

1.00 0.00 0.00 1.00 1.00 2.72 1.002.00 1.00 2.00 2.00 4.00 7.39 1.003.00 1.58 4.75 3.00 9.00 20.09 2.004.00 2.00 8.00 4.00 16.00 54.60 6.005.00 2.32 11.61 5.00 25.00 148.41 24.006.00 2.58 15.51 6.00 36.00 403.43 120.007.00 2.81 19.65 7.00 49.00 1096.63 720.008.00 3.00 24.00 8.00 64.00 2980.96 5040.009.00 3.17 28.53 9.00 81.00 8103.08 40320.0010.00 3.32 33.22 10.00 100.00 22026.47 362880.00

The logs here are base 2; as we are only dealing with proportionalitiesthe base of logs is irrelevant.

17.2 Searching revisited

Think of the linear search algorithm we have looked at. It doesn’t looktoo bad at first; after all O(n) is low down on the list of awfulness above.But think of a telephone book; the Paris directory must have a few millionentries. If we were to look for a person’s number using the linear searchalgorithm we would have to check a few million names. This is likely to pallas an amusing activity. Fortunately the entries in the directory have a spe-cial property that makes such tedium unnecessary; they are in alphabeticalorder.

Because of this property I can find an entry in a list of a million itemsin about 20 inspections. Can you work out the relationship between 20 andone million? We’ll come back to it later.

Now if we are searching a sorted list we have a much better algorithmthan the linear search. Start in the middle of the list, and see which halfthe desired item must be in. Repeat the operation on that half and carryon like that until we hit what we want or we find it is missing. This is moreor less what you do instinctively when using a telephone directory and iscalled binary search or binary chop.

The program in figure 17.1 looks for a word in the list of reserved Javawords, producing the result:

Index of static=40Index of ecstatic=-1

Page 143: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

17.2. SEARCHING REVISITED 143

public class BinarySearchExample {static String reservedWords[] = { "abstract", "boolean",

"break", "byte", "case", "catch", "char", "class","const", "continue", "default", "do", "double","else", "extends", "final", "finally", "float","for", "future", "generic", "goto", "if","implements", "import", "inner", "instanceof","long", "native", "new", "null", "operator", "this","package", "private", "protected", "public", "rest","return", "short", "static", "sure", "switch","synchronized", "throw", "throws", "transient","try", "var", "void", "volatile", "while" };

static int search(String theText, String theTable[]) {// Do a binary search for theText in theTable.// Return position or -1 if not present.int low = 0, high = theTable.length, mid = 0, comparison;boolean found = false;while (!found && low <= high) {

mid = (low + high) / 2;comparison = theTable[mid].compareTo(theText);if (comparison == 0)

found = true;else if (comparison < 0)

low = mid + 1;else

// comparison > 0high = mid - 1;

}return found ? mid : -1;

}

public static void main(String args[]) throws IOException,Exception {

String target1 = "static", target2 = "ecstatic";System.out.println("First result = "

+ search(target1, reservedWords));System.out.println("Second result = "

+ search(target2, reservedWords));}

}

Figure 17.1: Binary search

Page 144: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

144CHAPTER 17. BINARY CHOP SUEY AND ORDERS OF DIFFICULTY

Here the variables low and high refer to the limits of the portion ofthe list still left to search. mid is evidently the middle value. The methodcompareTo is a method of String. It is described in Chapter 11. Notice howmid gets moved at each step. If the value is not in the list then eventuallylow will become larger than high (draw a picture and work through it toconvince yourself).

Page 145: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 18

Data structures - Vectors

18.1 The nature of vectors

So far we have looked at only simple, linear data structures such as arraysand strings, and at classes. Well, I don’t want to change an ingrained habitso we will carry on looking at linear data structures, but shortly we shallget onto data structures of more exotic shapes. For the time being we aregoing to look at the notion of vectors in Java.

Mathematicians call vectors an ordered set of values, and physicists thinkof them as things with magnitude and direction (biologists think they arethings that spread diseases, but we don’t want to listen to them, do we). InJava a vector is an array that can grow and shrink. This idea is the same asin Standard Template Library (STL) in C++, but is not universal. Somelanguages refer to such data structures as flexible arrays and some forbidthem entirely.

18.2 The idea

A vector in Java is like an array which can be resized by adding elementsat either end or somewhere inside. Elements have the type Object, which isthe ultimate ancestor of all classes in Java. Hence one can create vectors ofany class since all classes are members of the class Object. An illustrationof various Vector operations is shown in the toy program below:

// Demonstration of the Vector class.

// First declare the utility classimport java.util.*;

// Now the class holding the main method

145

Page 146: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

146 CHAPTER 18. DATA STRUCTURES - VECTORS

public class VectorDemo1 {

public static void main(String args[]) {// Create a vector of 10 elements;// this is one Vector constructor

Vector v1 = new Vector(10);

// This is another way of doing the same thing.// If a Vector is created with// the default (no-argument) constructor then// it has 10 (potential) elements:Vector v2 = new Vector();

// Set element 0 of v1 to 27. Sorry, we can’t use [].// Notice value first, index second:// not what you’d expect.// Also we created a ten element vector// but we can’t use the elements// unless we insert them. I’ll explain later.v1.insertElementAt(new Integer(27), 0);

// Now we can use elementAt to get the value:System.out.println("Value 0 is " + v1.elementAt(0));

// Which surprisingly prints: Value 0 is 27

// So now we start our story:// once upon a time was Little Red Riding Hood,// who weighed 45.2 kilos and was 16 years old.// She was a scrawny little lass.Vector littleRedRidingHood = new Vector(10);littleRedRidingHood.insertElementAt(new String("Little Red Riding Hood"), 0);littleRedRidingHood.insertElementAt(new Float(45.2), 1);littleRedRidingHood.insertElementAt(new Integer(16), 2);

// Little Red Riding Hood was a Vector who// lived with her Mummy. Her birth certificate read:System.out.println(littleRedRidingHood.elementAt(0) + " "+ littleRedRidingHood.elementAt(1) +" " + littleRedRidingHood.elementAt(2));

// Which prints as: Little Red Riding Hood 45.2 16

Page 147: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

18.2. THE IDEA 147

// So, little Red Riding Hood met her mother (have// you ever wondered about people who ’meet their mothers’?// Surely mothers intrude, probe, infuriate, cook badly/well.// Have you ever ’met your mother’?// Maybe confronted, placated, lied to, confessed to. Oh well,// one can carry a parenthetical remark too far)// who said "Here I have a basket"Vector basket = new Vector(10);

// "I’m going to put a few prime numbers into it,// Granny loves primes"basket.insertElementAt(new Integer(3), 0);basket.insertElementAt(new Integer(5), 1);basket.insertElementAt(new Integer(7), 2);

// "Oh no"; one of them is very small. Here’s a bigger one"basket.setElementAt(new Integer(13), 0);

// "Now you hold onto it very firmly".littleRedRidingHood.insertElementAt(basket, 3);

// "Now take this to Granny. But watch out for the Big Bad Wolf".// So Little Red Riding Hood set off down the track// through the forest towards Granny’s house.

// SUDDENLY: out stepped a grey haired, whiskery fellow who said:// "Hello, little girl; who are you and what have you got there"System.out.println(littleRedRidingHood.toString());

// To which Little Red Riding Hood replied on her system console:// [Little Red Riding Hood, 35.2, 16, [13, 5, 7]]// "and I’m going to Grandma’s house", she added rather foolishly.// Now, of course, the whiskery fellow was a wolfish object:Vector bigBadWolf = new Vector(5);

bigBadWolf.insertElementAt(new String("long nose"), 0);bigBadWolf.insertElementAt(new String("big eyes"), 1);bigBadWolf.insertElementAt(new String("large teeth"), 2);

// and if Little Red Riding Hood had had the sense to say:System.out.println(bigBadWolf.toString());

// she would have seen: [long nose, big eyes, large teeth]// which would have saved a lot of trouble.

Page 148: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

148 CHAPTER 18. DATA STRUCTURES - VECTORS

// Anyway the wolf took the fast route to Grandma’s house.// Grandma was also, by chance, a Vector:Vector grandma = new Vector(3);grandma.insertElementAt(new String("Grandma"), 0);grandma.insertElementAt(new Float(85), 1); // She was rather fatgrandma.insertElementAt(new Integer(92), 2); // And quite old

// Without further ado the wolf gobbled up GrandmabigBadWolf.insertElementAt(grandma, 3);

// put on her bonnetgrandma = bigBadWolf; // poor Grandma

// and nipped into bed just before// Little Red Riding Hood arrived.// Little Red Riding Hood looked at the wolf and said:// "Oh, Grandma. What a long nose you have"; or in Java:System.out.println(grandma.elementAt(0));

// Which printed: long nose. Then she said:// "Oh, Grandma. What a big eyes you have"; or in Java:System.out.println(grandma.elementAt(1));

// which printed: big eyes. Then she said:// "Oh, Grandma. What large teeth you have"; or in Java:System.out.println(grandma.elementAt(2));

// which printed: large teeth.// Little Red Riding Hood fell back in fear// and the Big Bad Wolf jumped on her and was about to devour her// when the door flew open and in strode a woodsman object.// He’s lean and long so let’s make him a string:String woodsman = new String("wields an axe");

// (Now, here we have a narrative problem: we should have// introduced the woodsman earlier. He is an// important character but we don’t know much about// him. Let us suppose he is big and burly, high and hefty.// He is called MacTheKnife in an ironical reference// to his large axe. Readers who were born after the irony// age will not understand that last sentence;// others may think it Weill.// Personally, I don’t care.// )

Page 149: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

18.2. THE IDEA 149

// When he saw what was happening the woodsman// thought he should// throw an exception at the wolf, but because// we haven’t covered that yet// he bopped the wolf on the head with his mighty fist.// So the woodsman said:System.out.println(" " + bigBadWolf.elementAt(0) + ", "+ bigBadWolf.elementAt(1) + ", "+ bigBadWolf.elementAt(2));

// which printed: long nose, big eyes, large teeth.// Notice that he knows it’s a wolf and not a grandma.// "Hmph" said the woodsman. "There is more to this than meets// "the eye. I wonder how many elements this wolf has"System.out.println(bigBadWolf.size());

// Which printed: 4// "Ahah" said the woodsman. "an element more than expected".// So taking his axe he removed the long nose:bigBadWolf.removeElementAt(0);

// This was a safety measure; do not try this at home.// (Also, when he did his degree in Forestry he had taken a minor// in veterinary dentistry). Then peering down the wolf’s throat// he muttered "I want to see to the end of this". (You// should be so lucky, said the actress, but she is in// different joke). And he saw at the very extremity of the wolf:System.out.println(bigBadWolf.lastElement());

// which printed: [Grandma, 85.0, 92]// "Just as I thought", said the woodsman.// "There is a Grandma object in there".// "Just by chance I can see a Grandma reference here// so I can restore Grandma to her proper status"

grandma = (Vector)bigBadWolf.lastElement();bigBadWolf.removeAllElements();

// "Right ho", said the brave, burly forester.// "Now let’s check that everything// is as it should be"System.out.println( "Gran is " + grandma + "\n" +"girl is " + littleRedRidingHood + "\n" +"wolf is " + bigBadWolf);

Page 150: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

150 CHAPTER 18. DATA STRUCTURES - VECTORS

// which produces:// Gran is [Grandma, 85.0, 92]// girl is [Little Red Riding Hood, 35.2, 16, [13, 5, 7]]// wolf is []

// "Jolly good" said the brave woodsman. "Now, put the kettle// on love and let’s eat some of those primes you have// in your basket and let’s have a cup of tea".// At this Little Red Riding Hood thought: "Well, he ain’t PC// but the song says ’Stand by your Mac’".// So she put on the kettle, soothed Granny,// who was, quite reasonably, a bit ruffled, having had// a stressful day, and thought// to herself "Well, he’s a bit macho, but he has a nifty// way with wolves, and you can’t say that for all men.// And when you live in a forest it’s best to avoid those who are// hare today and gunned tomorrow".// And so they were married, lived happily ever after,// and had many kids, pups and whelps, which confused the// forester a great deal.//

try {System.in.read(); // prevent console window from going away} catch (java.io.IOException e) {}} // main} // VectorDemo1

Notes: Vector v1 = new Vector(10); Creates a vector which has up to 10elements. However, the elements don’t exist yet, they have to be createdone by one. Also the vector will be extended when necessary. You maywonder why we bother reserving 10 elements. Well this creates some spacebut doesn’t let you have it at the moment. The 10 suggests that this is asmuch space as you will want for this vector. Extending it is a fairly costlyoperation so it is a good idea to think about this number fairly carefully.Setting it too big will waste space, setting it too small will waste time.

v1.insertElementAt(new Integer(27), 0); Vectors are containers for ob-jects. If we want an array of one of the primitive types we cannot use vectorsdirectly because primitive types are not classes and therefore do not createobjects. What we do is use the wrapper classes for the primitive types. Inthis case we make an Integer object from an int value. insertElementAtinserts an element at a position in the vector and shuffles the remainder upby one. A better way might be to use addElement which adds at the end of

Page 151: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

18.2. THE IDEA 151

the vector.System.out.println(”Value 0 is ” + v1.elementAt(0)); ElementAt is used

to get the value of a particular element from a vector.(new String(”Little Red Riding Hood”), 0);etc. Notice that each element is a different type. This is allowed because

all classes in Java inherit ultimately from the super class Object. Vectorsare collections of Objects and so can contain objects belonging to differentclasses.

// Which prints as: Little Red Riding Hood 45.2 16Notice how all the different values have been converted into appropriate

text. All classes contain a method toString which can change an objectof the class to an appropriate string. For your own classes you can definethis method yourself. In a context where a string is expected, such as hereas the argument to println, the toString method can be called explicitly.basket.setElementAt(new Integer(13), 0);

The method setElementAt is used to change the value of an alreadyexisting element. littleRedRidingHood.insertElementAt(basket, 3);

Notice that basket is a vector which has been inserted into a vector. Thisis fine and can be carried on to any depth.

System.out.println(littleRedRidingHood.toString());The toString method has been included explicitly here purely to demon-

strate the point made in note 5.[Little Red Riding Hood, 35.2, 16, [13, 5, 7]]Notice how the vector within the vector is printed.bigBadWolf.insertElementAt(grandma, 3);Again we have a vector containing a vector.grandma = bigBadWolf;Both grandma and bigBadWolf are references to vectors and so can be

assigned to one another. In this case both grandma and bigBadWolf referto the same vector and so are said to be aliases for one another. Theoriginal grandma object still exists although it’s no longer referred to bythe grandma reference. Instead is inside bigBadWolf and is referred to bybigBadWolf.elementAt(3).

System.out.println(bigBadWolf.size());The size method of a vector gives the number of elements actually used

in the vector. Related methods are: isEmpty, which returns true if a vectoris empty; trimToSize, which trims the capacity of a vector to its currentsize; setSize, which alters the capacity either up or down (losing elements ifnecessary).

bigBadWolf.removeElementAt(0);removes the 0th element. Another, similar method is removeElement(Object

obj) which looks for obj in a vector and removes it if it there.System.out.println(bigBadWolf.lastElement());

Page 152: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

152 CHAPTER 18. DATA STRUCTURES - VECTORS

lastElement returns a reference to the lastElement in a vector. A similarmethod is firstElement.

bigBadWolf.removeAllElements();This method leaves a vector empty.Other methods on vectors include searching and copying vectors.

18.3 Vectors versus arrays

As vectors do more than arrays can, does this mean that we should prefervectors as a matter of course? Arrays have a fixed size; for example, whilevectors can grow and shrink. However, this is at some cost: vectors areslower and require more storage space than arrays.

As a general principle, if you require a collection of things that is notgoing to change size after creation then use an array. Use vectors when thesize of your collection is dynamic, but not too dynamic.

The methods insertElementAt and removeElementAt are particularlyexpensive because they require existing elements to be shuffled up or down.These methods take time O(n) for a vector of n elements. If your programis making heavy use of these methods then you may need to switch to thelist data structure which we shall look at later. Lists have the importantproperty that insertion and deletion of elements takes constant time. Onthe other hand, arrays and vectors take constant time to access an elementby its index, but lists take linear time (i..e. O(n)). It is for this reason thatarrays and vectors are called random access data structures.

18.4 Enumerations

A Java enumeration is an example of an interface and is used to iteratethrough successive values of a collection. It is very similar to the iteratorclasses used in C++ and the standard C++ template library STL. It is calledan interface because it defines a set of method behaviours which you candefine for any of your own collection classes. Most of the standard collectionclasses, such as Vectors, have already defined the enumeration interface forthemselves. When I say an interface such as Enumeration defines ”a setof method behaviours” I mean it defines method prototypes (the first lineof the methods with all the arguments etc.) and a description, in words,of what the methods do. An interface does not define HOW the methodsare implemented. That is up to each class to do. However, by stickingto the Enumeration interface every Java programmer knows how to usethe enumeration for any class. In other words, interfaces exist to enforceconsistency.

The two methods that must be implemented for an Enumeration arehasMoreElements and nextElement. These are defined as follows:

Page 153: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

18.4. ENUMERATIONS 153

boolean hasMoreElements();

returns true if there are any more elements in the calling enumeration object.

Object nextElement();

returns the next object in the calling enumeration. The next call will returnthe next object, and so on.

The following code fragment shows how to use an Enumeration on aVector. It puts a (not very significant) list of values in a vector and thenprints them by using an enumeration on the vector .

Vector myVector = new Vector(10);

// Fill with numbersfor (int i = 0; i <= 10; i++)myVector.addElement(new Integer(i*i - 5));

Enumeration en = myVector.elements();while(en.hasMoreElements()){System.out.println(en.nextElement() + " ");}System.out.println();

This outputs:

-5 -4 -1 4 11 20 31 44 59 76 95

Now, these numbers may look uninteresting, but be tolerant; they aredoing their best. So here are the interesting bits:

Enumeration en = myVector.elements(); Creates an enumeration whichstarts at the beginning of all the elements of myVector. The elementsmethod of a vector gives a reference to an enumeration starting at the firstelement of the vector.

en.hasMoreElements() Delivers true as long as en has more elements(surprise?)

en.nextElement() delivers the next element of en and arranges thingsso that the next time it is called it will deliver the next element of en.If you try to get an element after the last then it throws an exceptionNoSuchElementException.

Page 154: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

154 CHAPTER 18. DATA STRUCTURES - VECTORS

Page 155: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 19

Merging sorted lists - Afundamental algorithm

19.1 Introduction

So far you have seen classic algorithms for searching and sorting; later youwill see more sophisticated versions. Now we shall look at a fundamentalalgorithm for merging two lists of sorted values. This is called two-waymerging. Ways of merging several lists are called multiway merges.

In practical applications the lists being merged might be arrays, Vectors,files or any other data structure that can yield a sequence of ordered values.Here we will use arrays, mainly because they are easy to use.

19.2 Merging lists

Now we come to a Real Life Algorithm (RLA). This RLA you could easilywork out for yourself. This may not be true for some of the later ones welook at. The problem is to merge two sorted lists. We will, as usual, dealwith integers because they are very simple. The same procedure applieswhatever the elements of the list comprise. All that is needed is that we candefine the relationship less-than for whatever classes of object we are using.

To illustrate the problem, look at the lists below, which go part waythrough the merging process:

The algorithm should be obvious from the diagram. The circles showthe next item to be moved, the rectangles the elements already moved. Thetrick is to turn it into code.

The next program shows the merge algorithm applied to arrays of ints.

int list1[] = {1, 3, 5, 8, 9, 11, 13},list2[] = {2, 4, 6, 8, 10};int target[] = new int[list1.length + list2.length];

155

Page 156: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

156CHAPTER 19. MERGING SORTED LISTS - A FUNDAMENTAL ALGORITHM

// Merge list1 and list2 into targetint i = 0, j = 0, k = 0;while (i < list1.length && j < list2.length)target[k++] = list1[i] < list2[j] ? list1[i++] : list2[j++];

while (i < list1.length)target[k++] = list1[i++];

while (j < list2.length)target[k++] = list2[j++];

for (k = 0; k < target.length; k++)System.out.print(" " + target[k]);System.out.println();

Producing the result:

1 2 3 4 5 6 8 8 9 10 11 13

Notes:

while (i < list1.length && j < list2.length)

This loop will run until either of the two arrays is exhausted.

list1[i] < list2[j] ? list1[i++] : list2[j++]

Notice the ? : operator (SAQ: can you remember what it does?) It isimportant to realise that only i or j get incremented, but never both.

The two while loops are for copying the remaining elements from the listthat has not been exhausted. Only one of these loops will execute (SAQ:can you see why?)

Page 157: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 20

Recursion

”To iterate is human, to recurse divine” - Alan Perlis

20.1 Introduction

Recursion is one of the most interesting concepts in programming. It in-volves an idea of such power and originality that whole books and computerlanguages are built around it. I once heard a well known computer scientistclaim that all people can be divided into those who are able to understandrecursion and those congenitally incapable .

20.2 Worked example - Euclid’s algorithm

Cast your mind back to earlier where you saw a method for implementingEuclid’s algorithm for calculating the highest common factor of two numbers.To save you looking back I’ll refresh your memory:

public static int euclid(int a,int b) {int c;do {c = a % b;if ( c !=0) {a = b;b = c;}} while (c != 0);return b;}

The algorithm, when calculating the HCF of 3654 and 1365, calculatesthe remainder when the first is divided by the second (924) and then repeats

157

Page 158: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

158 CHAPTER 20. RECURSION

the process with 1365 and 924, then 924 and 441, then 441 and 42, then 42and 21. The remainder is 0 so the answer is 21.

Think of this algorithm as making the following sequence of postulates:HCF(3654, 1365) = HCF(1365, 924) HCF(1365, 924) = HCF(924, 441)

HCF(924, 441) = HCF(441, 42) HCF(441, 42) = HCF(42, 21)At each step Euclid’s algorithm replaces one problem by a simpler one.

Thus the first line says:HCF(3654, 1365) = HCF(1365, 3654 = HCF(3654 = HCF(1365 = . . .Notice that at each stage the HCF of one pair of numbers is defined in

terms of the HCF of a smaller pair. In general we can say that:HCF(a, b) = HCF(b, aThis defining of the function in terms of itself works fine but it has to

stop somewhere. This happens when b is zero, when we know the answer isa. So we can write:

The HCF of a and b is: if b is 0 the answer is a otherwise the answer isthe HCF of b and a

Mathematicians frequently use such definitions. They are said to berecursive. Such definitions can be written in Java. The above methodbecomes deceptively simple:

public static int euclid(int a, int b){if (b == 0)return a;elsereturn euclid(b, a % b);}

Notice how much simpler this is than the original version. It is not onlysimpler, it also expresses the idea behind Euclid’s algorithm more elegantlyand clearly. It can be even simpler; can you rewrite it using only one returnstatement and no if statement. The answer is in the footnote but try itbefore looking:

All loop control structures can be replaced by recursion. In fact, inthe language Lisp and its dialects such as Scheme, there are no loopingcontrol structures; everything is done using recursion. Does is imply thatwe should now throw away our Java loop statements? Well, sometimes aloop statement is much simpler to understand than an equivalent recursivesolution. For example, earlier we put ten integers into a vector using thestatement:

for (int i = 0; i <= 10; i++)myVector.addElement(new Integer(i*i - 5));

Now this is very clear and simple. We just want to do something tentimes so we use a loop designed for the job. Another issue is efficiency;

Page 159: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

20.2. WORKED EXAMPLE - EUCLID’S ALGORITHM 159

recursion can be expensive in both space and time. This is a complex is-sue which we will study a little later. For now we shall try to master thetechnique of recursion.

Well, I managed not to introduce recursion using the most boring exam-ple in the world; the one that is always used as the first example. So nowis the time to do it. Here is The factorial. As you learned in school thefactorial of, say, 5 is 5x4x3x2x1 which is 120. Mathematically, the factorialof a number n is written as n!. Now one way to think of n! is to say it is theproduct of n and the positive integers below n. This leads to the followingfactorial method:

public static int factorial(int n){int result = 1;while (n >= 1)result *= n--;return result;} // factorial

which gives the value 3628800 for an argument of 10. This method ispretty well a straight expression of the factorial definition above and worksefficiently. Now look at another way of defining factorial.

Given that 5! = 5.4.3.2.1 and 4! = 4.3.2.1 it is clear that we could write5! as 5.4!. Now we have just defined 5! in terms of 4!. So taking an inductiveleap we can see that n! is just n.(n-1)!. This is clearly recursive and like theEuclid problem gives us the worry of when do we stop? We need to thinkabout what the smallest value of n might interest us. Well, we could choose5 because we know the answer; it is 120. But 5 seems too large becausewe might want 4! or whatever. As factorials only seem to make sense fornon-negative numbers the smallest possible values of n would seem to be 0!or 1!. 1! is obviously 1, but could we go that extra step and handle 0!? Itwould be nice but at first blush doesn’t seem to make much sense. However,mathematics does not always make obvious sense. It can be shown that 0!is, bizarrely, 1.

So now we have a definition for factorial similar to that which we gavefor euclid. Writing in the same manner we have:

The factorial of n is:if n is 0 the answer is 1otherwise the answer is n times factorial(n - 1)

We can put this into Java as:

public static int factorial(int n){if (n == 0)return 1;

Page 160: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

160 CHAPTER 20. RECURSION

elsereturn n*factorial(n - 1);} // factorial

Notice again how closely this piece of program code resembles the originaldefinition. In the same spirit try to recast it with no if statement and onlyone return. Try it before looking at the footnote .

Now, this recursive way of calculating factorials is very inefficient, unlikethe recursive Euclid algorithm, which is not too bad. You must be gettingtired of reading this but you will see why this is so later. Be patient.

Many ’real world’ things have a naturally recursive nature. For example,trees are made of branches that are really little trees, which themselves aremade of smaller trees; natural languages contain grammar rules for suchthings as noun phrases which can contain noun phrases and so on; compli-cated moves in a game are made of simpler moves that follow some set ofrules.

20.3 The Tower of Hanoi

As an example of a problem where recursion is of the essence to finding agood solution we will look at the classic Tower of Hanoi problem. There arenon-recursive solutions to this problem but, personally, I would have foundit difficult to find them without understanding the recursive solution first.

The problem was stated as a puzzle in Scientific American in the firstfew years of this century. It is also a child’s game. There are three rods (inthe ’dramatic’ version they are diamond needles) and a set of (golden) discsall of different sizes. The discs are piled on one of the rods, largest at thebottom, smallest on top. In the original statement there are 64 discs but wedon’t want to deal with anything like that many. Here is a picture:

As you can see, to move two discs from peg 1 to peg 3 one must do:

Move 1 to 2Move 1 to 3Move 2 to 3

This sequence is what is shown in the pretty piccies. Now, as an exercise,work out what would be the next moves to end up with three discs on peg2. Now four discs on peg 3? Now work out the system.

You will easily see that to move several discs from one peg to anotherwe use the third peg as a sort of work space. We shall call this the auxiliarypeg.

Perhaps you can now perceive a principle: suppose we want to move fivediscs from peg 1 to peg 3; we move four discs (following the rules, of course)from pegs 1 to 2, then one from peg 1 to 3, then four from peg 2 to 3. Make

Page 161: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

20.3. THE TOWER OF HANOI 161

sure you understand this before the next paragraph, because here looms theGreat Inductive Leap (GIL) that always comes with this type of problem.We have just handled the five disc problem in terms of four discs, clearlywe could handle the three disc problem in terms of two, and two in termsof one. One is trivial.

Right, here’s the GIL: to move n discs from peg 1 to peg 3 we move n -1 to peg 2, then one to peg 3, then n - 1 from 2 to 3. How do we move then - 1? Well, of course, we move n - 2 from peg 1 to peg 2, then . . . Gotit? We can take a problem that involves n steps and reduce it to a problemthat involves n-1 steps. We realise that the end of this is a problem that is1-step, and any fool can solve that problem, so we can solve all versions ofthe problem. VOILA. we are n-talented creatures with regard to the Towersof Hanoi problem.

I’m sure you can all turn this into the five line program it is, but just tosave you the effort here is the solution in living Java:

public static void hanoi(int n, int fromPeg, int toPeg, int auxPeg){if (n == 1)System.out.println("Move from " + fromPeg + " to " + toPeg);else{hanoi(n - 1, fromPeg, auxPeg, toPeg);System.out.println("Move from " + fromPeg + " to " + toPeg);hanoi(n - 1, auxPeg, toPeg, fromPeg);}} // hanoi

Given the call:

hanoi(4, 1, 2, 3);

it produces the output:

Move from 1 to 3Move from 1 to 2Move from 3 to 2Move from 1 to 3Move from 2 to 1Move from 2 to 3Move from 1 to 3Move from 1 to 2Move from 3 to 2Move from 3 to 1Move from 2 to 1Move from 3 to 2Move from 1 to 3

Page 162: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

162 CHAPTER 20. RECURSION

Move from 1 to 2Move from 3 to 2

Do you not think it rather wonderful how a few lines of program cangenerate as many moves as we need to solve a problem to which the solutionis not obvious? There are ways, I have seen one delightfully simple one buthave lost the reference, of solving this problem without recursion. Never-theless, recursion opens up the problem and reveals its interior working ina very pretty way. And, as I mentioned earlier, I would never have founda different solution without the insight that I get from understanding thisrecursive version.

As a codicil, I was once at a meeting where one of the guest speakerswas Douglas Adams, he of ”The Hitch-hiker’s Guide to the Galaxy”, whichis, as all right thinking people know, the strangest thing since sliced bread.(By the way, it was originally a radio series, the books are a pale imitation).Mr Adams is an English literature graduate. Anyway, he was a fan ofHypercard on the Mac and had taught himself to program in Hypercard.He produced a fully animated solution to the towers of Hanoi problem whichwas excellent. He said he felt diffident about producing this in front of anaudience of computer science professionals, but he thought it said somethingfor his software that he, an Eng. Lit. type, could produce this thing at all.I thought it said a great deal about Douglas Adams.

Page 163: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 21

Quicksort

21.1 Divide and conquer algorithms

In 1960 the language Algol60 introduced the idea of recursion and C.A.R.Hoare took the advantage of this new language to propose a new sortingalgorithm. So far you have seen selection sort, which is an O(n2) sortingalgorithm. For a while after the start of computer programming all sortswere like that. A major innovation was Shell sort but then Tony Hoareproduced quicksort, primarily as a means of showing an application of re-cursion. Quicksort is O(n.lg(n)) and with slight modifications is the fastestalgorithm known for sorting an array without using extra memory.

The algorithm falls into a class known as ’divide and conquer’ algorithms.These all solve a large problem by dividing (usually halving) it repeatedlyand then somehow merging the many separate small results into one com-plete solution. Applied to sorting, we have seen algorithms that take O(n2)steps to sort an n item list. If we were to halve the size of the list we wouldneed one quarter the number of operations. So, it we could halve the list,sort the two halves and then find an efficient way to combine the resultswe ought to be able to achieve some improvement. If we were to halve thehalves we may be able to do even better. If we were to halve the quarters...When you see this type of argument you can guess that recursion is in theair. You have already seen one divide-and-conquer algorithm in the binarysearch of a sorted list.

21.2 The Quicksort algorithm

As usual we shall use an array of integers, but the method works for sortingany data types. The idea is to choose a value, called the pivot, which we hopewill be roughly in the middle of the range of values in the array. We thenpartition the array so that the lower portion contains values lower than thepivot and the upper contains larger values. This operation can be repeated

163

Page 164: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

164 CHAPTER 21. QUICKSORT

on each partition and so on. Let’s look at some pictures:Notes:The lines indicate where the partitioning has taken place and the num-

bers in circles are the pivot values. Notice that the pivot values are notalways values that are in the array. There is no need they should be. I havecheated in coming up with pivot values that are probably a bit too good.This makes the diagram easier to follow.

Once a partition becomes sorted I have not carried on partitioning. Inpractice partitioning carries on down to single elements. Again I left thisout to stop the diagram becoming too fussy.

Look at the first row above and try to see how the partitioning occurred(assuming a message from heaven gave the pivot value). The partition al-gorithm for one step is:

Choose a pivot; Start at the left and find a value greater than or equalto the pivot; Start at the right and find a value less than the pivot; Swapthose two values;

In pseudo-code the quicksort algorithm is:

void quicksort(int theArray[]) {if (theArray.upb > theArray.lwb){partitionTheArray(theArray, lowerPartition, upperPartition);quicksort(lowerPartition);quicksort(upperPartition);} // if} // quicksort

It is important to realise that the program above is not written in anyreal computer language. There was once a movement to create a standardlanguage called ”In Abstracto” wherein programmers could put their algo-rithms together without worry of particular language rules. It never reallytook off, but all good programmers have their own version. One should tryto think of algorithms at a level above that of primitive languages such asJava.

Returning to quick sort. To sort an array of integers the following methodcan be used:

an element in the array. The technique here is to use the average of thetop and bottom elements of the array. There is a lot to choosing pivot valuesand we shall discuss it later. The indices i and j are given values outside therange to begin with. This is because the while statement pre-increments iand pre-decrements j. There is no body to the while statements; they justincrement i and decrement j until values are located which need swapping.The simplicity of these statements contributes in no small way to the speedof quicksort. Once the partitioning is complete the values of i and j willhave crossed over. Notice the use of break to escape when partitioning iscomplete.

Page 165: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

21.3. CHOOSING PIVOTS 165

If the array elements are not numerical, for example strings, then wecan’t choose the average of the top and bottom values. In that case thepivot value will be an actual element in the array. What we do is choosethe value of some element as the pivot; a simple strategy is to use the righthand element.

static void quicksort(int theArray[], int left, int right){int pivot, i, j, temp;if (right > left){pivot = theArray[right];i = left - 1;j = right;for (;;){while (theArray[++i] < pivot); // scan from leftwhile (theArray[--j] > pivot && j > left); // scan from rightif (i >= j) break;temp = theArray[i]; // swap valuestheArray[i] = theArray[j];theArray[j] = temp;} // for// Put the pivot backtemp = theArray[i];theArray[i] = theArray[right];theArray[right] = temp;// Notice the pivot is left out from the remaining sortsquicksort(theArray, left, i - 1);quicksort(theArray, i + 1, right);} // if} // quicksort

The programming has been altered a little. As the pivot is the rightmostelement it is moved, after the partitioning, to the position between the twopartitions. The two subordinate sorts do not include this element becauseit is already at its correct place.

21.3 Choosing pivots

The problem of a bad choice of pivot is made very clear if you consider whatwould happen if we chose the left-most element of the array? Suppose theoriginal array is already in order. Then the partition process would selectelement 0 as the pivot point, the left partition would have no elements andthe right partition would have n - 1 elements (n is the number of elementsin the array). In this case there would be n recursive calls of quicksort thefirst with an array of n elements, the next for n - 1 and so on. We would

Page 166: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

166 CHAPTER 21. QUICKSORT

end up doing almost n2 comparisons, so our super fast algorithm would beno faster than the selection sort you saw earlier. As it is quite likely thatthe input may be in order, or almost so, the left element would be a lousychoice of pivot.

In the example above we chose the right element as pivot. Now clearlythis would be just as bad if the input were in reverse sorted order, but thatis less likely so the program above may not behave too badly.

Another approach would be to choose an element at random. This wouldbe very unlikely to behave badly; the probability of repeatedly hitting theworst possible pivots is very low. This approach is not approved of because,it is argued, repeatedly calculating random numbers would be expensive.

A favoured approach is called ’median of three’ pivoting. The idea isto choose three values from the array, usually the first, last and the middleones, and then choose as pivot the middle valued one. This gives close tooptimal performance. For example, if the array were:

{5, 3, 7, 1, 4, 9, 0, 6}

the values chosen would be 5 (first), 6 (last) and 1 (middle). As 5 is themiddle of these three then we would choose 5 as the pivot.

21.4 Performance of Quicksort

I mentioned earlier that quicksort is O(NlgN). In fact Sedgewick showsthat on average the number of comparisons will be 2N.ln(N) and that thisis only 38% short of the best case. To get a feeling for what this meanssuppose N is one million. Then selection sort would need roughly 1012operations where quicksort would require roughly 107 operations. This is100,000 times faster. Suppose quicksort could sort 1,000,000 items in oneminute; selection sort would take something like 70 days for the same job!

21.5 Further improvements

Quicksort is probably the best analysed algorithm used. Many people haveanalysed its best case behaviour, its worst case behaviour and its average be-haviour. There have been mathematical analyses which predict its behaviourand there have been experimental analyses which confirm the mathematics.Quicksort is a very good algorithm.

Page 167: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 22

Linked lists

22.1 Dynamic data structures

The Vector data structure has a degree of dynamism; this means that thedata structure can grow or shrink during use. We saw methods for addingand deleting elements. However, this is at some cost: inserting an elementrequires that elements above the insertion point must be moved up anddeletion requires that they be moved down. On a large vector this can bevery expensive.

A further overhead is the extra capacity built into vectors to reduce thecost of allocating more space. Vectors have the advantage that they arerandom access (it takes the same time to refer to any element) so they areideal for situations where rapid access is important and the frequency of sizechange is low. Often, however, we want data structures which can grow andshrink cheaply, maybe to the detriment of time in referring to elements. Thesimplest such data structure is the linked list.

22.2 A simple linked list

The essence of dynamic data structures is the generation of elements onlyas they are needed and the joining together of these elements by using refer-ences (other languages use pointers for this, but the Java technique is moresecure).

The next diagram illustrates a linked list holding an ordered set of in-tegers; the list consists of nodes (the outer boxes) with each node holdinga value and a link to the next node in the list. The links are references,which is why each one on the diagram is marked with an asterisk. Theearth (ground) symbol at the end of the list denotes the value null, which isconventionally used to terminate a list, and Root is a reference to the startof the list.

167

Page 168: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

168 CHAPTER 22. LINKED LISTS

A common use of linked lists is to hold a set of values with insertion atthe beginning. We will start of with a simple version. The basic class is:

public class ListNode{int value;ListNode next;

ListNode(int newValue, ListNode link){value = newValue;next = link;} // ListNode} // ListNode

Notice it has a value and a reference to the next element. Its one con-structor makes a ListNode. Using this is illustrated by:

public static void main(String args[]) {ListNode root; // Makes the root referenceroot = new ListNode(3, null); // The list now contains one element

System.out.println("First element is " + root.value);// Which prints: First element is 3

root = new ListNode(13, root);// Puts a new element in front of listSystem.out.println("First element is now " + root.value);// Which prints: First element is now 13

// To print everything we use:System.out.print("Whole list is [");for (ListNode tracer = root; tracer != null; tracer = tracer.next)System.out.print(" " + tracer.value);System.out.println("]");// which prints: Whole list is [ 13 3]

try {System.in.read(); // prevent console window from going away} catch (java.io.IOException e) {}} // main

This illustrates the basic idea. Now this version is awkward: we effec-tively put the elements in by hand and printing is not part of the class. Weneed to build these into a class to encapsulate all this functionality. Here itgoes; it uses the ListNode class defined above:

public class LinkedList{

Page 169: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

22.2. A SIMPLE LINKED LIST 169

ListNode start;

LinkedList(){start = null;} // LinkedList

public void addElement(int v){start = new ListNode(v, start);} // addElement

public String toString(){String result = "[";ListNode tracer = start;while (tracer != null){result += tracer.value;tracer = tracer.next;if (tracer != null)result += ", ";}return (result += "]");} // toString} // LinkedList

Note:There is one constructor without any argument.The method addElement puts a new ListNode at the start of the list,

making it up from an integer. If any class provides its own method toStringwhich takes no argument and delivers a String, the method will be calledwhenever the context requires a String. You will see how this is used shortly.

The method toString takes elements from the list one at a time. Theway this is done lies at the basis of most list processing programming. Thediagram illustrates how it works. After the line: ListNode tracer = start;the situation is:

with tracer referring to the first element of the list. So when we writeresult += tracer.value; we convert the first element of the list to a Stringand append it to result. Then the statement tracer = tracer.next; createsthe situation:

so that tracer has moved on one element. This carries on until we havethe situation in the diagram below. At this point the value of tracer.nextwill become null. The expression tracer != null in the while statement nowis false and the loop stops.

This illustrates two important things about linked list data structures:The insertion of a new element at the front of the list takes only one step(unlike with Vectors). Processing the list (as in toString above) generally

Page 170: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

170 CHAPTER 22. LINKED LISTS

starts at the beginning of the list and moving down it. In fact, it takessignificant effort to process a linked list any other way (again unlike Vectors).

There is a lot to lists; later we shall look at modifying the above classto implement a stack, one of the most useful data structures. Lists can beused merely to collect together objects, but they constitute the basis of avery important group of languages based on Lisp. Lisp, and its relativesCommon Lisp and Scheme, are the basis of a very large part of the work onartificial intelligence (AI), and are based on the idea that anything we wantto work with can be represented as lists (of various degrees of complexity)and the use of recursion.

Try thinking of the operations (methods) you would want to add to alist class to make it really useful. Write them down without worrying howto implement them.

Page 171: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 23

Binary search trees

23.1 Tree terminology

The next dynamic data structure we shall look at is the binary search tree(BST). This finds an enormous range of applications because it provides afast way of storing and accessing information, particularly information thatchanges constantly while you are using it. There was once a period in mylife when almost every program I wrote involved a BST.

Trees in general occur in many places other than gardens. Thus the ge-nealogy of families is frequently represented as a tree. Computer file struc-tures, structured documents, organisational hierarchies, class inheritancestructures in Java, are all tree-like. A general tree is shown below:

Some terminology:

• A, B, C, D, E and F are all nodes of the tree.

• A is the root of the tree.

• B, C, D, E are all children of A.

• A is the parent node of B, C, D, E.

• The arrows are called edges.

• F, G, C, D, H have no children. They are called leaves.

A tree is a specialised form of a graph. Graphs can be any network ofedges and nodes (the Paris Metro map is a graph). A tree is a graph whereall the edges are directional (that’s what the arrows signify) from parent tochild and where every child has only one parent node.

The tree above is not binary (A has four children). Applications ofgeneral trees will emerge later, but for now we will restrict ourselves tobinary trees (no more than two children per parent) and in particular BSTs.

171

Page 172: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

172 CHAPTER 23. BINARY SEARCH TREES

23.2 Binary search trees

BSTs are binary trees with a special ordering property illustrated in thediagrams below. Can you see what the property is? The trees have depths ofthree, four, four and six. This issue of depth is very important when dealingwith the efficiency of operations on trees. A tree that is completely filledfrom left to right except, perhaps, for the bottom level, is called complete.A tree where the left and right children of every node have heights differingby no more than one is said to be height-balanced or simply balanced. Thefirst tree below is balanced. The last one is a degenerate case which isas unbalanced as it can possibly be. In general we want our trees to beas well balanced as possible. Sometimes it is satisfactory to leave this tochance but sometimes we need to take definite action to balance a tree. Theusual algorithm for this was devised by the two Russian mathematicians M.Adel’son-Vel’skii and E.M. Landis and such trees are called AVL trees. Thealgorithm can be found in any data structures book.

Now some theory. For a full BST of depth D fill in the table below forthe number of nodes at level D and the total number of nodes in the tree:

D Nodes at level D Total nodes in tree1234567

Give a formula for the number of nodes at level DGive a formula for the total number of nodes including level DGive a formula for the depth of a full tree with N nodesFor a tree containing 64,000 nodes a well balanced BST can be searched

from top to bottom in about 16 steps; for such a tree that is perfectlyunbalanced it will take 64,000 steps. Clearly a well balanced BST gives usan extremely efficient way of storing data with respect to search time.

23.3 Building binary search trees

The easiest way of seeing how to build a BST is to regard a tree as a root,and then a left tree and a right tree. The left tree is a tree with a left treeand a right tree. The right tree also is a tree with a left tree and a righttree. By now you should be seeing a formula and thinking: ”It’s recursion”.

A simple, recursive algorithm for inserting an element in a BST is:

Page 173: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

23.3. BUILDING BINARY SEARCH TREES 173

void insertInTree(thing newValue, Tree root){if (newValue > root.value)add newValue in right subtree;else if (newValue < root.value)add newValue in left subtree;} // insertInTree

We are going to have to modify this simple version to cope with the rulesof Java; it is interesting that C, although very close to Java, needs almostno modification to the above algorithm.

To see the algorithm, and why we need to complicate it a little, considerinserting 5 in the tree shown below:

The first picture shows where 5 needs to go and the second shows it inplace. Notice that every new node has to go at the end of a null reference(they are the lines that don’t have numbers at the end).

Let’s follow the steps down from the root to where we insert 5; in thepseudocode version of the algorithm we start at 7 and the piece of program:

. . .else if (newValue < root.value)add newValue in left subtree;

moves into the left sub-tree of 7, the tree starting 4. At this point weget:

. . .if (newValue > root.value)add newValue in right subtree;

Well, this looks simple except that the right sub-tree of 4 is null. Whatwe need to do is stop at 4, and before following a child edge check whetheror not it is null. We can do this by adding an extra test so that we have(this is from the final, Java version):

if (right == null)right = new TreeNode(v);elseright.addElement(v);

You see that before pursuing an edge we check to make sure it leadssomewhere. If it doesn’t then this is where the new node has to go.

Page 174: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

174 CHAPTER 23. BINARY SEARCH TREES

23.4 Traversing trees

In the tree above (the one with 7 as the root) imagine a banana hangingwhere each number is. At the root of the tree sits a very consistent monkey.He wants to get all the bananas but he wants to be tidy about it; he wantto get them in a regular pattern. Being such a stickler for patterns he musesover the following possibilities:

1. I can eat the banana here at 7, then go left. I repeat this as often asI can until I reach a leaf. I then climb down one level and do the same onthe right. This will give me the bananas in the order 7, 4, 1, 5, 9, 10. As Iget gratification first I shall call this pre-order traversal.

2. I can explore the left tree first, always postponing gratification untilthe latest time possible on the left. Then I eat the banana and then godown and do the same on each of the right sub-trees. This will give me thebananas in the order 1, 4, 5, 7, 9, 10. As I get gratification in the middle Ishall call this in-order traversal.

3. I can eat the banana where I am last. First I go to the left sub-tree,then to the right sub-tree and then I eat the one here. I only eat a non-leafbanana after I have eaten both sub-trees. This will give me the bananasin the order 1, 5, 4, 10, 9, 7. As I get gratification late I shall call thispost-order traversal..

All these tree traversal methods are valuable in different circumstances.In-order traversal is obviously useful because it generates the elements inincreasing order. The other two have valuable applications which you willsee later.

Coda: The Monkey’s student came up to him and said ”But teacher,you only came up with three traversal methods but I can see six you alwayswent left before going right, but if you also allow going right before goingleft you could have six traversal methods in all”.

The Monkey picked up a folded copy of the Times Higher-EducationSupplement and whacked his student on the ear. ”That is called a trivialchange and is not interesting; don’t do it again”.

Then another student came up and quoth thus: ”But you don’t need tobe consistent: you could go left at one stage and right the next; you couldpick any route you like, so what is so special about these three?”

The Monkey gave a withering look to this student. ”You are not evenworth risking damage to my TH-ES. Get thee to the literature departmentwhere they like otiose questions and never darken my banana tree again”.

23.5 Writing that in Java

There is a discussion of BSTs in D&D, section 17.7. The example below ismy own, but turns out to be very similar. First we define a class for a node

Page 175: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

23.5. WRITING THAT IN JAVA 175

of a tree:

// Tree, example 1: DM 1998.

public class TreeNode{int value;TreeNode left, right;

TreeNode(int newValue){value = newValue;left = right = null;}

public void addElement(int v){if (v < value)if (left == null)left = new TreeNode(v);elseleft.addElement(v);else if (v > value)if (right == null)right = new TreeNode(v);elseright.addElement(v);// else v is already in the tree.}}

First it declares the instance variables: the value stored in the node andthe two left and right references. Notice the recursive routine which can puta TreeNode into a tree of TreeNodes. Can you follow the logic in detail?

There is also a simple constructor to make a new TreeNode.To make things easier we don’t use TreeNode directly; instead we hide

it behind a BST class. This hides ugly implementation details from a user.The BST class is:

public class BST{TreeNode root;

BST(){root = null;}

public void insert(int v){

Page 176: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

176 CHAPTER 23. BINARY SEARCH TREES

if (root == null)root = new TreeNode(v); // First entryelseroot.addElement(v);}

private void inOrderTraversalHelper(TreeNode start){if (start != null){inOrderTraversalHelper(start.left);System.out.print(" " + start.value);inOrderTraversalHelper(start.right);}}

public void inOrderTraversal(){inOrderTraversalHelper(root);}

}

Apart from the traversal method these routines simplify the interfaceto the methods in TreeNode. For example, inOrderTraversal removes theneed for an argument; it just calls inOrderTraversalHelper with the root asan argument. This use of helper methods (functions/procedures/routines)is very common. One often provides a method that is easy to use andthen which calls a helper that has more arguments and which requires moreknowledge of internal details. Helper methods are not meant to be calledby users; that is why inOrderTraversalHelper is not public.

We now need a test harness:

public class BSTTester {

public static void main(String args[]) {BST testTree = new BST();

testTree.insert(7); // That’s the roottestTree.insert(4); // That’s lefttestTree.insert(5); // That’s left and righttestTree.insert(1); // That’s left & lefttestTree.insert(9); // That’s righttestTree.insert(10); // That’s right & righttestTree.inOrderTraversal();

try {

Page 177: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

23.6. ANOTHER WAY OF REPRESENTING TREES 177

System.in.read(); // prevent console window from going away} catch (java.io.IOException e) {}} // main} // BSTTester

23.6 Another way of representing trees

The way we have used for representing trees is fine when trees have to berepresented in memory and need to grow. Sometimes we don’t need to growa tree or perhaps we want to write it to a file. As an example, consider thetree above. This can be represented as a vector in the following way:

The first element of the vector is the root of the tree. For any node atposition in the left child is at 2n+1 and the right child is at 2n + 2. Theasterisks indicate empty nodes. If the tree were complete there would be noasterisks.

This representation is very simple and efficient but does not allow easychange of the tree. It is rare that one has a tree in memory that one doesnot want to change but as a means of storage of a tree on an external file itis hard to beat.

Page 178: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

178 CHAPTER 23. BINARY SEARCH TREES

Page 179: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 24

Hash tables

24.1 Introduction

In the last chapter we looked at binary search trees which offer a way ofstoring data in such a way that it can be efficiently recovered. In fact, for awell balanced tree, the method is O(lgn) with respect to finding an element.It also has the advantage of being easy to update: we looked at insertion;the deletion algorithm is more complicated but is still very efficient.

For a balanced BST with 8 million elements we can find an elementin about 22 comparisons. While this method is fast it is not the fastestpossible. We could do the thing in almost constant time and in as manysteps as we are willing to accept using a hash table. For example, if youdecide you would be willing to accept 3 comparisons you can design a hashtable to serve your need. This is obviously a Big Idea. It is also very counter-intuitive: it depends upon a degree of randomness in the representation - infact the more random the better.

24.2 The Dictionary abstract class

Any database management system is just a way of finding an element basedon a key. Java has an abstract class to serve this purpose: Dictionary. Adictionary defines an interface (the things a Dictionary must provide). Itdoes not actually implement those things though; users can provide anyimplementation they like. A Hashtable is an implementation of Dictionaryprovided by all Java systems.

The main methods provided by a Dictionary are:

Object put(Object key, Object element)

Object get(Object key)

179

Page 180: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

180 CHAPTER 24. HASH TABLES

Object remove(Object key)

int size()

boolean isEmpty()

The meanings of these should be fairly obvious. A couple of others aredescribed in D&D. Before we discuss the Java Hashtable class, which isan implementation of Dictionary, it would be a good idea to explain theessential ideas behind hash tables.

24.3 Hash tables

A key to a database can be something simple like a number (e.g. a socialsecurity number), fairly complex (e.g. a string) of highly complex (e.g. anentire record). Now a table is really just an array indexed by integers so whatwe need is some method of mapping a key to an integer. The important, ifsurprising, thing to realise about hash tables is that this mapping does nothave to be unique. Let us take a concrete example: we have a tiny databasewith four keys such as:

The obvious way to find information about, say, Harpo is to search thefirst column for the string Harpo and then extract the information from thesecond column. This, of course, is slow (linear search with a string compar-ison at each step). So let’s produce a mapping from strings to integers. Wecould take the first character of each name (’a’ is 1, ’z’ is 26), divide by 4and get the remainder. This gives us:

Letter Value Value % 4G 7 3C 3 3H 8 0Z 26 2

Now we have a mapping but two keys (Groucho and Chico) map to thesame location. This need not be a problem; we could structure the tablelike this:

Each entry of a table like this is called a bucket and each bucket canhold more than one item. Now our algorithm becomes:

• Get the primary key P (for example, ”Chico”);

• Calculate the hash key H (3 for ”Chico”);

• Referring to bucket H -

Page 181: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

24.4. HASH FUNCTIONS 181

if any items in the bucket match Preturn the information of the matching item (stuff about Chico);elsethere is no entry for P;

Note: The only loop is where we look for items in the bucket (if anyitems . . .). I did not write the loop explicitly but clearly it will be there.

One bucket (number 1) is wasted.The fact that buckets might be wasted is fundamental and is what makes

hash tables efficient. For example, if we are willing to waste more space wecan remove the collision at bucket 3. If we have 7 buckets then we get aunique mapping:

Letter Value Value % 7G 7 0C 3 3H 8 1Z 26 4

With this mapping we waste 3 buckets but no bucket contains more thanone entry. We have traded off space against time.

24.4 Hash functions

The function we use to map from the primary key (”Chico”) to the hashkey (3) is called the hash function. In the first example above it was verysimple: for primary key P the hash key is P[0] % 4. In this case we chosethe first letter of P, but suppose we chose the last. All the names end in ”o”and so would hash to the same bucket no matter how big the table is. Solast letters are not a good idea for the Marx brothers. First letters wouldnot be a good idea for a table of Scotsmen (Mac...) or Irishmen (O’...).

Obviously just basing a hash function on one letter is not a good ideaat the best of times as there are only 26 letters, limiting us to 26 buckets.We would like to make use of more information from P. One way would beto add all the letters in P together: ”Chico” -¿ C + H + I + C + O -¿ 38.Then take this modulo the table size.

It reduces the problem but there is still a difficulty: ”AND”, ”DAN”and ”DNA” for example would all hash to the same bucket because theyare anagrams. The standard way to improve this is to take the position of aletter into account. For example, we could take the value of the first lettertimes 1, plus the value of the second times 2, plus . . . Doing this gives us:

"AND" -> 1*A + 2*N + 3*D -> 1*1 + 2*14 + 3*4 -> 41"DAN" -> 1*D + 2*A + 3*N -> 1*4 + 2*1 + 3*14 -> 48"DNA" -> 1*D + 2*N + 3*A -> 1*4 + 2*14 + 3*1 -> 35

Page 182: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

182 CHAPTER 24. HASH TABLES

Each of these numbers has to be taken modulo the table size, of course.By now it is clear what we want from a good hash function:It should produce hash keys spread evenly over the table (unlike the last

letter in the Marx brothers example). We can do this by using as muchinformation as possible from the primary key. It should be fast to calculate.This is a problem with the final example above because it uses a lot ofmultiplications (multiplication is a slow operation).

When hash functions work on strings a popular approach is the followingalgorithm:

hashKey = 0;for all letters in the primary keyhashKey = (hashKey << n) + value of next letter;

The operator ¡¡ is bitwise left shift. n is a small constant; 5 is as good avalue as any. Sometimes a hash function only uses a sample of informationin the primary key.

A final efficiency note: experiments have shown that hash keys distributemost evenly over the table if the size of the table is a prime number.

24.5 The Java class Hashtable

All objects in Java have a method called hashCode. Most classes overridethis method to provide a hash function suitable for the class. Thus thehashCode method of a String would be different from that of a BitSet, forexample. You can provide your own hashCode method for your own classes.

The class Hashtable has three constructors:

Hashtable()

– this makes a new hash table with a default capacity

Hashtable(int initialCapacity)

– makes one with initialCapacity capacity

Hashtable(int initialCapacity, float loadFactor)

– loadFactor must be between 0.0 and 1.0. If the number of entries in thetable grows to exceed loadFactor of the capacity, the table will automaticallyresize.

The load factor is an important attribute of a hash table. Rememberhow, in an earlier example, we were able to avoid collisions by making thetable large enough. By reducing the load factor we can improve access timeat the cost of space. A common rule-of-thumb is to use a load factor of 66%which should allow access to any element in less than two comparisons. Thedefault load factor is 75%. Resizing a hash table is an expensive operation.

27.6 A demonstration

Page 183: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

24.5. THE JAVA CLASS HASHTABLE 183

import java.util.Hashtable;

public class HashtableDemo {

/** A Hashtable demonstration. */public static void main(String[] args) {

// First we make a small HashtableHashtable elements = new Hashtable(10);

// Now we give it some elements// Use method putelements.put("actinium", "Ac, 89, 227");elements.put("aluminium", "Al, 13, 27.0");elements.put("americium", "Am, 95, 243");elements.put("antimony", "Sb, 51, 122");elements.put("argon", "Ar, 18, 39.9");elements.put("arsenic", "As, 33, 74.9");elements.put("astatine", "At, 85, 210");

// Let’s try to find something that should be there// Use method containsKeySystem.out

.println("elements.containsKey(\"arsenic\") gives "+ elements.containsKey("arsenic"));

// Produces: elements.containsKey("arsenic") gives true

// Let’s try to find something that’s not there// Use method containsKeySystem.out

.println("elements.containsKey(\"boron\") gives "+ elements.containsKey("boron"));

// Produces: elements.containsKey("boron") gives false

// Find element associated with a key// Use method getSystem.out.println("elements.get(\"antimony\") gives "

+ elements.get("antimony"));// Produces: elements.get("antimony") gives Sb, 51, 122

// Remove associated with a key// Use method remove; it returns the value removedSystem.out

.println("elements.remove(\"antimony\") gives "+ elements.remove("antimony"));

Page 184: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

184 CHAPTER 24. HASH TABLES

// Produces: elements.remove("antimony") gives Sb, 51, 122

// Try to get removed element// Use method getSystem.out.println("elements.get(\"antimony\") gives "

+ elements.get("antimony"));// Produces: elements.get("antimony") gives null

// How big is it? Should be one less than original.// Use method sizeSystem.out.println("elements.size() gives "

+ elements.size());// Produces: elements.size() gives 6

// Get an enumeration. This won’t print anything very printable// but can be used in the ways shown earlier for enumerations.// Use method keysSystem.out.println("elements.keys() gives "

+ elements.keys());// Produces: elements.keys() gives java.util.HashtableEnumerator@1da762

// The toString method generates a full description of the HashtableSystem.out.println("elements.toString() gives "

+ elements.toString());/** Produces: elements.toString() gives { astatine=At, 85, 210, argon=Ar,* 18, 39.9, americium=Am, 95, 243, actinium=Ac, 89, 227, arsenic=As,* 33, 74.9, aluminium=Al, 13, 27.0}*/

}}

The last one I had to reformat to get it to fit. Of course, in a realprogram one rarely uses such a small hash table.

24.6 Hash table implementations

The way shown of representing a hash table implied that when a collisionoccurs (two elements hash to the same bucket) a chain (linked list) is builtof the elements in the same bucket. This is, in fact, a common way ofimplementing hash trees. Whether or not this is the method used in the Javaclass Hashtable is not defined. This method is sometimes called externalchaining or separate chaining.

Page 185: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

24.6. HASH TABLE IMPLEMENTATIONS 185

As long as the load factor does not get too high these lists will be shortand so the method will be efficient. As the Hashtable class allows resizingthere is no reason in Java why the load factor should become too large.Some implementations allow for large load factors by using trees instead oflists.

Another approach does not use linked lists. If a primary key hashesto an already occupied bucket then a new hash key is recalculated using amodified hash function (a simple, but stupid, technique is just to add oneto the old hash key). If that bucket is occupied then another recalculationis made and so on. As the table fills it will require more and more rehashingto find a space. Clearly performance will degenerate badly as the table fillsand before the table is full it must be resized. This technique is called closedhashing.

Why, I hear you cry, would anyone want to do this? Surely it’s simplerand better to build a linked list of colliding elements? What lame brainedtwerp would do it this way? Well, many languages do not support dynamic(linked) data structures and some of those that do do not have nice librariesto make handling lists or trees easy. In those languages you have to dothings the hard way.

If you read a book on data structures you will often find very detailedand careful analysis of the closed hashing technique with various methodsof rehashing compared. There is a large body of research on the techniqueand a few years ago I would have taught it to you. Nowadays I think youcan get by knowing just open hashing.

Page 186: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

186 CHAPTER 24. HASH TABLES

Page 187: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 25

The bridge problem

25.1 Stating the problem

Bridge is a card game in which the aim is to get the most tricks. It requiresfour players who play in teams of two. All 52 cards are dealt, in rotation, tothe players so that at the end of the deal each player has 13 cards constitutinga hand. Preceding the actual play is a bidding stage in which a contract isestablished defining how many tricks the auction winner must make in thegame. During this bidding phase, players use their bids to communicate thestrength of their hand to their partner. To assist with this communication,various systems such as “Acol” and “Standard American Yellow Card” (SA-YC) have emerged to help standardise this communication.

There are 52 playing cards in a conventional ”deck”. These cards aredivided into four ”suits”, namely clubs, diamonds, hearts and spades. Eachsuit has 13 ”ranks” which are called 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen,King and Ace.

This project requires a program to be written to read a list of hands of13 cards in a format illustrated by:

Ace of spadesJack of spadesnine of spadesnine of heartsseven of heartstwo of heartsqueen of diamondsjack of diamondsten of diamondsking of clubsqueen of clubsfour of clubsthree of clubs

187

Page 188: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

188 CHAPTER 25. THE BRIDGE PROBLEM

Ace of spades...

The program should then evaluate the hand based on the system de-scribed below.

1. First, evaluate the hand based on ”High Card Points” as follows:

4 for an ace3 for a king2 for a queen1 for a jack0 for all other cards

2. Determine whether the hand is ”balanced”. A balanced hand containsat least 3 cards of each suit. The hand is also considered balanced ifone suit has only 2 cards, as long as the rest all have at least 3.

3. Determine the longest suit. Length is more important than strengthin bridge. If there is more than one suit of this length, choose thestrongest as follows CLUBS < DIAMONDS < HEARTS < SPADES.

4. Determine the opening bid based on the table provided below.

Table 25.1: Bridge opening bid system (based on Acol)Balanced hands0 - 11 No bid.12 - 14 1 No trumps.15 - 19 1 Longest suit.20 - 22 2 No trumps.≥ 23 2 Clubs.Non-balanced hands0 - 10 No bid.11 - 12 AND Length of longest suit ≤ 5 No bid.11 - 12 AND Length of longest suit ≥ 6 1 Longest suit.≥ 13 1 Longest suit.

The program should then produce, as output, the hand in descendingorder, in a style similar to that used in newspapers, together with the ap-propriate bid. i.e.

Page 189: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 189

SPADES: A K J 9HEARTS: 9 7 2DIAMONDS: Q J 10CLUBS: K Q 4

BID: 1 SPADES

Try to think about the problem. Write a description of a program tosolve this problem but don’t try to write the program. Think about howyou would represent the data in the program. Try to identify major subproblems.

25.2 Analysing the problem

The first thing to do is analyse the problem, then to come up with a designfor a solution. At this stage the programming language is largely irrelevantand the design should be in words. The style of the presentation here couldbe used as the basis for presenting reports for projects you will later beasked to do.

Within the project report the problem should first be re-stated ready tobe broken down into the solution steps. That has already been done above,so it will not be repeated it here.

The solution involves four major parts: reading the hand and decodingit, printing it in the required format, assessing it and making the bid. Each ofthese sections will be strongly dependent upon the method used to representa hand. This must be in a form that makes easy the printing of the cardsin order and at the same time makes assessing the hand easy.

The following shows the steps that a program will need to follow in orderto solve the stated problem.

Read the hands from a file.For each hand:

Print the hand.Calculate the bid.Print the bid.

25.2.1 Representing a Hand

Looking at our program outline, the first thing we want to do is read a listof hands from a file. In order to read the hands from a file, we need somekind of data structure to store them. Therefore, our first step is to work outhow to represent a hand within the program.

As previously described, a deck contains 52 playing cards, each desribedby a different combination of suit and rank. Each hand contains 13 of these.

Page 190: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

190 CHAPTER 25. THE BRIDGE PROBLEM

A clear way to represent suits and ranks would be with enumerated types.For instance a Suit can only be one of CLUBS, DIAMONDS, HEARTS orSPADES, so a Suit enum type to describe all suits could be as follows:

public enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES;

}

A card’s ranks can be anything from 2 to Ace, so a Rank enum typecould be as follows:

public enum Rank {TWO("2"),THREE("3"),FOUR("4"),FIVE("5"),SIX("6"),SEVEN("7"),EIGHT("8"),NINE("9"),TEN("10"),JACK("J"),QUEEN("Q"),KING("K"),ACE("A");

private final String shorthand;

Rank(String shorthand) {this.shorthand = shorthand;

}

public String shorthand() {return this.shorthand;

}

}

This is slightly more complicated than a Suit since for any Rank, wewant to also be able to get a shorthand form for display in the requestedformat.

Based on these enum types, we can create a PlayingCard class:

public final class PlayingCard {

Page 191: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 191

private final Suit suit;

private final Rank rank;

public PlayingCard(Rank rank, Suit suit) {this.rank = rank;this.suit = suit;

}

public Rank getRank() {return rank;

}

public Suit getSuit() {return suit;

}

public String toString() {return rank.toString() + " of " + suit.toString();

}

/** Returns the high card points value of the card. */public int getHighCardPoints() {

switch (this.getRank()) {case JACK:

return 1;case QUEEN:

return 2;case KING:

return 3;case ACE:

return 4;default:

return 0;}

}

}

So a PlayingCard holds a reference to a Suit and a Rank. Note theadditional methods added here. It seemed like a good idea to override thetoString() method so that when testing, it would be easy to print outdetails of the card. Since the program will need to know the high cardpoints value of a card, a getHighCardPoints() method was also added.

Page 192: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

192 CHAPTER 25. THE BRIDGE PROBLEM

Before going any further, it is a good idea to check that no mistakes havebeen made. It is much easier to fix them now than it will be later. A simplemethod could be written to test whether the PlayingCard toString(0)and getHighCardPoints() methods are working correctly.

public static void testPlayingCard() {PlayingCard card;

card = new PlayingCard(Rank.QUEEN, Suit.HEARTS);System.out.print("Card is " + card);System.out.println(", HCP = " + card.getHighCardPoints());

card = new PlayingCard(Rank.FOUR, Suit.SPADES);System.out.print("Card is " + card);System.out.println(", HCP = " + card.getHighCardPoints());

}

This produces the output:

Card is QUEEN of HEARTS, HCP = 2Card is FOUR of SPADES, HCP = 0

This looks like it is working. The toString() method on the PlayingCardis easy to read, and the correct High Card Points are being returned from thegetHighCardPoints() method. You could write more checks if you wantedto, but to save space here, only two tests are being carried out. When writ-ing a test like this, you should think about all the possibilities and decide foryourself how much ’coverage’ you need. For instance, since there are onlyfour suits, it would be easy enough to create tests for all of them. Likewise,you could make a point of having a 13 tests in order to cover all ranks. Butdo you need tests for all 52 combinations of suit and rank?

Now that we have a means of creating PlayingCard objects, we need ahand to put them in. A BridgeHand class will provide a data structure forstoring cards as they are read. We can also add a number of methods to theclass to help us assess the hand:

• isBalanced() We need to know whether the hand is balanced or not.

• getLength(Suit) We need a simple way to find out how many cardsof a given suit there are in the hand.

• getLongestSuit() As well as providing the length of a suit, we need tobe able to say which suit is longest in the hand for those non-balancedbids.

Page 193: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 193

• getHighCardPoints() Crucial to the bidding is the total high cardpoints in the hand.

package pij.bridgeproblem;

import java.util.ArrayList;import java.util.Collections;import java.util.EnumMap;import java.util.Iterator;import java.util.Map;

public class BridgeHand {

public static final int SIZE = 13;

/*** An EnumMap mapping each suit to another EnumMap which maps* a rank to a card.*/private Map<Suit, Map<Rank, PlayingCard>> cards;

/** A running total of high card points. */private int highCardPoints = 0;

/** A running indicator of longest suit. */private Suit longestSuit = Suit.CLUBS;

/** Constructor initialises data structures. */public BridgeHand() {

cards =new EnumMap<Suit, Map<Rank, PlayingCard>>(

Suit.class);

for (Suit suit : Suit.values()) {Map<Rank, PlayingCard> rankMap =

new EnumMap<Rank, PlayingCard>(Rank.class);

// Add an empty rank map to each suit map.cards.put(suit, rankMap);

}}

/*** Adds a card to the hand. Also updates the running totals

Page 194: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

194 CHAPTER 25. THE BRIDGE PROBLEM

* for high card points by suit and in total.*/

public void add(PlayingCard card) {Map<Rank, PlayingCard> rankMap =

cards.get(card.getSuit());rankMap.put(card.getRank(), card);

int points = card.getHighCardPoints();

// Add points to overall running total.highCardPoints += points;

// Update longest suit if necessary.if (!card.getSuit().equals(longestSuit)) {

if (getLength(card.getSuit()) == getLength(longestSuit)) {if (card.getSuit().compareTo(longestSuit) > 0) {

longestSuit = card.getSuit();}

} else if (getLength(card.getSuit()) > getLength(longestSuit)) {// Length is greater than current longest.longestSuit = card.getSuit();

}}

}

/*** A balanced hand contains at least 3 cards of each suit. It* is also considered balanced if one suit has only 2 cards,* as long as the rest all have at least 3.*/

public boolean isBalanced() {int twoCount = 0;int length = 0;for (Suit suit : Suit.values()) {

length = getLength(suit);if (length < 2) {

return false;} else if (length == 2) {

twoCount++;if (twoCount > 1) {

return false;}

}}

Page 195: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 195

return true;}

public int getLength(Suit suit) {return cards.get(suit).size();

}

public Suit getLongestSuit() {return longestSuit;

}

public int getHighCardPoints() {return highCardPoints;

}

25.2.2 Reading and Deciphering a Hand

We now have some working data structures where the hands from the filecan be stored. We need a BridgeHelper class with a method that allows usto read a file in the format defined, converting each line into a PlayingCardand adding it to the BridgeHand.

public class BridgeHelper {

/*** A simple utility method to read bridge hands from a file.*/public static List<BridgeHand> readHands(String filePath)

throws IOException {

ArrayList<BridgeHand> fileHands =new ArrayList<BridgeHand>();

BufferedReader theInput =new BufferedReader(new FileReader(filePath));

StringTokenizer tokenizer;String rankString;String suitString;Rank rank;Suit suit;String line;

do {

Page 196: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

196 CHAPTER 25. THE BRIDGE PROBLEM

BridgeHand hand = new BridgeHand();for (int lineNo = 1; lineNo <= BridgeHand.SIZE; lineNo++) {

line = theInput.readLine();tokenizer = new StringTokenizer(line);// First token is the Rank.rankString = tokenizer.nextToken().toUpperCase();rank = Rank.valueOf(rankString);// Second token is ’of’. Ignore it.tokenizer.nextToken();// Third token is the Suit.suitString = tokenizer.nextToken().toUpperCase();suit = Suit.valueOf(suitString);hand.add(new PlayingCard(rank, suit));

}fileHands.add(hand);// Move on a line after each hand.line = theInput.readLine();// The line will be null at the end of the file.

} while (line != null);

return fileHands;}

}

Why does readHands throw an exception? An exception is a class, andto throw an exception usually indicates an error. IOexception means some-thing wrong with an input or output operation. The readLine() methodof a BufferedReader is defined to throw an IOException, therefore we arerequired to cater for the possibility of this being thrown. We could do thisby using a try...catch block and handling it in there. Alternatively (aswe have done here), our method can be defined to also throw IOException.This means that the exception will be passed up to our controlling programand the decision of how to handle it must be made there. That decisioncould be to allow the program to crash, to ignore the error, or to log theerror.

Each card is represented as three words: FIVE OF CLUBS for example. Ifwe read a whole line at a time and then use a StringTokenizer, these wordscan be split into useful components ”FIVE” ”OF” ”CLUBS” as shown intokenizer = new StringTokenizer(line);. We can then read each tokenseparately by calling the nextToken() method of the tokenizer. The firsttoken produced gives us the rank of the card. The second token is of no useto us, so we can ignore it. The third token gives us the suit.

Page 197: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 197

Here we take advantage of a useful feature of enum types. When theSuit and Rank enums were defined, they were deliberately named so thatthey would match the names in the file. Therefore, if we have assignedrankString the value ”FIVE”, all we need is to call Rank.valueOf(rankString)in order to get a reference to the Rank FIVE. The same applies to Suit.

25.2.3 Printing the Hand

To do this in the required format, why not just add a printHand() methodto the BridgeHand class. This can be useful during testing since after cre-ating a hand, you can easily just print out the contents. The assignmentasked that we produce the print in descending order of Suit as follows:

SPADES: A J 9HEARTS: 9 7 2DIAMONDS: Q J 10CLUBS: K Q 4 3

If we were allowed to print it in ascending order of Suit, we could havebased the print on a nice simple loop such as for (Suit suit : Suit.values()) {}.However, since the aim is to print out the highest first we need to do itslightly differently. A straightforward way of doing this is to call Suit.values()get the list of suits as an array, set an index to the last array entry and thenstep backwards through the array, decrementing the index on each iteration.

public String printHand() {StringBuffer buf = new StringBuffer();

// Get suit values as an array.Suit[] suits = Suit.values();

// Iterate through the suits in reverse order.for (int i = suits.length - 1; i >= 0; i--) {

Suit suit = suits[i];

// Get a list of cards in the hand of this suit.ArrayList<PlayingCard> suitCards =

new ArrayList<PlayingCard>(cards.get(suit).values());

// Reverse the list since we need to display highest// values first.Collections.reverse(suitCards);

Page 198: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

198 CHAPTER 25. THE BRIDGE PROBLEM

buf.append(suit);buf.append(": ");for (PlayingCard card : suitCards) {

buf.append(card.getRank().shorthand());buf.append(" ");

}buf.append("\n");

}

return buf.toString();}

In order to print all the cards of each suit on each line, we need to gethold of a list of cards of that suit. If everything was held in an array orList, we could step through all values and check whether each was of theappropriate suit before adding it to the filtered list. However, there is anadvantage to having stored the cards in an EnumMap. We can just writecards.get(suit).values() to get a filtered Collection of cards.

The added advantage of having used the EnumMap is that the values()method returns the playing cards in the order of the keys in the map. There-fore, our collection of cards is already in ascending order. All we need to dois reverse it. The collections framework gives us another shortcut to reversethe ordering of our cards: Collections.reverse(suitCards);. So all weneed to do is print out the name of the suit and the ranks of the cards inthe reversed order.

25.2.4 Making the Bid

Knowing the length and the strength of each suit in the hand, making abid should be a straightforward matter of applying the rules specified in theproject assignment.

/*** Make a bid based on a simplified version of the Acol* system.*/public static Bid makeOpeningBid(BridgeHand theHand) {

int highCardPoints = theHand.getHighCardPoints();Suit longestSuit = theHand.getLongestSuit();

if (theHand.isBalanced()) {if (highCardPoints <= 11) {

return new Bid(0, null); // No bid.

Page 199: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 199

} else if (highCardPoints <= 14) {return new Bid(1, null); // 1NT

} else if (highCardPoints <= 19) {// Open 1 of longest suit.return new Bid(1, longestSuit);

} else if (highCardPoints <= 22) {// Open 2NTreturn new Bid(2, null);

} else {// 23+ pointsreturn new Bid(2, Suit.CLUBS);

}} else {

// Hand is non-balanced.if (highCardPoints <= 10) {

return new Bid(0, null); // No bid.} else if (highCardPoints <= 12) {

if (theHand.getLength(longestSuit) >= 6) {return new Bid(1, longestSuit);

} else {return new Bid(0, null); // No bid.

}} else {

// 13+ pointsreturn new Bid(1, longestSuit);

}}

}

25.2.5 The main program

As described earlier, the overall structure of the program is illustrated by:

Read the hands from a file.For each hand:

Print the hand.Calculate the bid.Print the bid.

We have done all the hard work inside the classes described already, sothere shouldn’t be much to do here. The main program itself looks like this:

public class BridgeBidDemo {

static List<BridgeHand> hands;

Page 200: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

200 CHAPTER 25. THE BRIDGE PROBLEM

public static void main(String args[]) throws IOException {

// Read the hands.hands = BridgeHelper.readHands("G:\\hands.txt");

// For each hand.Iterator<BridgeHand> handIterator = hands.iterator();while (handIterator.hasNext()) {

BridgeHand theHand =(BridgeHand) handIterator.next();

// Print the hand.System.out.println(theHand.printHand());

// Calculate the bid.Bid theBid = BridgeBidder.makeOpeningBid(theHand);

// Print the bid.StringBuffer buf = new StringBuffer();buf.append("BID: " + theBid);buf.append("\n\n");

System.out.println(buf.toString());}

}

}

Given the input in the file ”hands.txt”:

Ace of spadesJack of spadesnine of spadesnine of heartsseven of heartstwo of heartsqueen of diamondsjack of diamondsten of diamondsking of clubsqueen of clubsfour of clubs

Page 201: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

25.2. ANALYSING THE PROBLEM 201

three of clubs

Ace of spadesKing of spadesJack of spadesnine of spadesnine of heartsseven of heartstwo of heartsqueen of diamondsjack of diamondsten of diamondsking of clubsqueen of clubsfour of clubs

we get:

SPADES: A J 9HEARTS: 9 7 2DIAMONDS: Q J 10CLUBS: K Q 4 3

BID: 1 NO TRUMPS

SPADES: A K J 9HEARTS: 9 7 2DIAMONDS: Q J 10CLUBS: K Q 4

BID: 1 SPADES

I hope the logic is correct; there may be a bug, I hope not.

Page 202: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

202 CHAPTER 25. THE BRIDGE PROBLEM

Page 203: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 26

Exceptions and Defensiveprogramming

26.1 Introduction

You have already used exceptions without having them explained properly.Several languages have approaches to them. The problem exceptions addressis: I want to write safe code but I know things will go wrong. How do Ihandle unexpected occurrences without filling my program with extensivechecking code?

There are two types of things that can go wrong: you make a program-ming error (an array index out of bounds, for instance) or something beyondyour control happens (a data file does not exist). You may want some kind ofrecovery mechanism in the second case, but in the first you should hang yourhead in shame and print an apologetic message asking the user to contactyou and promising to fix the problem ASAP.

Although errors and exceptions are different logically, Java handles bothunder the exception mechanism.

26.2 The idea

You are writing a program to request the name of a data file from a userand then to process a lot of numbers in the file (we’ll just add them up, butthat’s for simplicity).

I’m going to mix true Java code with pseudo-code because I want toavoid the sometimes arcane syntax of Java.

Your first attempt might be: print a message asking for a file name; readthe file name and store in Name; open the file called Name;

Total = 0;while (not at end of the file){

203

Page 204: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

204CHAPTER 26. EXCEPTIONS AND DEFENSIVE PROGRAMMING

read a number N;Total += N;}print Total;

This looks fine and clearly would do the job. However, it assumes thatnothing goes wrong. It will clearly not do for professional code. You needto think of all the things that might go wrong: First thing that might gowrong is reading the file name. There may be no input available. When wetry to open the file it may not exist. When we try to read a number the filemight contain something else. Printing the Total might fail if there is nooutput device.

Your next, more robust, step might be:print a message asking for a file name; read the file name and store in

Name;

if (something went wrong){print message "Error getting file name";}else {open the file called Name;if (the file exists and opens properly){Total = 0;while (not at end of the file){read a number N;if (not a valid number){print "Invalid number input - stopping program";break;}Total += N;}print Total;} elseprint message "unable to open file";}

This takes 21 lines of program compared with the original 9. What ismore important, the clarity of the original logic has been lost - most of theprogram is now error checking.

The exception handling approach to this is:

try {print a message asking for a file name;read the file name and store in Name;

Page 205: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

26.3. USING STANDARD JAVA EXCEPTIONS 205

open the file called Name;Total = 0;while (not at end of the file){read a number N;Total += N;}print Total;

}catch (fileOpenException e1){

print message "File does not exist";}catch (inputException e2){

print message "Error getting file name";}catch (numberFormatException e3){

print message "Invalid number format";}

The advantages of this approach are: The original, logically clear pro-gram is intact. Things that should happen rarely (errors) are moved to theend of the program. All error handling is in the same place.

The try ... catch syntax above is correct Java. However, much of therest, including the exception names, is made up. You will see the correctversion shortly.

Java has a large number of predefined exceptions but you can add yourown. When an error occurs that is detected by the Java system an exceptionis thrown. It is up to the programmer to catch an exception. If you don’tthen the system will eventually catch it for you and print a message. Thatis probably the best thing to do for errors. For example, there is a stan-dard exception called IndexOutOfBoundsException which is thrown whenan array index is in error. You should not try to catch exceptions like thisbecause they are caused by programming errors. Instead you should fix theerror.

26.3 Using standard Java exceptions

The easiest way to use exceptions is to catch the standard Java exceptions.For example, the IOException is thrown when an input/output operationfails. This can be used to detect incorrect file names. Take as an examplethe program you saw earlier, which read a file of atomic element data. Thedata file in that case was called ”elements”, so what happens if you givea name that does not exist. The Java system will throw an IOExceptionwhich will ultimately be caught by the system. However, you can choose to

Page 206: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

206CHAPTER 26. EXCEPTIONS AND DEFENSIVE PROGRAMMING

catch this exception yourself and try to give helpful information. Below Igive a modified version of the program:

// Modification of the file reading program to show how to use exceptions.

import java.io.*;import java.util.*;

class Element{String name, symbol;int atomicNumber;float atomicMass;} // Element

public class Exception1 {

public static void main(String args[]) {String theInputFile = new String("aliments");DataInputStream theInput = null;try {theInput = new DataInputStream(new FileInputStream(theInputFile));Element table[] = new Element[103];

<snip>. . . . . . . . . </snip>

}} catch (IOException e){System.out.println(e.toString());System.out.println("Problem trying to open " + theInputFile);}

try {System.in.read(); // prevent console window from going away} catch (java.io.IOException e) {}} // main} // Exception1

Notice that I have changed the name of the data file. When I run this Iget

java.io.FileNotFoundException: alimentsProblem trying to open aliments

Note:

Page 207: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

26.4. DEFINING YOUR OWN EXCEPTIONS 207

Look at the use of toString to get the name of the exception. Noticehow main doesn’t throw IOException. Java lets us do this because we nowcatch it in main. If you contract to catch an exception then you don’t haveto tell Java that a method will throw it. Otherwise you must.

26.4 Defining your own exceptions

You can define your own exceptions by inheriting from Exception. Modifyingthe elements program so that it checks for valid atomic numbers we get:

import java.io.*;import java.util.*;

class Element{String name, symbol;int atomicNumber;float atomicMass;} // Element

public class InvalidElementException extends Exception{public InvalidElementException(){super("Impossible element");} // InvalidElementException} // InvalidElementException

public class Exception2 {

public static void main(String args[]) throws InvalidElementException{String theInputFile = new String("elements");DataInputStream theInput = null;try {<snip> . . .table[n].atomicNumber = Integer.parseInt(tokens.nextToken());if (table[n].atomicNumber < 1)throw new InvalidElementException();table[n].atomicMass = new Float(tokens.nextToken()).floatValue();n++;}

} catch (IOException e){System.out.println(e.toString());System.out.println("Problem trying to open " + theInputFile);} // catch

Page 208: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

208CHAPTER 26. EXCEPTIONS AND DEFENSIVE PROGRAMMING

try {System.in.read(); // prevent console window from going away} catch (java.io.IOException e) {}}}

I made one of the elements have a negative atomic number and then theprogram produced:

InvalidElementException: Impossible elementat Exception2.main(Exception2.java:42)at com.mw.Exec.run(JavaAppRunner.java:47)

Notice that the name of the exception is printed and also the stringassociated with its super class. This is often enough to tell you what isgoing wrong. Of course it not good enough for professional software.

Now, I hear you cry, what is the super class? The class name superalways indicates the class from which yours is inherited. In the case above,let’s look at the code:

public class InvalidElementException extends Exception{public InvalidElementException(){super("Impossible element");} // InvalidElementException} // InvalidElementException

This says that InvalidElementException inherits from Exception. It alsocreates a constructor for InvalidElementException which, of course, has thename InvalidElementException. It also calls a constructor for its parent(super) with a String as an argument. (What is really the name of super?).When an object of class InvalidElementException is created then its con-structor is called. Its parent constructor is also called because of the call ofsuper. That is why you see both names when the program fails.

The important thing is that the exception thrown is caught by the sys-tem. The usual practice, if you want to create your own exceptions, is toinherit a class from Exception, give it suitable constructors, and then throwit when necessary. Once an exception is thrown it will be caught in a catchblock or pass up the hierarchy eventually to be caught by the system andproduce a message such as that above.

Next we shall look at catching ones own exceptions. It is not hard.

try {<snip> . . . </snip>table[n].atomicNumber = Integer.parseInt(tokens.nextToken());if (table[n].atomicNumber < 1)

Page 209: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

26.4. DEFINING YOUR OWN EXCEPTIONS 209

throw new InvalidElementException();table[n].atomicMass = new Float(tokens.nextToken()).floatValue();n++;} // try

<snip> . . . </snip>}catch (InvalidElementException e){System.out.println("Invalid atomic element ");} // catchcatch (IOException e){System.out.println(e.toString());System.out.println("Problem trying to open " + theInputFile);} // catch

Notice the catch clause which catches the exception we created. Whenan exception is thrown the catch clauses are tried in turn until one matchesthe exception. If no match is found then control passes to any enclosing try.. catch block. If it is still not handled it is passed up again and so on.The runtime system finally handles any uncaught exceptions by printing amessage.

After the last catch clause you can have a finally clause. This containsany statements you want to make sure are obeyed such as closing files,breaking connections and so on..

Page 210: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

210CHAPTER 26. EXCEPTIONS AND DEFENSIVE PROGRAMMING

Page 211: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 27

Binary numbers andrepresentation in a computer

27.1 Conversion between number systems

The number system we all use is based on the number ten and is calleddecimal or denary. The number 169, in this system, is short for (100 x 1) +(10 x 6) + (1 x 9).

We say that 169 here is in base 10 and we can emphasise that by writingit 16910. The same principal can be applied to other bases and computerprogrammers often use bases of 8 and 16, while computers use base 2.

To illustrate the octal system (base 8), the number 3478 (pronounced’three four seven base eight’, not ’three hundred and forty seven base eight’)is (64 x 3) + (8 x 4) + (1 x 7) or in decimal notation 231. Notice that theoctal digit positions represent not units, tens and hundreds but units, eightsand sixty-fours (64 = 82). In an octal system there are only the eight digits0, 1, 2, 3, 4, 5, 6 and 7.

The binary system (base 2) only has two digits, 0 and 1, and is used incomputers because it is cheap to make electronic circuits which have onlytwo states. The binary number 11012 = 8 x 1 + 4 x 1 + 2 x 0 + 1 x 1 = 13.When working with binary numbers it is useful to keep a table of powers oftwo handy. Up to fifteen, these are:

20 = 1 24 = 16 28 = 256 212 = 409621 = 2 25 = 32 29 = 512 213 = 819222 = 4 26 = 64 210 = 1024 214 = 1638423 = 8 27 = 128 211 = 2048 215 = 32768

With this table, conversion from binary to decimal is easy. Countingfrom the right, the digits of a binary number represent 20, 21, 23, 24 andso on. Therefore conversion involves just adding up the powers of two cor-responding to the one-bits in the binary number. For example, 101012 = 1

211

Page 212: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

212CHAPTER 27. BINARY NUMBERS AND REPRESENTATION IN A COMPUTER

+ 4 + 16 = 21.The reverse operation involves breaking a number down into a sum of

powers of two. For instance, 37 = 32 + 4 + 1 = 1001012.Because binary numbers are unwieldy when written, if they have to be

read or manipulated by humans they are usually translated into octal (base8) or hexadecimal (base 16). These bases are chosen because conversionfrom either to binary is very simple. Each octal digit represents a group ofthree bits, and each hexadecimal digit represents four bits. Octal to binarytranslation uses the following table:

08 = 0002 18 = 0012 28 = 0102 38 = 011248 = 1002 58 = 1012 68 = 1102 78 = 1112

To convert an octal number to binary, substitute the appropriate threebits for each octal digit. Thus, 72458 = 111 010 100 1012. For the reverseprocess group the binary digits in threes and substitute the correspondingoctal digit. The hexadecimal (base 16) system is nowadays used more oftenthan octal. In this system there are sixteen symbols representing the num-bers 0 to 15. The digits 0 to 9 are written in the usual way, and then 10,11, 12, 13, 14 and 15 are represented by A, B, C, D, E and F respectively.The positions of hexadecimal digits represent successive powers of 16, i.e.units, 16s, 256s etc. As an example, the number B516 = 11 x 16 + 5 = 181.Conversion from hexadecimal to binary uses the following table:

016 = 00002 116 = 00012 216 = 00102 316 = 00112416 = 01002 516 = 01012 616 = 01102 716 = 01112816 = 10002 916 = 10012 A16 = 10102 B16 = 10112C16 = 11002 D16 = 11012 E16 = 11102 F16 = 11112

To convert a hexadecimal number to binary substitute the appropriatefour bits for each hexadecimal digit. Thus the hexadecimal number A68B16= 1010 0110 1000 10112. For the reverse process group binary digits in foursand substitute the equivalent hexadecimal digit.

27.2 Negative numbers

The left-most bit of a signed value is called the sign-bit, with zero indi-cating positive and one indicating negative. However, a number cannotbe made negative just by reversing the sign bit. Computers use what isknown as one’s-complement or two’s-complement notations but Java usestwo’s-complement.

In one’s-complement notation the negative of a number is formed byreversing all its bits, so that +17 is represented as 0000 0000 0001 0001 andreversing all the bits gives us -17, which is 1111 1111 1110 1110. In this

Page 213: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

27.3. BITWISE OPERATIONS 213

notation the largest positive value on a 16-bit machine is the bit pattern0111 1111 1111 (32767 in decimal), and the most negative value is 1000 000000 000 (-32767 in decimal). Few computers use one’s-complement notationto represent integers because it has two representations for zero, namely0000 0000 0000 0000 and 1111 1111 1111 1111. Instead two’s-complementis favoured.

In two’s-complement notation the negative of a number is formed byreversing all the bits and then adding one to the result. The table belowshows some values on a sixteen bit computer

32767 0111 1111 1111 11112 0000 0000 0000 00101 0000 0000 0000 00010 0000 0000 0000 0000-1 1111 1111 1111 1111-2 1111 1111 1111 1110-32767 1000 0000 0000 0001-32768 1000 0000 0000 0000

Notice that the most negative value has a larger absolute magnitude thanthe most positive value. Notice also that overflowing (trying to producea value out of the range of integers) will, unless detected by the system,produce a result of the wrong sign. For example, adding 1 to 32767 willproduce 1000 0000 0000 0000, which is -32768.

27.3 Bitwise operations

The bitwise operations on whole integers are AND, INCLUSIVE OR, EX-CLUSIVE OR and COMPLEMENT (otherwise known as NOT). In Javathese operations can be invoked by using the operators &, |, ^ ~ respec-tively. The operands are usually unsigned char, int or long int, althoughsigned values can be used.

The following truth table illustrates the operations on individual bits aand b.

a b a\&b a\|b a^b ~a

0 0 0 0 0 10 1 0 1 1 11 0 0 1 1 01 1 1 1 0 0

The bitwise AND operation between two operands produces a resulting bitpattern which has a one-bit only at the positions where both operands haveone-bits. A bitwise INCLUSIVE OR operation produces a pattern with a

Page 214: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

214CHAPTER 27. BINARY NUMBERS AND REPRESENTATION IN A COMPUTER

one-bit where either operand has a one bit. A bitwise EXCLUSIVE ORoperation produces a pattern with a one-bit where either operand has a onebit, but not both. A COMPLEMENT operation reverses the value of eachbit.

Assuming v1 and v2 are eight-bit quantities, the example below illus-trates these operations.

v1 = 0 1 0 1 1 1 0 1v2 = 1 1 0 1 0 1 1 1v1 & v2 = 0 1 0 1 0 1 0 1v1 | v2 = 1 1 0 1 1 1 1 1v1 ^ v2 = 1 0 0 0 1 0 1 0~ v1 = 1 0 1 0 0 0 1 0

27.4 Shift operations

Shift operations on bit patterns are classified as logical, arithmetic and ro-tational, but Java does not provide all these. The shift operators in Javaare:

<< Shift left, fill with zero from right. (logical)>> Shift right, copying sign bit from the left. (arithmetic)>>> Shift right, fill with zeros from the left. (logical)

In a logical shift the whole group of bits being moved are treated asan unsigned quantity. Arithmetic shifts, on the other hand, consider theleft-most bit to be a sign bit. For example, if the sixteen-bit word

1111 1111 1111 1100

which represents the value -4, is shifted right arithmetically by one po-sition the result will be

1111 1111 1111 1110

which is -2. A left arithmetic shift by one position is equivalent tomultiplying by 2, and a right shift produces division by 2. A rotational shiftof a bit pattern causes bits lost at one end to reappear at the other. Forexample, if the pattern

1101 1011 0011 1110

is rotated right by five places the result is

1111 0110 1101 1001

Unfortunately Java does not provide rotational shift operators; if neededthe effect must be achieved rather clumsily by combining logical shifts andbitwise operations.

Page 215: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 28

Timing programs -Instrumenting your code toimprove performance

28.1 Introduction: a brief history of time

Time has been around for a very long time and is still not fully under-stood. Many methods are used to measure it including mechanical clocks,atomic clocks, astronomical observations and vibrating crystals. It is theselatter which are usually used in computers. Most computer language imple-mentations provide methods of accessing the computer clock, although themethods and how they are used are often not part of the official languagedefinition.This means that the precise way of reading a clock varies betweendifferent implementations of the same language.

Computers distinguish two kinds of time: clock-on-the-wall-time andprocess time. The first is more or less what its name implies although it isusually stored internally in small units such as milliseconds. The second isthe time that a process (a program) has been consuming the entire powerof the machine. As most computers run several processes at the same timethe process time is a measure of how the time available has been shared out.For the purposes of your programs it is the second that is most useful butunfortunately Java provides methods for getting the clock-on-the-wall-timeonly.

The disadvantage of this for our purposes is clear: if other processes arerunning at the same time as the process you are trying to measure then eachtime one of them runs the clock-on-the-wall-time advances, but this is notdue to your program. Thus your final result is likely to be a bit high. Allyou can do about this is stop any unnecessary processes before you beginyou timings and then grit your teeth and wear a cheerful countenance. Thismethod is completely unsuitable if accuracy is paramount, but is adequate

215

Page 216: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

216CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

if you just want to compare programming methods and algorithms. As thatis what we are concerned with here we need not feel too guilty. If we weredoing carefull measurements comparing different machines for publicationin a technical journal we would have to be much more carefull.

28.2 Measurements

There are certain principals which are common to making and presenting anyscientific measurement. Many of these are taught in high schools (althoughnot all students seem to absorb them), and they have been honed over thelast four centuries until they are now regarded as holy writ. Most of themare obvious, but the obvious is not always clear until it has been put intowords.

28.2.1 Measuring small quantities with tools that can onlyhandle large quantities.

Among the things we are going to do is measure the time that one machineinstruction takes. As machine instructions typically take small fractions ofmicroseconds (s) and our tools can only measure milliseconds (ms) this mayat first seem difficult. However, imagine you wanted to measure the thicknessof one page of a book and all you had was an ordinary ruler. The answeris obvious: take a few hundred pages and measure their thickness. Thendivide the result by the number of pages and you should have a reasonablyaccurate answer. In the programs I used here I measured about 100,000operations for each case.

28.2.2 Repeat all measurements several times.

All the measurements here were taken five times. The first reason for doingthis is to detect blunders. Even if you are measuring the size of a room takemore than on measurement. This will show any times you have misread ormisplaced the measure. Next it reduces random errors: if one measure hasa random error of up to ten percent then the average of four measurementsshould have an error less than five percent.

28.2.3 Errors may be random or consistent.

Random errors can be caused by such things as electrical fluctuations in acircuit, vibrations caused by nearby traffic or machinery, radioactive decay,instrumental limits causing you to read a value high or low at random,natural fluctuations in a quantity such as flow (water, air, people). Randomerrors should first be minimized by such instrumental improvements as canbe made and then statistics can be used. If one has a set of n measurements

Page 217: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28.3. THE CLOCK CLASSES 217

with an average random error of e, then the average of n will have an errorof around e√

n. By taking many measurements (sometimes millions) one can

reduce random errors enormously.Consistent errors require a different approach. Suppose you have a cup

of water, the temperature of which you wish to measure. Simple; stick athermometer in it and measure the answer. Repeat a few times. Well thatseems fine but what about the thermometer itself? Merely inserting thethermometer will change the water temperature.The first approach is toimprove the thermometer to make it less intrusive. Reduce its size, see if itcan be made with a substance with low specific heat etc. One could makemuch progress in this way but eventually you will have to try to calculatethe effect of the thermometer. When you have allowed for this you shouldhave a reasonable, but not perfect result.

In our measurements here we will get consistent errors from, amongother things, the instruments (program tools) we insert in the programsand the problem mentioned earlier of concurrent processes disturbing thetiming. We could try to correct these but I haven’t bothered as we are onlyconcerned with comparative results.

28.2.4 Distinguish between accuracy and precision.

When you measure something you are mainly concerned with accuracy: howfar away from the true value is your measurement? Precision is concernedwith the fineness of your instrument. The fact that your instrument cangive (say) six significant figures does not mean that the accuracy is alsosix figures; it depends upon all the other things involved the measurement.This is very important when presenting your results. You have taken anumber of measurements of some quantity and you crunch them throughyour calculator to get the average. The calculator will reply with somethinglike 2.38473901, a total of nine significant figures. Is this the answer youshould present as your result? Almost certainly not. First you look at yourraw data and see that they mainly start 2.38???? This implies that the firstthree figures are probably alright, a guess is possible for the fourth figureand the rest are ’noise’. Thus the answer could be written 2.385 if we roundthe rubbish to the nearest figure. To be more correct we could write it as2.385 0.005. There are more refined ways of handling the errors, but theyare not really worth it in our case.

28.3 The clock classes

Our measurements here are based on two classes written for the purpose.For now, the internals of the classes are not so important. They will bediscussed later in the chapter. For now we just need to know how to use the

Page 218: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

218CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

classes. Remember that our main purpose in doing these measurements isto improve the performance of programs. This affects the measurements wechoose to make.

package pij.timing;

class Clock {

private int uses = 0;

private boolean isOn = false;

private long elapsedTime = 0, timeLastStarted = 0;

final static String spaces = new String(" ");

final static int numSpaces = spaces.length();

void on() {if (!isOn) {

timeLastStarted = now();uses++;isOn = true;

}}

void off() {if (isOn) {

elapsedTime += now() - timeLastStarted;isOn = false;

}}

long now() {return System.currentTimeMillis();

}

void resetClock() {elapsedTime = 0;timeLastStarted = 0;

}

static String format(String s, int n) {return spaces.substring(0, n - s.length()) + s;

Page 219: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28.3. THE CLOCK CLASSES 219

}

void print() {StringBuffer buf = new StringBuffer();

buf.append(" Uses = ");buf.append(uses);buf.append(", elapsed time = ");buf.append(elapsedTime);buf.append(" milliseconds. \n");buf.append("Time per use = ");

double avgTimePerUse = (double) 1000* (double) elapsedTime / (double) uses;

buf.append(avgTimePerUse);buf.append(" microseconds.");

System.out.println(buf.toString());}

int usesOf() {return uses;

}

}

package pij.timing;

import java.util.BitSet;import java.util.Vector;

class ClockBank {

final static private int maxClock = Integer.MAX_VALUE; // Why not?

private int bankSize = 10, // Should be enough, most times.lowestClock = maxClock, // Ensure set on first go.highestClock = 0, clocksPrinted = 0;

Vector<Clock> theBank = new Vector<Clock>(bankSize);

BitSet clockInstalled = new BitSet(maxClock);

Page 220: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

220CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

ClockBank() {for (int n = 0; n <= bankSize; n++)

theBank.insertElementAt(new Clock(), n);}

ClockBank(int n) {for (int i = 0; i < n; i++)

theBank.insertElementAt(new Clock(), n);}

void on(int n) {install(n);if (n < lowestClock)

lowestClock = n;if (n > highestClock)

highestClock = n;((Clock) theBank.elementAt(n)).on();

}

void off(int n) {((Clock) theBank.elementAt(n)).off();

}

void print(int n) {((Clock) theBank.elementAt(n)).print();

}

void printClocks() {for (int n = lowestClock; n <= highestClock; n++) {

System.out.print("At Clock "+ Clock.format("" + n, 5) + " ");

print(n);}clocksPrinted++;

}

private void install(int n) {clockInstalled.set(n);

}

}

The only true novelty here is System.currentTimeMillis(); whichgives the clock-on-the-wall-time in milliseconds. The rest is the code for

Page 221: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28.4. SIMPLE USE 221

handling the clocks which is there because of its intrinsic interest.The class Clock imitates a stopwatch such as those used in races. It

can be started, stopped and read. As well as recording the time accumu-lated when it is running, a clock records the number of times that it hasbeen started. The class Clock is never used directly but serves as a helperclass for the class ClassBank. This is a collection of clocks numbered from0. One turns on and off a number of clocks and finally prints the values.One normally brackets sections of program code between on and off calls.A ClassBank has two constructors, ClassBank() creates a bank of of tenclocks (initially, it can be increased) and ClassBank(n) which creates (andinitializes) ten clocks numbered zero to 9 in the usual Java fashion. Themethods in ClassBank that you may use are on(n), off(n), print(n) andprintAllClocks().

You have already seen packages; these are the items you put after importat the start of a program. Examples include java, Math etc. It is easy to usea package in a program: just use its name after include. To make a packageis as easy as using one: just put the word package and a suitable title as thefirst line. To illustrate I shall give the entire timing package. This is notbecause it represents a particularly tricky package but because it is a usefulpackage.

28.4 Simple use

To get started we shall use the clocks to time the clocks. This should give usan idea of the consistent error caused by using the clocks themselves. Thismeans that we shall want to time statements such as

thisClock.on(3);thisClock.off(3);

Here we run into the first problem; the time taken by two statements suchas these will likely be a few s but our tool measures in ms. The solutionis to use the page thickness approach; i.e. time very many copies of thestatements. The statements used to do this were:

public static void testClockBank() {

ClockBank myClocks = new ClockBank();

int reps = 1000;

for (int i = 0; i <= 10; i++)myClocks.theBank.insertElementAt(new Clock(), i);

Page 222: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

222CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

myClocks.on(0);

for (int n = 1; n <= reps; n++) {myClocks.on(1);myClocks.off(1);myClocks.on(1);myClocks.off(1);// ... on and off 100 times ...myClocks.on(1);myClocks.off(1);myClocks.on(1);myClocks.off(1);

}

myClocks.printClocks();

}

The comment in the middle implies enough statement pairs to make upone hundred. The first statement declares and creates the bank of clocksalthough it does not create the clocks themselves. That is left to the forloop which creates each clock in turn and inserts it in the vector theBankin the object myClocks. reps is the number of repetitions required for themain loop. Notice the placement of on and off around this loop.

You may be wondering why the loop contains one hundred copies of thestatement pair we want and then this is repeated 1000 times. Why not have aloop containing one statement pair once and repeat it 100,000 times. The an-swer, of course, is that the code for the for loop requires machine instructions.In fact the instructions to implement for(int j = 0; j < 100; j++) prob-ably take a time comparable with an on/off pair. By having many pairs wecan avoid the effect of the for loop on the results.

The output on the author’s machine were as follows:

At Clock 0 Uses = 1, elapsed time = 0 milliseconds.At Clock 1 Uses = 100000, elapsed time = 16 milliseconds.

The results obtained were that one pair of calls costs 0.16 s. This tells usthat whenever we put a group of statements between on and off they musttake substantially more than 0.16 s to have any meaning.

28.5 Timing machine instructions

When I write of ’primitive’ instructions here I mean the most primitivethings you write such as addition, multiplication and so on. It is a good

Page 223: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28.5. TIMING MACHINE INSTRUCTIONS 223

idea to get a ’feel’ for these operations because you can take this into ac-count when you first write your program. As you write it is easy to substitutecheaper operations for more expensive ones where this is possible. As anexample, on most machines (but not all) division is significantly more expen-sive than multiplication and if a division can be changed to a multiplicationsome benefit may accrue (particularly if the instruction is in heavily usedcode) and nothing will be lost.

These fundamental operations take very little time each and so timingthem will involve many repetitions. In fact all the figures below use 10million operations each in the form of 100,000 repetitions of 100 instructions.The results in s are:

int + int 0.048int + 1 0.045int ++ 0.038int * int 0.043int / int 0.051double + double 0.049double * double 0.046double / double 0.051sqrt(double) 0.25sin(double) 0.36

Several points emerge in a first look at these figures. The ordinaryoperators (i.e. not sin or sqrt) all take roughly the same time (abour 0.04s); on many machines this is not true and multiplication is slower than‘addition and quicker than division. The operator ++ is signicantly fasterthan + 1, possibly because the operator ++ has special hardware to speedit up. This is quite common.

Note especially the times for sqrt and sin. These operations take manymachine instructions and are slow. Try to remove them or introduce extravariables to hold intermediate results calculated more than once. For exam-ple, should a group of statements contain sin(theta) more than once thenintroduce a new variable with a statement such as:

sinTheta = Math.sin(theta);

and then use sinTheta whenever you want Math.sin(theta). Often a littletrivial algebra can make a huge difference. The following is from a realprogram (in a Java related language):

while(sqrt(1 + x^3)/sqrt(1 + y^3) < eps) do ...

A few moments reflection shows that we can remove the division and thensquare both sides to remove the sqrt leaving:

while( 1+x^3 < eps^2 * (1 + y^3) do ...

Page 224: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

224CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

As this is the central loop of the entire program this simple change speededeverything up by about ten times. Moral: see if you can rework the algo-rithm.

28.6 Summary of simple optimizations

The optimizations we have seen so far are very simple, require no particularanalysis of the program and can be largely implemented as we first writea program. In the next section we will look at deeper improvements. Thesimple optimizations can be summarized easily:

Remove statements from loops wherepossible. Sometimes we find state-ments in loops which do not change each time round the loop. The valueeps2 in the statement above is probably such a value. If it never changesduring transits round the loop then we can calculate it once, before the loop.Then the statement above becomes something like:

eps2 = eps*eps;while (( 1+x^3 < eps2 * (1 + y^3) do ...

Weaken operators when possible. A weaker operator is one that takesless time than a stronger one. So on most machines addition is weaker thanmultipliction and multiplication weaker than division. So, for example, theexpression 2 ∗ x can be replaced by x + x and be a little faster. This caseis fairly easy to recognize and may be carried out automatically by yourcompiler so you may not need to make the improvement, but it will do noharm.

Avoid calculating values twice. Given a sequence of statements con-taining repetitions of the same expressio, calculate the value of one of therepeated expressions once, store the result in a supplementary variable andthen use that whenever the value is needed.

Try a little algebra. When expressions are slightly less than trivial see ifthey can be simplified algebraicly. To do this it may help to translate themfrom Java notation back to ordinary algebra.

Avoid mathematicalefunctions. As we saw a little earlier the mathemat-ical functions such as sin and sqrt are slow. In fact most of the functionsin Math are slow. Try to remove these from inside loops and see if a littlealgebra can reduce the need for them.

28.7 Using instruments to help optimization

The optimizations discussed above can be applied without too much analysisof the program being developed. However, when efficiency is important itis necessary to make a careful study of the program. This can be helped

Page 225: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28.8. EXERCISE 225

by instrumenting the program. This means inserting measuring tools in theprogram; in this case we are going to use the clock tools developed above.The subject program we are going to use is often used for benchmarking; itis the sieve of Eratosthenes which is an ancient and efficient way of findingprime numbers (numbers that can only be wholly divided by themselves orone). To do it take a nice flat beach, put on loads of sun block, and make arow of small pits each large enough to hold a small pebble. Put a pebble ineach pit and then start at pit two and remove every second pebble. Then goon to pit three and remove every third, then pit 5 (4 is empty) and removeevery fifth and so on. Soon you will find that there are no more pits to goand all you have left are the stones in pits 2, 3, 5, 7, 11, 13, 17, 19 and soon. These are prime numbers and we found them without using a singledivision; not bad for a more than 2000 year old algorithm.

28.8 Exercise

If there are N pits then we can stop trying to cast out pebbles after the pitnumbered n. We can prove that n =

√N . Prove this.

To implement the sieve program we inspect it and identify the mainplaces where time may be occupied and put a clock around each. For ourprogram this gives us:

class Eratosthenes1 {

public static void main(String args[]) {final int maxPrime = 10000;int i, candidate, strikeOut, primes = 0, repetitions = 10000;boolean sieve[] = new boolean[maxPrime + 1];ClockBank theBank = new ClockBank();

theBank.on(1);for (; repetitions > 0; repetitions--) {

theBank.on(2);for (i = 2; i <= maxPrime; ++i)

sieve[i] = true;theBank.off(2);theBank.on(3);candidate = 2;while (candidate <= Math.sqrt(maxPrime)) {

theBank.on(4);for (strikeOut = 2 * candidate; strikeOut <= maxPrime; strikeOut += candidate)

sieve[strikeOut] = false;theBank.off(4);theBank.on(5);

Page 226: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

226CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

while (!sieve[++candidate]);

theBank.off(5);}theBank.off(3);theBank.on(6);for (i = 2, primes = 0; i <= maxPrime; ++i)

if (sieve[i])++primes;

theBank.off(6);}theBank.off(1);

System.out.println("The number of prime numbers up to "+ maxPrime + " is " + primes);

theBank.printClocks();}

}

The output from this is:

The number of prime numbers up to 10000 is 1229At Clock 1 Uses = 1, elapsed time = 1547 milliseconds.At Clock 2 Uses = 10000, elapsed time = 295 milliseconds.At Clock 3 Uses = 10000, elapsed time = 876 milliseconds.At Clock 4 Uses = 250000, elapsed time = 813 milliseconds.At Clock 5 Uses = 250000, elapsed time = 16 milliseconds.At Clock 6 Uses = 10000, elapsed time = 376 milliseconds.

According to this, 10,000 repetitions of searching for the primes less than10,000 takes about 1.547 s which is 44s per group of 10,000. As no correctionhas been made for the time to turn on or off each clock or any other overheadthis figure will be a little high. The most interesting part of the code is thattimed by clock 4, which is only five lines long yet takes a significant time.There is very little to be changed that can bring any advantage however,although the next improvement will halve the number of times it is calledand so improve the overall time.

The line starting while (candidate ¡= Math.sqrt . . . looks promisingbut introducing an extra variable to remove the square root from inside theloop had virtually no effect. This is interesting because on an older, muchslower machine this was a worthwhile improvement.

None of this piecemeal ’code tweaking’ has much effect on the test ma-chine, so we are left to find ways of improving the algorithm. One approach

Page 227: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

28.8. EXERCISE 227

is to think about the meaning of each pit. The pit represents a number withpit 1 representing 2, pit 2 -¿ 3, 3 -¿ 4 and so on. Half the pits representeven numbers yet half these are struck out on the first move. Why botherhaving pits for the even numbers? If we let pits 1, 2, 3, 4, 5, 6, 7 representthe numbers 3, 5, 7, 9, 11, 13, 15 we halve the size of the sieve which willhave an effect on the clock 4 loop in particular. The final version is:

class Eratosthenes2 {

public static void main(String args[]) {final int maxPrime = 10000, maxElem = ((maxPrime + 1) / 2 - 1), sieveSize = (maxElem + 1);int i, candidate, strikeOut, primes = 0, repetitions = 10000, currElem;boolean sieve[] = new boolean[sieveSize];double sqrtMaxPrime;

ClockBank theBank = new ClockBank();theBank.on(1);

for (; repetitions > 0; repetitions--) {for (i = 1; i < sieveSize; ++i)

sieve[i] = true;candidate = 3;currElem = 1;sqrtMaxPrime = Math.sqrt(maxPrime);while (candidate <= sqrtMaxPrime) {

for (strikeOut = candidate * candidate / 2; strikeOut <= maxElem; strikeOut += candidate)sieve[strikeOut] = false;

while (!sieve[++currElem]);

candidate = 2 * currElem + 1;}

for (i = 1, primes = 1; i < sieveSize; ++i)if (sieve[i])

++primes;}

System.out.println("The number of prime numbers up to "+ maxPrime + " is " + primes);

theBank.printClocks();}

}

Page 228: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

228CHAPTER 28. TIMING PROGRAMS - INSTRUMENTING YOUR CODE TO IMPROVE PERFORMANCE

The output was:

The number of prime numbers up to 10000 is 1229At Clock 1 Uses = 1, elapsed time = 750 milliseconds.At Clock 2 Uses = 10000, elapsed time = 48 milliseconds.At Clock 3 Uses = 10000, elapsed time = 325 milliseconds.At Clock 4 Uses = 240000, elapsed time = 203 milliseconds.At Clock 5 Uses = 240000, elapsed time = 46 milliseconds.

The time was 750 ms for the whole program, compared with 1547 msfor the first version. This means this version takes only 48% of the originalprogram. This illustrates a general point: most advantage comes from im-proving the algorithm. Remember that almost all the improvement comesfrom very little code. Use tools such as the one given here to identify thesecritical sections and most of the time you can forget the rest.

Page 229: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 29

Sets

29.1 The set concept

You have probably learned about sets in maths classes. Mathematically aset is a collection of anything, but a set can only hold a particular thingonce.

First some mathematics:

• a set can be enumerated:

p1 = {2, 3, 5, 7} // primes less than 10.p2 = {1, 3, 5, 7, 9} // odd numbers less than 10

• a set can be defined by a rule:

p1 = {i | i < 10 and i is prime} // primes less than 10.p2 = {i | i mod 2 ? 0} // odd numbers less than 10

• two sets can be united:

p3 = p1 p2 // {1, 2, 3, 5, 7, 9}

• two sets can be intersected:

p4 = p1 p2 // { 3, 5, 7}

• one set can be a subset of another:

p3 p4

• one can test for set membership:

3 p3

229

Page 230: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

230 CHAPTER 29. SETS

Mathematical sets can be assembled from anything, even other sets. Afamous one at the heart of Russel’s paradox:: is the set of all sets which notmembers of themselves a member of itself? In Java one has sets which arebased on integers. These are called BitSets.

29.2 The class BitSet

A bitset is a set of fairly small (¡ 232 - 1) positive integers. It is much morerestricted than a mathematical set but can still be extremely useful. TheJava implementation is not as elegant as that of Pascal (Pascal sets are builtinto the syntax of the language, Java bitsets are just a library class).

The way bitsets are implemented is that a block of memory is set asidefor the bitset. Each bit of the memory block represents the presence orabsence of an integer. For example, the set 1, 20, 101 can represented by achunk of memory where all bits are zero except bits 1, 20 and 101. Becausean integer can only be present in a set once we only need one bit to representit.

The operations on sets (union and intersection) can be performed bybitwise operations. A little reflection should convince you that set union isequivalent to bitwise or and intersection is bitwise and.

As before, I shall demonstrate bitsets with a program to show them inoperation:

package pij.sets;

import java.util.BitSet;

public class BitSetDemo1 {

public static void main(String args[]) {// First a default constructorBitSet smallPrimes = new BitSet();

// Then one with an initial size// BTW, to remove an element use the similar method clearBitSet smallOdds = new BitSet(10);

// Now set up the first setsmallPrimes.set(2);smallPrimes.set(3);smallPrimes.set(5);smallPrimes.set(7);

System.out.println("smallPrimes = "

Page 231: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

29.3. CREATING A CHARSET CLASS 231

+ smallPrimes.toString());

// This printed: smallPrimes = {2, 3, 5, 7}// Now the other one (I won’t bother printing it)smallOdds.set(1);smallOdds.set(3);smallOdds.set(5);smallOdds.set(7);smallOdds.set(9);

// Now we find the odd small primes// First make a cloned copy of smallPrimes-// need to use a castBitSet oddSmallPrimes = (BitSet) smallPrimes.clone();

// Now intersect it with smallOddsoddSmallPrimes.and(smallOdds);System.out.println("oddSmallOddPrimes = "

+ oddSmallPrimes.toString());

// This printed: oddSmallOddPrimes = {3, 5, 7}// We can compare sets for equality by using equal (answer false)System.out.println("Comparison gives "

+ oddSmallPrimes.equals(smallPrimes));

// Finally we can test for a particular member (prints true)System.out.println("get gives " + oddSmallPrimes.get(5));

try {System.in.read(); // prevent console window from going away

} catch (java.io.IOException e) {}

}}

This example shows what methods there are in a bitset but not how touse one. That comes next.

29.3 Creating a CharSet class

I am going to make a new class called CharSet which is based on BitSet butwhich makes handling sets of characters easier. I shall then go on to showhow this might be used. We don’t have to create a new class but it makeslife a lot easier.

Page 232: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

232 CHAPTER 29. SETS

Things I want to do are:

• I want to turn a string into a set.

• I don’t like and, or and get because they are not the same as themathematical terms. I prefer intersect, unite and contains so I shallcreate methods with these names.

• I want to print a set of chars fairly easily.

My class definition is:

package pij.sets;

import java.util.BitSet;

/*** A class based on BitSet but which makes handling sets of* characters easier.* <p>* Things I want to do are:* </p>* <ul>* <li>I want to turn a string into a set.</li>* <li>I don’t like ’and’, ’or’ and ’get’ because they are not* the same as the mathematical terms. I prefer intersect, unite* and contains so I shall create methods with these names.</li>* <li>I want to print a set of chars fairly easily.</li>* </ul>*/

class CharSet {final int maxChar = 127; // ASCII only, Unicode later

private BitSet theSet_ = new BitSet(maxChar);

public CharSet(String theChars) {int length = theChars.length(); // Avoid unneeded callingfor (int i = 0; i < length; i++)

theSet_.set(theChars.charAt(i));}

public void set(String theCharSet) {theSet_ = new BitSet(maxChar); // Get rid of old setint length = theCharSet.length(); // Avoid unneeded

// calling

Page 233: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

29.3. CREATING A CHARSET CLASS 233

for (int i = 0; i < length; i++)theSet_.set(theCharSet.charAt(i));

}

public void set(char ch) {theSet_.set(ch);

}

public boolean contains(char ch) {return theSet_.get(ch);

}

public void clear(char ch) {theSet_.clear(ch);

}

public void unite(CharSet theSetToAdd) {theSet_.or(theSetToAdd.theSet_);

}

public void intersect(CharSet theSetToIntersect) {theSet_.and(theSetToIntersect.theSet_);

}

public String toString() {String theString = "{";int size = theSet_.size();for (int i = 0; i < size; i++)

if (theSet_.get(i))theString += (char) i;

return theString + "}";}

public boolean equals(CharSet right) {return theSet_.equals(right.theSet_);

}

}

The following method demonstrates its use:

CharSet vowels = new CharSet("aeiouAEIOU");

// Print a set - prints: vowels = {AEIOUaeiou}

Page 234: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

234 CHAPTER 29. SETS

System.out.println("vowels = " + vowels);

// Add a character - prints: vowels = {AEIOUYaeiouy}vowels.set(’y’);vowels.set(’Y’);System.out.println("vowels = " + vowels);

// Remove a character - prints: vowels = {AEIOUaeiou}vowels.clear(’y’);vowels.clear(’Y’);System.out.println("vowels = " + vowels);

// Set to a string - prints: vowels = {AEIOUYaeiouy}vowels.set("AEIOUYaeiouy");System.out.println("vowels = " + vowels);

// Test unite: - prints: vowels = {ADEIJOUXYZadeijouxyz}CharSet polishVowels = new CharSet("XxZzJjDd");vowels.unite(polishVowels);System.out.println("vowels = " + vowels);

// Test intersect: - prints: vowels = {adeij}CharSet firstTen = new CharSet("abcdefghij");vowels.intersect(firstTen);System.out.println("vowels = " + vowels);

// Test equals: - prints: true falseSystem.out.println(" " + vowels.equals(vowels) + " "

+ vowels.equals(polishVowels));

// Test contains: - prints: true falseSystem.out.println(" " + vowels.contains(’a’) + " "

+ vowels.contains(’m’));

29.4 Using the CharSet class

The following program uses the CharSet class to help to conjugate Frenchregular verbs in the present indicative.

package pij.sets;

/*** Program to conjugate French verbs. Present indicative and* regular. So what do you expect? Irregular imperfect

Page 235: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

29.4. USING THE CHARSET CLASS 235

* subjunctives?*/public class ConjugateFrench {

private static void conjugate(String theVerb) {int verbGroup = groupOf(theVerb);String verbRoot = rootOf(theVerb);CharSet vowels = new CharSet("aAeEiIoOuU");boolean startsWithVowel = vowels.contains(theVerb

.charAt(0));

for (int conj = 1; conj <= 6; conj++) {System.out.print(pronoun(conj, startsWithVowel)

+ " ");System.out.print(verbRoot);System.out.println(endingFor(conj, verbGroup));

}System.out.println();

}

private static int groupOf(String verb) {switch (verb.charAt(verb.length() - 2)) {case ’e’:

return 1;case ’i’:

return 2;case ’r’:

return 3;}return 0; // Shouldn’t happen

}

private static String rootOf(String verb) {return verb.substring(0, verb.length() - 2);

}

private static String pronoun(int person,boolean needsJapostrophe) {

String[] pronouns = { "je", "tu", "il", "nous", "vous","ils" };

if (person == 1 && needsJapostrophe)return "j’";

elsereturn pronouns[person - 1];

Page 236: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

236 CHAPTER 29. SETS

}

private static String endingFor(int person, int group) {String[][] ending = {

{ "e", "es", "e", "ons", "ez", "ent" },{ "is", "is", "it", "issons", "issez", "issent" },{ "s", "s", "", "ons", "ez", "ent" } };

return ending[group - 1][person - 1];}

public static void main(String args[]) {conjugate("aimer");conjugate("passer");conjugate("rendre");conjugate("finir");conjugate("etre");conjugate("avoir");conjugate("pouvoir");

}}

Notice the way a CharSet is used to decide whether to write je or j’.The output (edited to save space) is:

j’ aime je passe je rends je finistu aimes tu passes tu rends tu finisil aime il passe il rend il finitnous aimons nous passons nous rendons nous finissonsvous aimez vous passez vous rendez vous finissezils aiment ils passent ils rendent ils finissent

j’ ets j’ avois je pouvoistu ets tu avois tu pouvoisil et il avoit il pouvoitnous etons nous avoissons nous pouvoissonsvous etez vous avoissez vous pouvoissezils etent ils avoissent ils pouvoissent

Don’t you wish it were really like that?

Page 237: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 30

Stacks

30.1 Stack basics

We have looked at a number of classic data structures such as arrays, vectors,lists, trees and sets. The final ’classic’ we shall look at here is the stack.A common metaphor for describing a stack is the spring loaded plate stackoften found in a cafeteria.

With these devices one can only add or remove a plate from the top andso it is a Last-In-First-Out (LIFO) device. The operations for manipulatinga stack are traditionally called push (place an item on the top of the stack),and pop (remove and return the top item). There is also the operation ofinspecting the top element; it isn’t universal usage, but we shall call thisoperation peek (because that’s what Java calls it).

Stacks can be based on arrays, vectors or linked lists (the Java imple-mentation uses vectors) but the implementation details are not importantfrom the point of view of the user of the stack; the user thinks in terms ofthe abstract operations (push, pop, peek).

30.2 Benefits of abstraction

Beginners often have trouble understanding why, if we have a collection ofdata, we should restrict ourselves to accessing it only in specific ways. Forexample, we can only put an element on a stack at the top. Wouldn’t it bebetter to allow us to put an element where we like?

There are two responses to this: firstly the stack operations can beimplemented very efficiently and map directly to a number of ’real world’problems; secondly, when such a mapping exists it is very beneficial to thinkonly in terms of the abstract operations and hide the implementation details.

237

Page 238: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

238 CHAPTER 30. STACKS

30.3 Applications of stacks

So what are those ’real world’ problems I hear you cry? Well here are a few.Hewlett-Packard calculators: These don’t use an algebraic notation. For

example, to evaluate 2x3+4 one doesn’t type it like that; instead one enters:

2 (enter) 3 (enter) x 4 (enter) +

At each stage the current answer is displayed on the screen. Anotherway of entering the same calculation would be:

4 (enter) 2 (enter) 3 (enter) x +

This notation has the advantage that it is priority and parenthesis freeand is a form of reverse polish notation (RP to its friends).

Toy borrowing: This one is from Arnold and Gosling’s book . A chainof children borrow toys from one another. If one child borrows a toy it mustbe returned to the lender. Therefore if Mary lends to Josh, who lends toTang, who lends to Esther then Esther must return the toy to Tang, whoreturns it to Josh. Josh might, at this point, relend to Hamid who lends toKebir.

This whole process can be managed as a stack where each borrowingpushes a name on the stack and each return pops a name.

Memory management: Most modern languages have some form of blockstructure. This is implemented as a stack in the computer’s memory. Whenyou call a Java method its local variables and arguments are given a space(called a stack frame) which is pushed on to what is known as the runtimestack at the point where the method is called. When the method finishesthis block of memory is popped. This approach to memory handling is veryefficient in time (it requires only a few machine instructions to push/popeach stack frame) and in space (memory released when a method ends isavailable for re-use).

Parsing languages with nested structures: Most computer languages havesymbols that must be matched in pairs. Examples are:

Java: { }, ( ), [ ], /* */Algol68: ( ), begin end, if fi, case esac, [ ], do od

Ensuring that matching symbols are used correctly can be easily achievedwith a stack. Detail will be left to you because there is an exercise on this.

My in tray: a letter arrives and is placed on top of all the other letters.When I get time I deal with the top letter, then the one under it and so on.New mail goes back on top.

This ensures that the earlier I receive something the later I shall dealwith it. This creates problems, not least with France Telecom, and EDF-GDF. I need another data structure (a priority queue) but I don’t know howto implement it on my desk.

Page 239: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

30.4. JAVA’S STACK IMPLEMENTATION 239

30.4 Java’s stack implementation

The Java utilities package provides a stack implementation called java.util.Stack.To use it you need to import the package.

You create a stack with a statement such as:

Stack myStack = new Stack();

Once you have your stack you can push things onto it with:

myStack.push(anObject);

You can see what is on top with:

anotherObject = (ClassOfAnotherObject)myStack.peek();

And you can remove the top element with:

yetAnotherObject = (ClassOfYetAnotherObject)myStack.pop();

If you try to remove an object from an empty stack it will throw Emp-tyStackException. You can prevent this by using the empty method:

if (myStack.empty())System.out.println("Oops");elsex = (String)myStack.pop;

If you want to find out how many elements down the stack a particularobject might be found you can use the search method.

i = myStack.search(someObject);

This returns a number with 1 being the top of the stack.

Page 240: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

240 CHAPTER 30. STACKS

Page 241: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Chapter 31

Threads

31.1 Thread basics

All the programs we have seen so far operate one step at a time, a verystrictly serial approach. A different model is that a set of different processes(maybe on one CPU, maybe shared between many CPUs) may be executingtogether.

Imagine a group of computer processes connected together with one blockof RAM shared among them all. It is easy to imagine each process runninghappily in its own little portion of the RAM and no great conflicts arising.However, when one wants the different processes to share a portion of RAMcertain problems immediately become evident: two processes cannot changethe same chunk of RAM at the same time because it may be a bad idea ifone process reads the RAM when another is busy writing to it.

The Java model of multiprocessing involves processes (threads) runningat the same time. If different threads need to share the same portion ofmemory they can forbid other threads from accessing that portion. Oth-erwise the runtime thread scheduler will share available resources amongstthe threads wishing to run.

Many systems, for example Unix, allow many processes to run at thesame time. However, switching from one process to another can be veryexpensive. The idea behind threads is that so called ’context switching’ isvery cheap and should involve only a few machine instructions. It is thusreasonable for a Java program to spawn many threads without sufferingintolerable performance consequences.

31.2 Threads in Java

You may not, by now, be astonished to find that a thread in Java is just aclass Thread. However, it is not just another class because it has syntacticsupport within the language. To begin, let’s look at a two thread program:

241

Page 242: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

242 CHAPTER 31. THREADS

package pij.threads;

/** Threads demonstration. */public class HeyHo extends Thread {

String word;int delay;

public HeyHo(String whatToSay, int delayTime) {word = whatToSay;delay = delayTime;

}

public void run() {try {

for (int i = 1; i <= 20; i++) {System.out.print(word + " ");sleep(delay);

}} catch (InterruptedException e) {

return;}

}

public static void main(String[] args) {new HeyHo("HEY", 5).start();new HeyHo("HO", 10).start();

}

}

Producing:

HEY HO HO HEY HO HEY HEY HO HEY HEY HO HEY HEYHO HEY HEY HO HEY HEY HO HEY HO HEY HEY HO HEYHEY HO HEY HEY HO HEY HO HO HO HO HO HO HO HO

Note what is happening:

• the method main starts two threads running, each with a different textto print and a different sleep time.

• There are rules about catching exceptions; in this case InterruptedExceptionmust be caught.

• Returning from a thread kills that thread.

Page 243: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

31.3. EXERCISES 243

31.3 Exercises

1. Explain why there are lots of HOs at the end of the output above.

Page 244: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

244 CHAPTER 31. THREADS

Page 245: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Appendix A

Glossary of terms

Algorithm Algorithm Named after Abu Ja’far Mohammed ibn Mussa alKhowarizm. Sorry, there are some other diacritical marks in there,but my computer refuses to type them.

Applet A program which can be transmitted from a server computer (nor-mally a World Wide Web server) to a client machine and which thenexecutes on the client machine.

Application A stand-alone program which runs on a computer withoutbeing copied from a server. Most programs you use on your computer areapplications.

Argument Used to pass a value to a method. Arguments are in paren-theses after method names. For example, println("Hello World") says“invoke the println method with "Hello World!" as an argument”.

Assignment is the process of storing a value in a variable. The assignmentoperator is =. A typical assignment statement is x = 2+3*y;

Block See compound statement.Cast Used to convert from one type to another. If x and y are floats

then (int)(x/y) will give an int result.Class A type from which objects can be created (instantiated). For ex-

ample, in String s; the variable s is an object of class String. Classes containmethods common to all objects created from them and instance variables(data values) which belong to each individual object. As a complicationclasses can also contain their own data values which are common to allderived objects.

Comment Text in a program that is ignored by the compiler; it conveysinformation to a human reader. In Java comments may be enclosed in /* ...*/ or between // and the end of the line.

Compiler A program (such as CodeWarrior) which reads a program insome programming language such as Java and which translates it into the

245

Page 246: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

246 APPENDIX A. GLOSSARY OF TERMS

machine code of some computer. It also indicates syntactic and semanticerrors.

Compound statement A sequence of statements enclosed in curly brack-ets . A compound statement can be used anywhere where a statement isrequired. Also known as a block.

Constant variable A variable with a value that cannot be changed. e.g.final int size = 27;

Constructor a method that is used to construct an object of a class. Ithas the same name as the class e.g the class Font has a constructor Font(...).

Control statements are language statements such as if, switch, for etc.which change the order in which the statements in a program are executed.

Declarations are statements which create variables. For example, int a,b, c;

Event driven programs Programs built around a GUI are structured inthis way. The programs waits until an event (mouse click, menu choice etc.)occurs. They then choose an appropriate action. Such programs generallyhave a loop called the event loop which is the main activity of the program.In many modern languages, Java included, the event loop does not needto be written by the programmer; it is built into the fundamental runtimesystem.

Expression A combination of operators, operands and parentheses whichcalculates some value.

Function A subprogram (part of a program). Methods of classes in Javaare actually functions built into the classes.

Identifier A name for a variable, constant, function, class etc. Identifiersmay contain letters, digits and the underscore character.

Inheritance All classes in Java are derived from other classes. To derivea class you inherit it using the extends keyword. The root class in Java isObject.

Instance A particular object (or other thingy) derived from a generalclass.

Instance variable A data member that belongs to an object of a class.To refer to the instance variable soap of the object joe you write joe.soap.

Memory The active, purely electronic storage area in your computer. Itis very fast and is lost when you turn off.

Method A function that belongs to a class; something that a class cando. In ’proper’ object oriented parlance one invokes a method by sending amessage to an object. For example, the statement myShape.draw() is saidto ’tell myShape to draw itself’.

Multithreading A thread is an independent process that can run at thesame time as other threads. Control can switch from one thread to anotherwith little overhead. When a thread needs to ensure it can run withoutinterruption it can be declared to be synchronised.

Object A particular instance of a class. See the definition of class above.

Page 247: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

247

Object oriented Much misused buzzword. As an approach to program-ming it is generally regarded as involving the following ideas: classes whichcontain (encapsulate) data and methods that define the behaviour of de-rived objects, objects of those classes, polymorphism (the ability of differentobjects to respond to the same message in different ways appropriate tothemselves) and inheritance .

Operand In an expression such as 2 + a*b, the operands are 2, a and b.The operators are + and *.

Operator Symbols such as +, *, ¡¡ etc. which join operands together inan expression.

Overriding Replacing a method of a class with your own method.Parameter The place holder for an argument in a method. For example,

void sin(float theta) defines sin to have a parameter theta.Peripheral An external physical device such as a printer or hard disc.Pixel The smallest unit of space on a screen. Pixels are numbered left

to right and top to bottom.Polymorphism The ability of different objects to respond to the same

message in different ways appropriate to themselves. For example, differentobjects might have an area method but would respond differently to itsbeing invoked.

Processor The portion of the electronics in a computerwhich obey theactual program. These days this is often a single chip.

Reserved Words Symbols such as if, switch, class etc. which have specialmeaning in a language and cannot be redefined by a programmer.

Sand box Java applets run in a protected environment called the sandbox which restricts access to facilities on the client computers such as discfiles, non-Java devoted RAM etc.

Semantics The meaning of a program construction.String A string is a sequence of characters in double quotes e.g ”John le

Carre”.Syntax The grammar of a language. The syntax of a statement, for

example, describes the legal forms that a statement can take.Thread See multithreading.Variable A named location in the computer’s memory. Variables are

created by declarations.

Page 248: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

248 APPENDIX A. GLOSSARY OF TERMS

Page 249: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

Appendix B

Writing about your work

I want to be a technical writer, technical writer. . .

or

That which is written without pain is seldom read with pleasureDr Samuel Johnson

B.1 Introduction

This is not an English course, but it might help to know something of howto present your work. For most of your projects you will have to prepare areport and when you get into what is, rather risibly, called “the real world”,you will have to spend more time writing about what you are doing thanactually doing it. What I want to present here are a few rules and princi-ples that always apply to writing and a few points specially for computerscientists.

B.2 Reading is the best way to learn to write

Donald Knuth invented the term literate programming. Read Knuth. Heeven has made tools to help.

One of the greatest programmers ever is Edsgar Djikstra. He wrote thefirst Algol compiler (I think), a significant operating system, and producedmany superb algorithms, as well as being the man behind structured pro-gramming. He is Dutch, but writes English like a native. Let this be alesson: if you know what you want to say, and you know your material, thenthe language will put itself together. If you write nonsense it’s your fault.

Also in the structured programming stable you should read Tony Hoare.This is the chap who created quicksort and one of the major styles of con-current programming.

249

Page 250: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

250 APPENDIX B. WRITING ABOUT YOUR WORK

When you read these authors you will find they use a fair amount ofmathematics. As Knuth and Hoare are mathematicians and Djikstra is atheoretical physicist, which means the same thing really, you will not besurprised. Learn to use mathematics. Don’t be afraid of it. An equationcan be worth a thousand bytes.

B.3 Nitty gritty

First of all I would like to deal with mechanics. If you can handle a fewbasic ideas your documents will start to look like proper material. This isnot my bailiwick (use an unusual word from time to time, if you know whatit means and it adds color, but don’t overdo it. Well, I almost always overdoit, but I ain’t a good example (never use slang)).

On typography there is an excellent book by Robin Williams (no rela-tion), called ”The Mac is not a Typewriter”, published by Peachpit Press.Some of her principles are given below:

Use a sensible font This document is written in Baskerville with Courierfor the programs. You can look silly if you use Zapf Chancery for regularwork but it may be nice for invitations or cute effects. Helvetica is alsopopular. Times has little decorative bits and Helvetica doesn’t: Helvetica issans serif and Times is serif. Most fonts are proportional, which means thatletters like M take more space than I. Courier is based on those old electrictypewriters and every character takes the same space. That is why it ishandy for programs and tables. It looks silly for letters and term papers.

Choose a reasonable size This is in ten point. A point is 1/72 of an inch.Most books are ten or eleven point. Twelve point looks overly chunky andanything larger looks ridiculous. Your profs are aware that if you type likethis it isn’t because you have a sensitive concern for their ageing eyes; it’sbecause you don’t have anything to say but want to stretch it over as manypages as you can.

Don’t use too many fonts unless you really know what you are doing. Itcan make your work look excessively fussy.

No space before punctuation, one space after This applies to full stops aswell as anything else. People brought up on typewriters often have the habitof putting two spaces after full stops, question marks etc. Typesetters nowregard this as a Bad Thing because it upsets the flow of nice proportionalfonts.

Paragraphs You can indent the first line of a paragraph or leave a blankline before it. Don’t do both. Indent modestly: about the size of threecharacters is enough. Some publishers tell you to use indents because blanklines take more paper. They also tell you not to indent the first line after aheading; I have followed that style here.

Never use the space bar for layout If you do, then reformat your text, you

Page 251: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

B.4. WRITING THE STUFF 251

will find all your layout needs redoing. Use the ruler of your word processor.Use hanging indents This is done by splitting the left margin marker on

the ruler. It can save a lot of work when you change the layout of yourdocument.

Explain acronyms I recently had a problem with my WWW connection.It emerged that when I changed my PPP software I lost the DNS IP addressin my TCP/IP control panel. Did you get that?

Better: It emerged that when I changed my Point to Point Protocol(PPP, the protocol that handles the serial connection via my modem) soft-ware I lost the domain name server (DNS) Internet protocol (IP) address inmy transfer control protocol (TCP/IP, the protocol of the Internet) controlpanel.

This still isn’t pretty but it increases the chances of a non-anorak un-derstanding it. Instead of explaining terms in the text you may prefer touse footnotes or a glossary at the end of your document, but always expandacronyms in the text the first time you use them.

Limit jargon All specialities have jargon. Sometimes it is necessary toallow experts to communicate at all effectively among themselves: ”A systemof two identical fermions such as protons or neutrons, must, according to thePauli principle, be described by an antisymmetrical complete wave function,that is, one that changes sign on interchange of the two particles” . Thislanguage assumes that the reader has done a lot of study in the field; it isessential when highly technical material is communicated between experts.

Sometimes jargon is used to define members of an in-group and an out-group. There is a classic list of such jargon on the Internet. Called theJargon File it originated at MIT but is now available from many Internetsources.

Finally jargon is used to obfuscate. If someone wants to create theimpression he knows more than he does, or has thought more deeply thanhe has, he may dress up his text with obscure words or phrases. There aretoo many examples out there for me to need to give any here.

Know what you are writing about

It isn’t pollution that’s harming the environment. It’s the impu-rities in our air and water that are doing it.

- Vice President Dan Quayle

[It’s] time for the human race to enter the solar system.

- Vice President Dan Quayle

B.4 Writing the stuff

(Notice that I did not take a blank line here, nor an indent). Now we getto what you should write: you may have to write several different kinds of

Page 252: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

252 APPENDIX B. WRITING ABOUT YOUR WORK

reports: technical reports describing how your programs work; user manualsdescribing how to use your programs and research reports describing theconclusions you draw after a piece of speculative work.

There are similarities with reports you write for courses in other sub-jects: you must avoid plagiarism, footnote all your sources, write clearEnglish, structure your work appropriately, explain technical terms whenappropriate, use technical terms with great care and so on.

B.5 Technical reports

Background This type of report is appropriate when you have been given afairly well defined problem such as the bridge bid problem earlier. Try topitch it at the level of a textbook (you’ve read lots of those so you knowwhat they’re like).

Start with an abstract This should explain, in three of four sentences,what the project is to do and what success you had. For example:

This project had, as its objective, the construction of a program to usehistorical, stochastic analysis to predict the results of the National Lottery.The project has been a complete success and the author has now retired tothe Cayman Islands.

Describing the success of the project is crucial; it allows your professorto read the report with the knowledge of how it turns out. Reading a reportis done in one of two frames of mind: either one is looking for the crucialerrors or is just making comments and suggestions for improvement. It helpsto know at the start.

Explain your algorithm at a suitable level of abstraction For example, inthe description of the bridge algorithm I start with a diagram to show thedata structures I intend to use. Then a description in words and mathemat-ics:

Assessing a hand requires finding the strongest suit, where strength isdefined in such a way that point count is the most important criterion, thensuit length and finally suit. If we associate an integer with each suit, rangingfrom CLUBS = 0 to SPADES = 3 then we can represent the strength of thecards present in any suit by a number S calculated from the formula:

S = 1000p + 100q + r

where p is the point count, q is the number of cards in the suit and r isthe integer associated with the suit.

This formula gives an appropriate weighting to each of the three factors.This makes assessing a hand simple: for each suit in the hand calculate thelength, the point count and then the S factor. The suit with the highest Sfactor is the strongest.

Page 253: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

B.6. USER MANUALS 253

Notice how there is very little use of program code. In fact, the descrip-tion of an algorithm and data structure should almost always be independentof the language used.

Sometimes students write something like: “I shall use if structures tochoose the best value and then a for expression to output the results”. Thisis a) at too low a level of detail and b) misuses technical words - thereare no such things as ’if structures’ or ’for expressions’ - these things arestatements.

You don’t have to explain standard algorithms or data structures. Forexample, if you intend to use the classic pattern matching algorithm byBoyer and Moore you can write something like ”the Boyer and Moore algo-rithm will be used for finding the substrings”.

Give examples of output in the report or maybe in an appendix.Assemble the whole into one document Instead of lots of separate sections

put it all together into one stapled or bound volume. This makes it mucheasier to handle.

B.6 User manuals

Since I first worked in the computing field the quality of user manuals hasincreased enormously. Good examples to take as models are produced byClaris and by Adobe. Examples of what you don’t want to do can be foundin almost any Unix manual or IBM mainframe OS manual.

Write for a non-technical reader User manuals are for people who don’tknow anything about computing. Don’t use jargon, explain all terms. Gostep by simple step.

Use screenshots Rather than explain what is supposed to appear on thescreen, give a screen shot.

B.7 Research reports

You will sometimes carry out research projects where the purpose is toinvestigate various approaches to a problem. In this case there may be nofinal program but a set of conclusions perhaps comparing the advantages ofdifferent methods. The reports are similar to technical reports (the abstractis essential) but some extra things are likely to be needed:

A bibliography covering other research is usual (and can involve a lot ofwork). This is best included as end notes. Scrupulous footnoting of all workyou use is essential; careers have been destroyed by weakness in this area.

Introduction covering earlier work Research is not in a vacuum; thereis previous work in the field published in the literature. The report shouldhave an introduction section covering this material in adequate detail.

Page 254: Programming in Java 1 · Programming in Java 1 David Masters January 27, 2007 1A work in progress.My father David passed away in 2005 with this book almost finished. I felt that

254 APPENDIX B. WRITING ABOUT YOUR WORK

A conclusion summarising the results of the research and suggestions forfuture research.

B.8 Conclusion

From this point you will be expected to write a report for virtually all thework you submit. You have had to do that already but rather informally.In future the report will be an important part of the grade on every pieceof work.