Java
The First Step ... 4
Basic Programming Ideas ... 6
Command line programming ... 7
Installing and Using an IDE ... 10
Writing Your Own Programs ... 12
How Java works ... 14
Data ... 16
Data types ... 17
Variables ... 18
Input and Output ... 20
Statements ... 23
The Three Frames of Programming ... 24
Expressions... 27
Increment decrement and short-cut ... 29
Conditional Statements ... 30 Algorithms ... 35 Loops ... 38 Testing ... 43 Data Structures ... 44 Bitwise operations ... 51 Using a Debugger ... 54 Type casts ... 57
Structured Programming ... 59
Static methods and parameter passing ... 60
Scope ... 64
Recursion ... 66
A first look at Swing ... 80
The Java API ... 83
Subclassing ... 84
Variables and values ... 87
Wrapper Classes... 94
Overloading ... 95
Inheritance ... 98
The Object class ... 100
Overloading and overriding ... 102
super ... 103
this... 108
static ... 110
Date and Time in Java ... 115
Interfaces ... 119
Event handling ... 121
Defining a new class ... 124
Projects and Packages ... 126
Encapsulation ... 128
Writing new classes - a personnel system ... 130
Writing New Classes - Tic Tac Toe ... 140
Binary Trees ... 146
Hash tables ... 151
Swing ... 155
Starting a Swing application ... 156
Swing event handling ... 157
Swing containers ... 161
Swing widgets ... 168
Images ... 170
Color ... 172
Fonts... 173
Menus, Popups andToolbars ... 174
Swing and MVC ... 177
Inheritance - a GUI Tic Tac Toe ... 181
More OOP ... 192
abstract ... 193
Annotations ... 198
Nested Classes ... 200
Generics ... 205
The Collections Framework ... 211
Enums ... 216
Exceptions ... 218
Multi-threading ... 225
Classes and types ... 237
Input and Output ... 241
Reflection ... 249
Networking - UDP ... 251
Networking - TCP ... 256
The First Step
This is intended for people who are learning Java and who have never programmed before.
Java is a big deal. Learning to program in Java is not like learning wordprocessing or learning how to
use a graphics program or editing a video. Such applications try to be as easy as possible to use. Java is a language which was designed to be used by experienced professional programmers who were experienced in coding in C. It was designed to be the best possible general-purpose language, designed on the basis of around 50 years development of programming languages. It was designed to be the best, not the easiest.
So expect to take this seriously, expect to have to think hard, and expect to spend considerable time learning it - mostly by using it to write programs. An undergraduate might expect to learn basic Java over their first year. They might follow more advanced topics over the next two yeas.
You will find it easier if you also learn basic computer science at the same time - compilers
interpreters and syntax, algorithms and data structures and so on. This will help to make more sense of many of the topics.
Try out the code in the book. It is easiest and faster if you copy and paste it from an electronic version. Try and make small changes, and see what happens. Write lots of your own small programs. If things won't work - look at the chapter about debugging.
What is Java?
Java is a general purpose programming language, designed by a small group working at Sun MicroSystems. Any further description would not make sense until you learn more of the concepts involved.
What to read first
You could start at the beginning and read it to the end. Or you could start at the end, but this is not recommended.
The inter-relationships between the concepts in Java mean it is not possible to order the
presentation into a single line. So you might read a section with partial understanding, read on, then go back and re-read with more understanding. In fact you should.
The reason for this is that Java was designed so that experienced programmers could learn it quickly. But they already had a significant set of concepts already developed. If you are a beginner, you do not, and so you will probably have to go back and forth.
There are five main sections:
Basic programming ideas - including setting up your computer to write and run Java Structured programming
Swing - writing GUI programs in Java More OOP - not so basic OOP ideas. What else to read
There is a great deal of Java material on the web. Some is good, most is not.
The most reliable material is from Oracle (who took over Sun). 'The Java Programming Language' by Arnold, Gosling and Holmes is the key text, but not the easiest. 'The Java Language Specification' sets out formally the language. This is a free download, but is not for beginners. 'The Java Virtual
Machine Specification' is another free download but again is not for beginners.
Oracle offer an on-line set of tutorial 'Trails'. These are more suitable for people converting from other languages.
Useful Links
Where appropriate, links to reliable learning materials are given. Some key links follow. These are not suitable for total beginners, but bookmark them now:
The Java SE 7 API
The Java 7 Language Specification Java 7 Virtual Machine Specification The Oracle Java Tutorials
Java 7 SE Documentation
Basic Programming Ideas
This part is mostly about what a computer program actually is, how you can work out what a program will do, and how you write one.
Some people think these ideas are obvious. Others do not, and so programming makes no sense to them, and they quickly drop out. Many courses do not address these ideas.
If you are new to programming, read this carefully.
This part also leads you through what to install on your computer and how to set it up so that you can write and run Java programs.
Command line programming
This section is about setting up a computer and writing a first Java program using the 'command line'. Most people think this is the best way to start. The details here assume you are using
Windows. If you use Linux or another OS, the principles are the same but the details are different - use Google.
Follow through this tutorial as you read it. You need to:
Use a text editor, such as Notepad, to write the source code. You save this as a file with the extension .java.
Use the compiler to compile it into a bytecode file, with the extension .class. You might get error messages at this stage.
Use the JRE to execute the bytecode. Error messages are also possible here.
You need to have the compiler and other tools installed – this is called the software development toolkit ( JDK ). This is a free download from the web. Google Java JDK. You want Java SE (Standard Edition) not J2EE (Enterprise Edition). The JRE (to run Java) is bundled with the JDK (to write Java). Select the one matching your OS – Windows, Linux, Mac or Solaris.
Once you have installed the JDK, we can start using it, as follows:
To get to the command line (on Windows XP) go Start.. Accessories.. Command Prompt. (On Windows 7, go Start..All
programs..Accessories.. Command Prompt.) You will see a window with a black background and a prompt like C:\Documents and
Settings\Walter Milner> Type in the word java and press Enter. In other words you would see:
C:\Documents and Settings\Walter Milner>java
and you hit Enter (things you type are in yellow). You should get lots of lines of help messages listing options. We are just checking you have the JDK correctly installed.
If it says ‘Not recognised’, check the download and installation, and also the 'path' setting. The path Command line interface
depending on the version. Check you have this, then make sure this is included in the list of
folders in the path. Google how to
set the path for your version of Windows.
Type in cd Desktop
This changes directory to your Desktop.
Type in notepad
This will start Notepad, the text editor, running. In Notepad type in the following: public class ProgramOne
{
public static void main(String[] args) {
System.out.println("It works"); }
}
Type it exactly as it is here. The best way if possible is to cut and paste it. It must be capital P for ProgramOne, capital S for String, capital S for System. Each bracket must be the correct type. The quotes must be double “ not single ‘.
Then save this, in the Desktop. The filename must be ProgramOne.java – note the capital P. Click back at the command line. Type in
dir *.java
This means list all the files ending in java. You should see your file ProgramOne.java listed. If not you have saved it in the wrong place.
Next type in
javac ProgramOne.java
javac is the Java compiler. You are telling the compiler to compile your file ProgramOne.java into bytecode. You might get an error message. If so, read it very carefully – it will tell you the line number where the error is. Go back to Notepad, find the line and correct it. Save it again and run the compiler. Repeat until you get no error message.
Type in dir *.class
which lists all files ending in class. You should see ProgramOne.class, which is the bytecode produced by the compiler.
Then type in java ProgramOne
Check capital P. This invokes the JRE and executes your bytecode. You should see It works
You have now started. You are no longer maggots.
You can write all your Java code like this – use Notepad to write it, compile it with ‘javac’ and run it with ‘java’.
Summary
To write and run Java programs at the command line, you need the JDK and the JRE, which are free downloads.
Exercise
Installing and Using an IDE
An IDE is an 'integrated desktop environment'. This is a piece of software which includes an editor, in which you can write your source code, and the ability to compile and run the code from one button. They also include many other features, which take a long time to explore - probably you will not use some of them. It is suggested you start with the basic usage described here, and progress on a need to know basis.
There are two common (and free) IDEs - NetBeans and Eclipse.
Netbeans
Google NetBeans, and download the latest version for your OS. This will include the JRE. For a first try-out, do the following:
Run NetBeans
From the menu, go File.. New project.. Choose category Java.. Java application..Next.. Project name
ProgramOne .. Create main class yes, and set as main project yes, then Finish
You should see something like on the left. The right-hand pane headed Main.java is
your source code. The ‘syntax colouring’ helps you see what is what. On the left you see your projects, with the Source packages containing the package programone,File..New.. Java Project and inside that, the source code Main.java.
Make a small change to the source code, like this: public static void main(String[] args)
{
System.out.println("It works"); }
so you just change the TODO line.
NetBeans 7.1.2 running on openSUSE Linux
Then compile it and run the bytecode by clicking the green triangle button under the menu. You’ll either get an error message, or towards the bottom of the screen, a pane headed Output will appear, saying “It works”.
This has set up a 'project'. This is a set of source files - in this case, just one, called Main.java, but for typical projects there will be several. There might also be additional 'libraries' of system code which your project uses, and maybe resources like image or sound files.
Using Eclipse
Google Eclipse downloads. You want Eclipse for Java Developers. Download and install it. For your first try-out, start Eclipse,
then go File.. New.. Java project..Project Name programone.. Finish.
Then go File..New..Java class.. Name Main, check public static void main. You should see:
The source code editor pane is on the right. Make a small change to the source code, like this:
public static void main(String[] args) {
System.out.println("It works"); }
so you just change the TODO line.
Run it by clicking the green arrow button under the menu. Towards the bottom you will see a pane headed “Console”, which should say “It works”.
How to carry on
You can use the code in the following sections, and write your own, by just changing the source code. At the command line you need to save, compile and run it. In NetBeans or Eclipse, just change the source code and run it.
Summary
Writing Your Own Programs
Here is a Java program to use as a model for your programs: class MyProgram
{
public static void main(String[] args) {
System.out.println("Hello"); }
}
Modify this like :
Write your code to replace the System.out.println as shown.
The class name ( MyProgram ) must match the filename it is saved in, including capitalisation. So the class MyProgram must be save in the file named MyProgram.java.
Using the command line
1. Use Notepad or any text editor to write the program.
2. Save it with the correct filename. If the class name is ProgramTwo, save it as ProgramTwo.java 3. Compile it by typing javac <filename>. So if you wrote ProgramTwo.java, say javac
ProgramTwo.java
4. Run it by saying java <classfile>. So if you are writing PrograTwo, say java ProgramTwo. Using NetBeans
In NetBeans, programs are written as groups of files called 'Projects'. Do as follows:
1. From the menu, go File.. New Project.. Java..Java application (Next) Project Name 'Whatever' , Create Main Class Test (or whatever), and Finish
2. In the editor pane you will see a source code file, public class Test (or whatever), and a public static void main. Write you code there.
3. To compile and run it, click the green arrow in the toolbar. Using Eclipse
Summary
1. Use the model given as a template for your own programs. 2. The filename must match the name of the class, and end .java
Exercise
Modify and run a program at the command line or using an IDE
How Java works
People use computers as if they were servants. But there are significant differences. Computers are very fast – like several thousand million operations per second
There are a very limited set of kinds of things they can do – like moving pieces of data around in memory, doing arithmetic, comparing data and so on
Processors seem to be like brains – but in fact they are electronic devices, which can input binary codes which are treated as ‘instructions’ and which are carried out – moving data and so on.
How computers work
Computers and all other programmable digital devices contain a processor. This is an electronic device which can recognise and execute instructions. An instruction is a very simple step - like moving data around in memory, doing arithmetic, comparing data and so on. These instructions are encoded as binary strings, like 0110 1101, and held in memory. The processor fetches one
instruction at a time from memory, decodes it, carries it out, and moves on to the next one. The processor will carry out around a thousand million instructions per second.
A program is contains a sequence of these instructions. A program is stored in a file, and must be loaded into memory before the instructions are carried out (because it would be too slow to read it in from file one instruction at a time). This is called machine code or native code.
Different processor chips have different instruction sets - so a machine code program for a Motorola chip will not work on a computer with an Intel chip.
Programs also use facilities provided by the OS (Windows or Linux and so on). This means the same program will not run on different OS.
Writing programs using machine code is extremely difficult and error-prone. Instead programs are normally written in a high-level language such as Java, which uses English words.
High-level language programs must be converted into machine code before they can be executed. This is done by a piece of software called a compiler. The program as you write it is called source code.
In fact Java from the start was based on the Internet, and so Java programs needed to work on a wide range of computers with different processors (and so different machine code) and
different operating systems (such as Windows, Linux, MacOS and Solaris). In other words Java is cross-platform.
But how to do this? The instruction sets of different processors are different - so how could the same Java program work on different processors?
Virtual machine, JVM). This was a piece of software which in effect ironed out the differences of different platforms, so that they all seemed the same. Each different platform has its own JVM, taking into account the hardware differences.
A Java application is compiled into an intermediate form called bytecode. A piece of software called the Java Runtime Environment (JRE) then executes the bytecode on the JVM.
This means the same Java program will run on a wide range of platforms. This is one of the most significant feature of Java. Compared with other languages, especially C and C++, it is slightly slower – but it has the big advantage that it will run unchanged on many different platforms.
EXAMPLE
Suppose you were planning to write a personal finance application which people could use to track their spending and saving. This could be a desktop application – in other words it would be a program which ran on the user’s computer, rather than on a server across the Internet. You plan to sell the application as a download from your website.
Do you use Java or C++? C++ would probably be slightly faster, but this is not a speed-critical application. If you use C++, you would need to write different versions for different types of computers – Windows machines, Linux, Macs and so on. By contrast, the same Java code would work the same on all these platforms, provided users have the JRE installed.
Having decided to use Java, you would write the program as source code. You would then need to compile it, producing bytecode. It is this bytecode which users would buy. They would download and install the bytecode. When this ran, the JRE would execute it on the JVM. Different types of
computers would have different JVMs, making them all seem the same and enabling the same code to run on different platforms.
Summary
1. Java source code is compiled into an intermediate form called bytecode. 2. Bytecode runs on a JVM
3. There are JVMs for different hardware/OS platforms
4. The same Java program will run on several different platforms
Exercise
1. Why do we need to use compilers?
2. Is the bytecode of a Java app different on different platforms? 3. What is a JVM?
Data
Computer programs deal with data. Here are some examples of data in different contexts:
Word processing - the text of the document, including font name and size and style, colour, spacing. Images and their psoitions. Page size, margin sizes. Most of this data is made of strings (sequences of characters) but some is numeric - like the size of margins. The data is in memory when the document is being edited, and otherwise placed in a file, usually stored on disc.
Email - the text of messages, the email addresses of contacts, dates and times of messages.
Graphics programs - an image can be represented in different ways, but the most common is to have a rectangle made of rows and columns of pixels. Each pixel will have three numbers representing the red, green and blue parts of the colour at that point. There might be a fourth number for how transparent the pixel is.
Browser - this handles a web page, which is a piece of text representing the page in HTML. The browser has to render the html and present a visual version of it.
Summary
programs handle data
data is held in memory or in a file
data is input (from a keyboard, mouse, a file, a network connection etc) and output (to a screen, a printer, a file etc).
Data types
In general data comes in different types - numbers, text and so on. In a programming language, the idea of data type is very important. In Java there are two kinds of types:
Reference types. These are about objects. More on objects and references later Primitive types. These are single values. This section is about primitive types.
An example of a primitive type is an int. This is short for integer - a whole number. The int type represents a positive or negative whole number. An int is held in 32 binary digits, bits, which is 4 bytes, of memory. This means there is a minimum value - about -2 billion - and a maximum, of +2 billion. The numbers are held using a method called two's complement (see bit-wise operations). Integer arithmetic is completely accurate.
Sometimes this range is not enough - or sometimes it is too much, so other types of whole number are available. Here is the complete set:
Name Memory usage (bytes) Minimum value Maximum
byte 1 -128 127
short 2 -32,768 32,767
int 4 -2,147,483,64 2,147,483,63
long 8 -9,223,372,036,854,775,808 9,223,372,036,854,775,807
Often we need numbers with decimal parts - what mathematicians would call rational numbers. In computing these are called floating point numbers. Two versions are available - float (in 4 bytes) and
double (in 8 bytes). Floating point arithmetic is slower than using integers, and in general it is not
completely accurate. This is because many numbers cannot be represented as a finite sequence of bits, in base 2.
In addition to numbers , there are two other primitive types.
boolean data has just two possible values - true and false. boolean data is used for logic.
char represents a character. Java uses the Unicode character set, which uses 2 bytes = 16 bits to represent each character.
Summary
Java operates with several different data types
Variables
Java programs handle data by using variables. Here is a program fragment which is pretty easy to see what it does: int x; int y; int z; x = 2; y = 3; z = x+y;
Clearly the program adds 2 and 3. In more detail:
The program uses three variables, named x y and z. The variables have data type int. The program starts by declaring these variables:
int x; int y; int z;
Variables must be declared like this, before they are used. The declaration tells the compiler what memory it needs to allocate for this data, how they will be referred to (their names) and what data type they are.
The three lines are three statements. These are declaration statements. All statements must end in a semi-colon ; if you miss that out, the compiler will give you an error message.
You can put statements on the same line: int x; int y; int z;
but this makes things harder to read - don't do it. You can declare variables of the same type together, like int x,y,z;
The program then has three assignment statements: x = 2;
y = 3; z = x+y;
An assignment statement assigns a value to a variable. The first statement gives x the value 2. The 2 and the 3 are literal constants. These are of type int - if you want type long, say for example 2L. The third assignment is different. 'x+y' is an expression. The compiler sets up code so that the values of x and y will be added, and the resulting value of the expression will be assigned to z.
Note that the calculation takes place at run-time, not compile-time. We can see that obviously z will be 5 - but the compiler does not actually work that out. It produces code which will do the addition, when the program runs.
A variable has three attributes - a name, a type, and a value. Once declared, we cannot change its name or its type, only its value. There is a fourth attribute, namely the address in memory where it is
held, but we cannot get or refer to that in Java - we do not need to. Also, this is an address in the JVM, not the physical machine.
Summary
Changing data items in a program are called variables Variables have type
Variables must be declared before use Variables can have values assigned to them Variables are held in memory
Exercise
1. Variables must be ……….. before use? 2. What is a 'literal constant'? Give an example. 3. Give an example of an 'expression'.
Input and Output
To start with we will look at output, to the 'console' - so this is just output of characters, not graphics.
This is done with a statement like System.out.println("A B C D E");
This outputs everything in the string enclosed by the double quotes, including the spaces. If we want to output a number, we can say it like
int x; x=4;
System.out.println(x);
We can output a string and a number like System.out.println("The value of x is "+x);
Note the string is joined to the variable by a +. Or two values: System.out.println("x = "+x+" and y = "+y);
println goes on to a new line after it has finished, but print stays on the same line. For example System.out.print("A");
System.out.print("B"); System.out.print("C"); would output
ABC
all on the same line. Input
We can have assignments like x=3;
which give variables constant values, known at compile-time. But we usually need to enable our programs to input data values at run-time. Wordprocessing, for example, means the user inputs data (text) when the wordprocessor software is running. This is what we mean by input.
Keyboard input can be done using a class called Scanner. For example: java.util.Scanner scanner = new java.util.Scanner(System.in); int x, y, z;
x = scanner.nextInt(); y = scanner.nextInt(); z = x + y;
System.out.println(z);
We will improve this program in three steps: Comments
A comment is some text which will be ignored by the compiler. Comments are used to say who wrote the program, when, why, what its supposed to do, and to explain obscure parts of code. There are two ways of having comments in Java. One is to start with /* and end with */. This can cover several lines. The other is a line comment, which starts // and goes to the end of the line. For example
/* A program to input 2 numbers and output the sum */
// create the keyboard input scanner
java.util.Scanner scanner = new java.util.Scanner(System.in); int x, y, z;
// input 2 ints x = scanner.nextInt(); y = scanner.nextInt(); z = x + y; // calculate sum
System.out.println(z); // output result
Import
The class Scanner is located in the package (group of classes) called java.util. Its fully-qualified name is java.util.Scanner. This tells the compiler where to find Scanner, and distinguishes it from any class also called Scanner in other packages. But its a lot of typing. Provided we say
import java.util.Scanner; then we can just say
Scanner scanner = new Scanner(System.in); so the whole thing is
import java.util.Scanner;
/* input 2 numbers and output the sum */ class Test {
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int x, y, z; x = scanner.nextInt(); y = scanner.nextInt(); z = x + y; System.out.println(z); } }
IDEs typically generate import statements for you - in NetBeans, right-click and choose Fix Imports. Program listings here will usually omit import statements.
User prompts
Scanner scanner = new Scanner(System.in); int x, y, z;
System.out.println("Enter a number, then Enter"); x = scanner.nextInt();
System.out.println("Now another"); y = scanner.nextInt();
z = x + y;
System.out.println(z); which produces, for example Enter a number, then Enter 3
Now another 4
7
Summary
As a program runs, data values can be input from the keyboard and other sources Results can be output to the screen or elsewhere.
Exercise
1. Change the program so it subtracts the two values. 2. Change the program so it inputs and adds three values. 3. What is the difference between println and print? 4. Give three reasons for using a comment.
Statements
A statement is an important part of Java code.
Previously we have seen three types of statement. The first is a declaration statement, like int x;
The second is an assignment statement, like z=x+y;
The third is a method invocation: System.out.println("Hello");
There are several other types of statements which we will meet.
In Java one statement is usually written on one line. It does not have to be, but code is easier to read if it is. The important point is that a statement ends with a ; semi-colon.
The Three Frames of Programming
When writing a program, or reading someone else's, there are three mental frames you need to think about. In other words, there are three areas you must pay attention to:
Program text
Changing variable values Input/output
The first one, program text, is obviously important - its what the program is.
The second means tracking how variable values change, as the code executes step by step. This is needed because when an early program step changes a variable value, this will in general affect what later program steps do. Some people think this is obvious, but some do not.
We will return to input/output later. For example: ( * means multiply) int x; int y; x=3; y=2*x; x=x+1; y=y*x; System.out.println(y); What will this program do?
We could guess, or try to work it out in our heads. An easier and more reliable way is to trace it - track what will happen step by step, in the program code and in memory.
In the table alongside, on the left we see what values we have in memory, after each step. On the right, we see the program text. The step which has just executed in shown in yellow. We have to be careful – are we looking at memory before it has executed, or after? In this table we see the memory contents after that step. Look at this table very carefully. Make sure you understand everything it shows.
We will use this technique of tracing to see what more complex program structures do. With experience you will be able to think about how program text and memory affect each other with ease.
Variable exchange
As an example - how can we exchange the values of two variables? Suppose the variables are x and y, and initially x is 1 and y is 2. After the swap, x should be 2 and y 1.
Memory Program text
int x; int y; x=3; y=2*x; x=x+1; y=y*x; int x; int y; x=3; y=2*x; x=x+1; y=y*x; int x; int y; x=3; y=2*x; x=x+1; y=y*x; int x; int y; x=3; y=2*x; x=x+1; y=y*x;
The obvious way to do this is with two statements: x=y;
y=x;
Suppose we trace this:
Values in memory Program step Effect x 1 y 2 Initial state x 2 y 2 x=y; y=x;
The value from y (2) has been written into cell x,
over-writing the previous 1 x 2
y 2
x=y;
y=x; written into y - which was 2 The value from x (now 2) is anyway.
The problem is that the first x=y over-writes the initial value of x, which is lost and cannot be placed in y. How can we fix this?
The usual solution is to use an extra location, as a temporary store. One initial value is copied there, the other initial value written into the first, and then the copy written into the second. In other words:
temp=x; x=y; y=temp;
We trace this to check:
Values in memory Program step Effect
x 1 y 2 temp ? Initial state x 1 y 2 temp 1 temp=x; x=y; y=temp;
We've made a temporary copy of x
Exercise
Suppose we have three variables, x,y and z, and we need to 'shuffle' their values : x->y, y->z, z->x. So if to start with x=1, y=2 and z=3, afterwards x=3, y=1, z=2.
How would you program this? Try it and test it works.
x 2 y 1 temp 1 temp=x; x=y; y=temp;
Write the initial value of x, from temp, into y
Expressions
Something like 4-3 is an expression. In an assignment statement, we say something like x = <an expression >;
We use – for subtraction, * for multiplication and / for division. So examples of expressions are 4 * 3
12-3 12 / 4 For example y = 20/5;
makes the value of y to be 4.
% is the modulo operator, or remainder
so 10%3 is 1, because 10 divided by 3 gives remainder 1 17%5 is 2
10%5 is 0
% 10 is useful for getting the separate digits of a number. For example int x= 12345;
x%10 is 5 What about 2+3*4 ?
Will it do the addition first (so it gets 20) or the multiplication first, so it gets 14? The answer is that it works the same as normal mathematics, which means it will do multiplication and division first, then addition and subtraction. So
4+5*2 is 14, not 18.
Also as in normal maths we can use brackets – operations in brackets are done first. So (4 + 5) * 2 = 9 * 2 = 18
12/3 is 4 15/3 is 5 16/3 is 5
Exercise
Evaluate the following expressions. The first two are done for you. Check your answers with little Java programs. 2+3 = 5 2-3 = -1 2*3 6/3 7/3 0/3 2+3*4 2*3+4 3-3/4 (3 * 3)/4 (3-3)/4 (5-1)*(10-1)
Expressions with floating point numbers are similar, except that floating point division is used - so 7.0/2.0 is 3.5
Take care. 7 is an int, 7.0 is a double. So while 7.0/2.0 = 3.5, 7/2=3.
We cannot do arithmetic with boolean types, but we can do logic. We use ! for not, && for AND and || for OR. Google logical AND OR and NOT. For example:
boolean a=true; boolean b=false;
Increment decrement and short-cut
Increment operatorFor ints, we often want to increase them by 1, and there is an operator to do this: int x=27;
x++;
makes x be 28.
In fact there are two versions of this - post-increment (x++) and pre-increment (++x). In post-increment, the variable is first used, then incremented. For pre-post-increment, it is first incremented then used. For example
int x=1; int y; y = x++;
makes y be 1, and then changes x to 2. But int x=1;
int y; y = ++x;
first increases x to 2, then makes y be 2 also. You can also say x-- or --x
Short-cut operators
Suppose you want to increase x by 2. You cannot say x+++. You could say x++ twice, or you could say x = x+2;
But the usual way is x += 2;
Similarly
x -= 3; // same as x = x - 3; x *= 4; // same as x = x * 4; x /= 2; // same as x = x / 2; and for a boolean type
boolean b = true;
b != b; // same as b = !b; so now b is false
Exercise
Suppose x and y are ints, and x=2 and y=3. After x *= y++;
Conditional Statements
As well as arithmetic, input and output, there are only two other basic features a program can have: 1. Comparing values and doing different actions for different data
2. Repeating actions
This section is about the first of these.
Suppose we need a program which will input a number, and then output a warning message if it is greater than 100.
That description uses the word if– and we can write it using an if statement
Scanner scanner = new Scanner(System.in); double number;
System.out.println(“Enter a number”); number = scanner.nextDouble();
if (number > 100.0)
System.out.println("Too big");
Try this. Run it twice – firstly entering a number less than 100, then greater than 100.
Exercise
Alter this so you only get a message if the number is greater than 1000.
Syntax
Syntax means grammar rules. An if statement is like this: if ( <some condition> )
<what to do if the condition is true>
The <some condition> is an expression which evaluates to true or false. If it is true, the statements in the curly brackets are executed. If it is not, nothing happens and we just move on to what comes next.
Example
Suppose we want a program which gives a discount of 10% if the purchase is over £100: Scanner scanner = new Scanner(System.in);
double purchase; double discount; System.out.println("Enter purchase "); purchase=scanner.nextDouble(); discount=0.0; if (purchase>100) discount=purchase*0.10; purchase=purchase-discount;
System.out.println("After discount this is £"+purchase);
This sets the discount to zero before the ‘if’. This means if the purchase is not over 100, the discount is zero, but if it is, it is 10%.
Exercise
Change it so you get a 20% discount.
Tracing an if
Tracing a program fragment might help to understand ifs. For example: int x;
int y;
Scanner myScanner = new Scanner(System.in); x=myScanner.nextInt();
y=1; if (x>10) y=2;
System.out.println(y) Suppose the user inputs 12:
Memory Program Comment
x ? y ?
int x; int y;
Scanner myScanner = new Scanner(System.in); x=myScanner.nextInt(); y=1; if (x>10) y=2; System.out.println(y); x and y declared x 12 y ? int x; int y;
Scanner myScanner = new Scanner(System.in); x=myScanner.nextInt(); y=1; if (x>10) y=2; System.out.println(y); scanner object created (omitted) and 12 input x 12 y 1 int x; int y;
Scanner myScanner = new Scanner(System.in); x=myScanner.nextInt(); y=1; if (x>10) y=2; System.out.println(y); y becomes 1 x 12 y 2 int x; int y;
Scanner myScanner = new Scanner(System.in); x=myScanner.nextInt(); y=1; if (x>10) y=2; System.out.println(y); x is greater than 10, so y=2; is executed
if (x>10) y=2;
System.out.println(y);
Conditional as flowchart
This is another way of looking at ifs, as shown at the side.
ifs, semi-colons and blocks
Do NOT put a semi-colon at the end of an if header - this is WRONG:
if (x>4); y=10;
As a result of Java syntax, this is allowable. So unfortunately the compiler will not tell you it is wrong - but it is. The ; ends the statement, so the if stops there - and y=10; is executed either way. In effect it says if x is greater than 4, do nothing. Then just make y=10.
Often you want to do several things if the condition is true . A block will do this. This is just several statements enclosed in curly brackets. For example
if (x>4) {
y=10; z=2; }
A block does not need a semi-colon after it. Else
We often want to do something if a condition is true, and something else if it is not. The if..else structure does this:
if (something) do option one else
do option two
For example, suppose we want to accept a number only if it is greater than 10. We want to tell the user whether it was accepted of not:
.. x=myScanner.nextInt() if (x>10) System.out.println("Accepted"); else System.out.println("Not accepted");
Exercise
Write a program which inputs an integer. If the value inputted is greater than 50, output "Accepted". Otherwise output the message "Too small".
Indentation
Indentation means setting code in from the left margin by amounts which show the code structure. For example: if (x>100) { .. .. } else { .. .. }
This helps to make things clearer, especially when we come to have ifs inside ifs and loops inside loops. Many IDE editors will do this for you - right-click and choose Format.
Compound conditions
Suppose we want to require a value to be between 5 and 10. One way to do this would be to first check if it was more than 5, then less than 10, with two ifs:
if (x>5) if(x<10)
System.out.println("OK");
In this structure, the statement inside the first if is itself an if. This is OK - an if can contain any type of statement.
But we can do the two tests together, like this: if (x>5 && x<10)
System.out.println("OK");
The && means 'and' - so it reads if x is greater than 5 and x is less than 10.. The following is WRONG:
if (x>5 && <10)
System.out.println("OK");
You can say 'x is greater than 5 and less than 10' in English, but not in Java. The symbol for 'or' is ||. So
if (x<5 || x<10)
System.out.println("OK");
says OK if x is less than 5 or greater than 10. Equality and assignment
To test if two values are equal, use == if (x==5)
if (x=5)
System.out.println("OK");
x=5 is an assignment - it tells the system to make x 5. It should be x==5, which asks whether x is 5. The symbol ! means NOT, so != mans not equal to:
if (x!=5)
System.out.println("OK"); accepts anything except 5.
You need to be careful with edge values. For example if (!(x > 10))
System.out.println("OK");
means 'if x is not greater than 10'. So it accepts 10, or less.
Exercise
Write a program which accepts numbers up to 5 inclusive, and over 9, outputting 'OK', and outputting 'Out of range' otherwise.
Algorithms
Suppose we need some code to input two integers, and then outputs them in order of size, largest first. So input 26, 20 outputs 26 20. Input 3,4 outputs 4,3:
import java.util.Scanner; public class Main {
public static void main(String[] args) { int x;
int y;
Scanner myScanner = new Scanner(System.in); x = myScanner.nextInt(); y = myScanner.nextInt(); if (x > y) { System.out.println(x + " " + y); } else { System.out.println(y + " " + x); } } }
This is easy - we compare x and y, and if x is bigger, output x then y, otherwise y then x. This is a simple algorithm.
An algorithm is a method or recipe or solution to a problem, as a series of simple logical steps. A program is an implementation of an algorithm in a particular language.
For clever programming, finding the correct algorithm is more significant that actually writing the program. Fortunately optimal algorithms for many standard tasks have been invented, and sometimes even coded into languages.
Not so easy..
Suppose we need to input three numbers and output them in order, biggest first. How would you do that? Before you read on, decide what algorithm you would use, and program it.
One algorithm would be 1. Find the biggest, and output it. 2. Find the middle and output it. 3. Find the smallest, and output it.
Finding the middle one is not easy. If the numbers are x y z, then x is the middle if the order is y x z or z x y.
so we need to test if y is greater than x and x is greater than z, or z is greater than x and x is greater than y.
int x, y, z;
Scanner myScanner = new Scanner(System.in); x = myScanner.nextInt(); y = myScanner.nextInt(); z = myScanner.nextInt(); // find biggest if (x > y && x > z) { System.out.println(x); } if (y > x && y > z) { System.out.println(y); } if (z > x && z > y) { System.out.println(z); } // find middle if ((x > y && x < z) || (x < y && x > z)) { System.out.println(x); } if ((x > y && y > z) || (x < y && y < z)) { System.out.println(y); } if ((z > y && z < x) || (z < y && z > x)) { System.out.println(z); } // find smallest if (x < y && x < z) { System.out.println(x); } if (y < x && y < z) { System.out.println(y); } if (z < x && z < y) { System.out.println(z); }
This is getting tricky. We have included comments like // find biggest
to help keep track of what we are doing. Try this method.
Is it the best way? It uses 9 comparisons. If we've found the biggest and the middle, we should not have to find the smallest - which suggests it is not.
An alternative algorithm is to simply test the 6 possibilities, which are x y z x z y y x z y z x z x y z y x Here we go:
int x, y, z;
Scanner myScanner = new Scanner(System.in); x = myScanner.nextInt(); y = myScanner.nextInt(); z = myScanner.nextInt(); if (x > y && y > z) { System.out.println(x + " " + y + " " + z); } if (x > z && z > y) { System.out.println(x + " " + z + " " + y); } if (y > x && x > z) { System.out.println(y + " " + x + " " + z); } if (y > z && z > x) { System.out.println(y + " " + z + " " + x); } if (z > x && x > y) { System.out.println(z + " " + x + " " + y); } if (z > y && y > x) { System.out.println(z + " " + y + " " + x); }
Exercise
Try this way. Do you think this is more efficient that the first? Could it be further improved? Was your method more efficient?
Loops
Suppose we want to add up the first twelve integers. This does it: int total=0; total+=1; total+=2; total+=3; total+=4; total+=5; total+=6; total+=7; total+=8; total+=9; total+=10; total+=11; total+=12;
This works, but it's a lot of typing. Suppose we needed to add up the first 12000 integers? This method would be impractical.
The code above has almost the same statement total+=?; twelve times. What we need is a way to execute the same statement several times.
We could use the statement total+=n; and change the value of the variable n. This would need to be 1, then 2, then 3, up to 12. Here it is
int total = 0; int n; n = 1; while (n < 13) { total += n; n++; } System.out.println(total);
Study this code carefully. We have a new kind of statement - a while loop. 1. There is a loop header, while (n<13)
2. This is followed by the loop body - a block { } containing two statements: total+=n; and n++; 3. The loop body is repeatedly executed, so long as the condition (n<13) is true.
4. The index n is initialised to be 1.
The loop body is repeated. The first time, n is 1, so the first statement in teh loop body is in effect total+=1;. The second statement, n++; increase n to be 2.
So on the next repeat, it does total+=2; and n is increased to 3. On the third repeat it does total+=3;
This will continue up to and including n=12, when it does total+=12; and n increases to 13. But then the condition to continue, n<13, is no longer true, so the loop terminates. How could we modify this to add up integers from 1 to 20? Just change the condition:
int total = 0; int n; n = 1; while (n < 21) { total += n; n++; } System.out.println(total);
Add up the numbers from 10 to 20? Change the initialisation: int total = 0; int n; n = 10; while (n < 21) { total += n; n++; } System.out.println(total);
Add up the odd numbers from 1 to 1000? We need 1,3,5,7, so we need to start at 1 and go up in steps of 2: int total = 0; int n; n = 1; while (n < 1001) { total += n; n+=2; } System.out.println(total);
Display the total as we go along? Have the output inside the loop body: int total = 0;
int n; n = 1;
while (n < 1001) { total += n;
System.out.println("n = "+n+" total = "+total); n+=2;
}
while loops
1. The condition must be in round brackets, like (n<13)
2. The condition can be any boolean expression, such as (n<13 && x!=5) 3. There should be no semi-colon at the end of the loop header
4. If there is just one statement in the loop body, it does not need to be a block - such as while (n<10)
n++;
5. You might have an endless loop, such as while (true)
total += n;
In this case, you would need to use the IDE to cancel the process, or use Task Manager in Windows. do..while loop
int total=0; int n=1; do{ total+=n; n++; } while (n<10);
In most situations the choice of while or do..while is arbitrary. The only difference is that do..while will execute at least once. In a while, if the condition is false the first time in, the loop body will never be executed.
Exercise
Write a program which adds up the even numbers from 2 to 10 inclusive and outputs the total. Test that it gives the correct answer
Change it so it adds the even numbers from 2 to 10000.
Programming with loops example
We often need some ingenuity to solve a programming problem with a loop. A key stage is to recognise that a task involves repeating something, so a loop is needed.
Suppose we need to separate, and print separately, the digits of a number. So given 1234, it should output
1 2 3 4
We need to do this for each digit - so we are repeating something and need a loop. Do we know how many times to repeat? The number could be 1234 (4 times) or 54321 (5 times) or whatever, so it is not a fixed number of repeats.
How to separate the digits? Use integer division by 10, and modulo. For example, if the number is n=1234, then
n%10 is 4, the lowest digit, and
n/10 is 123. So change n to this, and loop. So we have an outline: given the number n
while..
digit = n%10, and output it n = n/10
When should the loop end? n will get smaller. On the last output, n is less than 10. Then it is zero. So our code is int n = 1234; while (n > 0) { int digit = n % 10; System.out.println(digit); n /= 10; }
We have declared and assigned the variable digit inside the loop. This is OK.
This is not quite right - the output is least significant digit first, when we wanted most sgnificant first. This is easily fixed using an array, which we will meet later.
for loops
for (...) { // loop body }
Here is an example, to add up the numbers 1 to 5: int number;
int total; total = 0;
for (int c = 1; c < 6; c++) { number = c;
total = total + number; }
System.out.println(total);
The loop header has three parts, separated by semi-colons. It goes for ( start; loop so long as; change after each repeat )
So in our example, we start with c=1, we repeat so long as c is less than 6, and after each repetition, it increases c by 1. In other words, c goes 1 2 3 4 and 5. The loop body is repeated for each of these. So the first time it says number = 1, then number = 2, then number = 3, then - you've got it.
Exercise
Modify this program so it adds up the numbers 1 to 1000. Is it correct? If you cannot remember how to work it out, google 'arithmetic progression'
Note that in the loop start: int c=1;
we both initialise c to be 1, and declare it. We do not have to declare it here (it could have been declared with the other variables) but it can be, and often is. If it is, it can only be used in the loop body ('its scope is restricted to the loop')
Another example
This program outputs 100 down to 0 in steps of 2: for (int c = 100; c > -1; c=c-2) {
System.out.println(c); }
If the loop body has just one statement in it, you do not need the block (the curly braces). As with an if, a semi-colon at the end of the header is WRONG. This is WRONG
Exercise
Write loops which will output 1. 0 1 2 3 4 5 6 7 8 9 10 2. 10 8 6 4 2 0
3. 5 4 3 2 1 0 -1 -2 -3 -4 -5
4. Write a loop which will calculate the total of 1+2+3+4+5..., stopping when the total exceeds 100. 5. Write a program which first inputs an integer n, then calculates and outputs 1X2X3X4X..n (which is called n! or n factorial)
Nested loops
The statements in a loop body can be any type, including loops themselves. Look at the following program:
for (int c = 1; c < 6; c++) for (int d = 1; d<6; d++) System.out.println(c+" "+d); What do you think it will output? Try it - can you explain what it does?
Exercise
1. Write a program which will output the 5 times table, like this 1 X 5 = 5
2 X 5 = 10 3 X 5 = 15 ..
12 X 5 = 60
2. Extend this so it outputs all the multiplication tables, one after the other, from the 2 to the 12 times table.
break and continue
These are two new types of statements which can be used in loops (and conditionals).
You use continue; part way through a loop body. It misses out the rest of the loop body, and repeats. You would usually use it with an if, like
while(...) {
..
if (..) continue;
.. this is missed out if the if was true }
break is similar, but it breaks out of the loop completely. So you might say: while (true)
{ ....
if (..) break; // ends the loop totally ..
}
Testing
Beware of bugs in the above code; I have only proved it correct, not tried it. - Donald E. Knuth
Testing means checking a program works by trying to run it.
You should write program code in small sections, and test each small section before you write more. Testing is a major aspect of software engineering. In Java, the JUnit framework is a formal way of testing code. Since testing may take a long time, the process is sometimes automated.
However the beginner programmer needs to test code in an informal manner. To test, you need to know what the output should be - otherwise you cannot tell if it works. For example, we might have some code to convert Centigrade temperaturs to Fahrenheit:
int centi = 17;
int fahr = centi*9/5 + 32; System.out.println(fahr);
If we run this, it outputs 62. However that does not help unless we know what the correct answer is. In fact it is 62.6. Why is our code wrong? The correct answer is not an int, but we have used that as the type. The correction is simple:
double centi = 17;
double fahr = centi*9/5 + 32; System.out.println(fahr);
Sometimes thought is needed to work out how to test something - a testing strategy. For example, you might be working on code to write data into a file, and read it back. You might write both the writing and reading code at the same time. How to test it? If it does not work, is the writing wrong, or the reading? The solution is to look at the file directly, say in a text editor. If it is wrong, the writing code has the error. If it is correct, the reading code is wrong.
Data Structures
In previous sections we have used data as single items. There are many situations where we need to use many items of data in an organised structure. Some examples are
The color of the pixels in a line on a graphic image The colour of the pixels in a rectangle
The set of exam marks for the students in a class The transactions on a bank account
The frames of a video clip
The items in a data structure are called elements or nodes. Data structures
Some standard ways of arranging data are
Linear list - data elements are next to each other
Linked list - elements are linked by pointers. They are not next to each other in memory
Binary tree - each element is linked to two others, except for leaf nodes
Queue - elements join at one end and leave at the other
Stack - elements join and leave at the top
Data structures and algorithms
We need to be able to add new elements to the data structure, delete them, find one, and go through everything in the structure - traverse it. How that is done - the algorithm - will depend on which data structure it is. Some algorithms and data structures will use more memory and be faster than others. The study of algorithms and data structures is central to classic Computer Science.
Data Structures and Languages
There are two different ways of looking at this - In the abstract, using diagrams like those above
Concrete implementations of these structures in a programming language. The structures might be 'built-in' to the language, or it might be possible for the programmer to write their own implementations
Both ways have their advantages. The abstract language-independent approach lets us focus on the structure itself. A concrete implementation lets us use these theoretical ideas in reality.
Data Structures in Java
The Java language allows the programmer to implement most of these ideas. The standard classes include the 'container' classes which already provide implementations of many of them, and 'generics' offer algorithms to use them. The only thing Java does not allow is direct access to memory through actual numeric addresses - because this is a common source of bugs. We will look in this section at one structure - the array.
Arrays
Imagine a street of houses. Each house has a distinct house number. Each house contains different things.
We can think of an array like this. It is a set of boxes, or elements. Each element has a different index, which is like the house number, except that Java arrays start at 0 rather than 1. Each element contains some data. This could be any type, such as integers, doubles, objects or whatever - but they have to be the same type. We can get to any element through its index - to read the data out of the element, or to change it.
Streets have street names, and arrays also have names. In a Java program arrays are variables, and like all variables we have to declare them before use. For example:
int[] myArray = new int[5];
This declares myArray to be the type 'array of ints', and it constructs an array with five elements - indexed 0 to 4. Java arrays are indexed using [ square brackets ].
myArray[0]=48; myArray[1]=72; myArray[2]=31; myArray[3]=99; myArray[4]=43;
Note the array index goes from 0 to 4.
We could output the values from the array like this: System.out.println(myArray[0]);
System.out.println(myArray[1]); System.out.println(myArray[2]); System.out.println(myArray[3]); System.out.println(myArray[4]); Arrays and loops
The last two fragments show program code with very similar statements repeated. These are situations where loops are appropriate. For example we can output the array with:
for (int i=0; i<5; i++)
System.out.println(myArray[i]); Trace through this:
Execution Value of i Action
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=0 Initialise i to 0
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=0 Output myArray[0]
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=1 Increment i, continue
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=1 Output myArray[1]
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=2 Increment i, continue
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=2 Output myArray[2]
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=3 Increment i, continue
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=3 Output myArray[3]
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=4 Increment i, continue
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=4 Output myArray[4]
for (int i=0; i<5; i++)
System.out.println(myArray[i]);
i=5 Increment i, stop
Exercise
Run this program
Random numbers
How do we get numbers to put in the array? In real programs they come from pixels read in from a jpeg or similar. For our study programs, we could input values from the keyboard using a Scanner, but this is tedious and for an array with a 1000 elements, impractical. A good alternative is to use numbers generated at random by the computer.
The class Math has a method called random which produces a number in the range 0 to 1 - a double type with decimal parts. This is called Math.random().
If we multiply it by say 1000.0, we will have a random number in the range 0 to 1000. This is Math.random()*1000.0
We can change this to a whole number by 'casting' it to an int. This is done by (int)(Math.random()*1000.0).
Putting this in a loop, we have for (int i=0; i<5; i++)
myArray[i]=(int) (Math.random()*1000.0);
Exercise
Follow this with the loop for outputting the array. Run the program several times. Do you get the same random values each time?
Summing an array
We can add up all the values in an array by using the following simple algorithm initialise a running total to 0
for each value in the array,
add the value into the running total
After this, the running total will be the sum of all the elements. For example:
int[] myArray = new int[5000]; // fill array with numbers for (int i=0; i<5000; i++)
myArray[i]=(int) (Math.random()*1000.0); // find total
int total=0;
for (int i=0; i<5000; i++) total+=myArray[i]; // output total
System.out.println("Total = "+total);
Exercise
Modify this so it outputs the average as well as the total.
for (int i=0; i<5000; i++)
the 5000 is a magic number. Why 5000? We know it is because the array has been declared to have 5000 elements, but in a long and complex program we might have forgotten this. Or (more likely) your program is being read by another programmer who has the task of maintaining your code. Do them a favour, help them out and make the code self-evident:
final int ARRAY_LENGTH = 5000; int[] myArray = new int[ARRAY_LENGTH]; // fill array with numbers
for (int i=0; i<ARRAY_LENGTH; i++)
myArray[i]=(int) (Math.random()*1000.0); // find total
int total=0;
for (int i=0; i<ARRAY_LENGTH; i++) total+=myArray[i];
// output total
System.out.println("Total = "+total);
ARRAY_LENGTH is in capitals because this is the convention for constant values. Just by looking at it we know it is supposed to be a constant.
It is declared to be a final int. This forces it to be constant - it can only be given a value in its
initialisation. If code further on changes it, it will not compile. This is an example of using a language feature to make bug-free programming easier. The compiler will tell us if we go wrong.
If for some reason we decide the array length should be different, we just have to change one line of code, where ARRAY_LENGTH is initialised. Otherwise we would have had to have searched for every occurrence of 5000, check if it was appropriate, and change it if it was.
Finding extreme values
For example, how could we find the largest number in the array? And its location? Here is an algorithm, using the idea of 'the biggest so far'.
Set biggestSoFar to be the first element Set location to be the first
For each subsequent element:
If this element is bigger than the biggestSoFar, Change biggestSoFar to be this element
Change location to be this location
At the end, biggestSoFar will be the biggest in the whole array. Here is an implementation of this in Java:
final int ARRAY_LENGTH = 5000; int[] myArray = new int[ARRAY_LENGTH]; // fill array with numbers
for (int i=0; i<ARRAY_LENGTH; i++)
myArray[i]=(int) (Math.random()*1000000.0); // find maximum
int biggestSoFar=myArray[0]; int location = 0;
for (int i=1; i<ARRAY_LENGTH; i++) if (myArray[i]>biggestSoFar) { biggestSoFar=myArray[i]; location=i; } // output result System.out.println("Largest is = "+biggestSoFar); System.out.println("Located at = "+location);
The range has been changed to 0 to 1 million - otherwise the maximum is almost always 999.
Exercise
Make sure you understand every line in the above program. Change it so it finds the smallest value.
How can you test this program?
Sorting
In computing, 'sort' means to arrange data in order.
In normal life, sorting means separating things out into different types. The reason why sort came to mean ordering is a curious historical tale involving Herman Hollerith (the founder of IBM), the US Census of 1901, and a method now called a radix sort. Google it for the details.
How could we re-arrange the numbers in our array into decreasing order, biggest first? Invent a method.
One way would be to find the biggest (which we can already do) and swap it into first place. Then find the second biggest, and swap it into second place. Then the third, and so on.
Our current find biggest starts at 0. Introduce another variable for where it starts: // find maximum, from start
int start=0;
int biggestSoFar=myArray[start]; int location = start;
for (int i=start+1; i<ARRAY_LENGTH; i++) if (myArray[i]>biggestSoFar)
{
biggestSoFar=myArray[i]; location=i;
}
Then exchange the biggest value with the one at the start. Remember the variable exchange trick we saw before:
for (int start=0; start<ARRAY_LENGTH-1; start++) {
.. }
After we've sorted it, we want to output the array in a loop. Here's the whole thing: final int ARRAY_LENGTH = 5000;
int[] myArray = new int[ARRAY_LENGTH]; // fill array with numbers
for (int i = 0; i < ARRAY_LENGTH; i++) {
myArray[i] = (int) (Math.random() * 1000000.0); }
// sort begins
for (int start = 0; start < ARRAY_LENGTH - 1; start++) { // find maximum, from start
int biggestSoFar = myArray[start]; int location = start;
for (int i = start + 1; i < ARRAY_LENGTH; i++) { if (myArray[i] > biggestSoFar) {
biggestSoFar = myArray[i]; location = i;
} }
//swap values at start and location of max int temp = myArray[start];
myArray[start] = myArray[location]; myArray[location] = temp;
}
// output array
for (int i = 0; i < ARRAY_LENGTH; i++) { System.out.println(myArray[i]); }
}
How many steps are involved in this method? To find the biggest we go through the whole array, 5000 steps. We have to do this 4999 times - about 5000. As we do this we don't have to do as many steps - it goes from all to none, so averages half, or 2500. So the total steps is approximately 1/2 5000 X 5000, or around 12 million.
Exercise
Before you run it, roughly how long do you think it will take to sort 5000 numbers? That's 12 million steps.
Copy and run this program.
Change the array length. Try a very small number - say 10. How long does it take? Try a bigger array - say 100 000. That will be 5 billion steps. This is not an exceptionally large array - an image with a resolution of 1000 by 1000 pixels has one million elements.
This method is a type of exchange sort. It is simple but slow.
Exercise
Think of a faster way. To get some ideas, google 'sorting algorithms'. Don't go mad. Find one you can understand, and implement it in Java.
Bitwise operations
All computer data is represented by strings of bits. Java has some operators which work at the bit level, and their use can provide some insight into how data is stored.
Shift and masks
The >> operator shifts the bits in a number to the right - shifting 0s in on the left. So x>>1 shifts the bits in x one place right, and puts a 0 at the front.
The & operator forms a bitwise AND mask. For example, what is 12 & 3 ? In base 2, 12 is 1010, and 3 is 0011, so
1010 0011 AND ----
0010 = 2
We are taking pairs of bits and forming the logical AND. 1 AND 0 is 0, 0 AND 0 is 0, 1 AND 1 is 1 and so on.
& is the bitwise AND, while && is the logical AND eg if (x>7 && y<3)...
& masks are usually used to isolate certain bits from a pattern. For example, a mask with 1 gets the right-hand least significant bit only. For example 15&1 is
1111 (15) 0001 AND ---- 0001 (lsb of 15) But 8&1 is 1000 (8) 0001 AND ---- 0000 (lsb of 8)
| is the corresponding OR bitwise mask.