progstack

This site contains Java programs and explanations related to 48023 Programming Fundamentals (University of Technology, Sydney) that supplement Natalie Mazurek's tutorials.

Get started >>

Java

The basics

Structure

  • A Java program will always have a class declaration
    class StrangeThings { } with starting and closing braces (curly brackets).
  • Inside of the class there must always be a main method
    public static void main(String [] args) { } also with starting and closing braces.
  • All the executable code (that you will write) lives inside of the main method's braces that, in turn, lives inside of the class' braces.
  • All statements end in semicolons;

Variables

Variables have a data type (ie, integer) and name (ie, "length").

int length;

This is called "declaring" a variable, which must be done before you can use it in your program. Then, optionally, you can "initialise" it with a value using the assignment operator (=).

int length = 4;

In other words, the integer variable called length is assigned the value 4. It does not equal 4.

The following Java programs calculate the area of a rectangle and illustrate different ways of declaring and initialising variables - all are equivalent.

Example: Calculating the area of a rectangle

Java code

Output

Arrays

Arrays

An array is an object that holds a fixed number of values of a single primitive type (eg, int) or object references. Each element in an array is just a variable.

In this example we have an integer array named "num" of length 3, initialised with three values.

int [] num = { 8, 99, 15 };

Each element is accessed by its index position. For example, the element "8" is located at index 0, notated num[0] (in Java we start counting at zero).

Task: Which elements are located at which index positions and how would we reference them in our Java program? (Click "Ans" to reveal the answer.)

[ 0 ]
[ 1 ]
[ 2 ]

Creating a primitive type array

Primitive variables store the bits representing a value (true, 99, 'abc', etc). The primitive data types include boolean, character, byte, short, integer, long, float and double.

Procedure:

1) Declare an array variable.
int [] num;

2) Create a new int array of length 3 and assign it to "num".
num = new int[3];

// you could do this with just one line:
int [] num = new int[3];

3) Assign a value to each element in the array.
num[0] = 8;
num[1] = 99;
num[2] = 15;

In an array of type int, each element can hold only an int.

Creating an object reference array

You should read about Objects before trying to understand this.

Reference variables store the addresses of the objects they refer to (that are on the heap). They require the dot (.) operator to access instance variables and methods and have a value of null when not referencing any object.

Procedure:

1) Declare an array variable called "doggo" and assign to it a new Dog array with length 3.
Dog [] doggo = new Dog[3];

These are reference variables, so doggo[0] references one dog... we still need to create the objects.

2) Create objects (using a constructor).
doggo[0] = new Dog();
doggo[1] = new Dog();
doggo[2] = new Dog();

In an array of type Dog, each element can hold a reference variable to only a Dog object.

Java code

class Dog

class DogMainArray

Output

Click for Dog source code

Click for DogMainArray source code

Scanner

Scanner

Scanner lets you read input from the console. For example, the program might ask the user to guess a number, which they type on the keyboard, that Scanner reads and which is then assigned to a variable.

Scanner is just one way to read input from the keyboard, which it breaks into tokens using whitespace as the default delimiter.

To use Scanner, you need 4 things:

  • The import statement (before the class header): import java.util.Scanner;
  • A Scanner object (in the main method): Scanner scan = new Scanner(System.in);
    ("scan" can be any name you choose)
  • A prompt for the user: System.out.println("Enter a number: ");
  • A variable to assign the read Scanner input to: int guess = scan.nextInt();


    For doubles, use scan.nextDouble();
    For Strings, use scan.nextLine();

    Java code

    This program asks for user/keyboard input twice and uses the inputted values to calculate the area of a rectangle (area = width * height).

    Click for source code

    Importing packages

    Predefined Java classes are organised into packages. The Scanner class is found inside "util" which lives inside "java". So, to use the Scanner class we need to import the java.util package into our program.

    Some methods don't need to be imported such as println() because they are members of the "System" class that is predefined by Java and automatically included in your program.

Codercise

"Scanner" coding exercises >>

Temporary variable

Temp

In this example, we reverse the array
int [] numbers = { 11, 22, 33, 44, 55, 66 }

so that it reads
int [] numbers = { 66, 55, 44, 33, 22, 11 }

  • The first element in the array (11) is referenced with numbers[0], the second element (22) is numbers[1], etc.
  • You know that the values contained in the array must be integers because the array is declared an "int" type.

We reverse the array by swapping the pairs of elements that are located at mirror ends of the array using the swap algorithm. The pairs that need to be swapped are 11 with 66, 22 with 55, and 33 with 44. That is, numbers[0] with numbers[5], numbers[1] with numbers[4], and numbers[2] with numbers[3].

A temporary variable (temp) is required in order to reverse an array. Temp holds a value (for safekeeping), say 11, so that we can put 66 in its position without overwriting 11.
If our first line of code is numbers[0] = numbers[5] then 11 gets overwritten in this first reassignment and we no longer have 11 to put into 66's position.

Again.. Why do we need a temporary variable?

If we try to reassign the values without a temporary value, one of the values disappears.

Because numbers[0] has been reassigned (from 11 to 66) its original value (11) has been overwritten (lost!) and so we have no way of now reassigning numbers[5] with the value 11 in order to conduct the swap.

Example: Reversing an array with a temporary variable

Java code

Output


Click for source code

Tracing through the program

1) We declare a temp variable but don't initialise it.

2) The value in numbers[0] (or numbers[5]; any order will work) is assigned to temp for safekeeping.

3) numbers[0] is assigned the value in numbers[5], which overwrites the original value in numbers[0]. No problem.. we saved it in a temp location!

4) We assign to numbers[5] the value that is stored in temp.

We have swapped 11 and 66.

5) Repeat for 22 & 55 and 33 & 44.

Codercise

"temp" coding exercises >>

"sequence" coding exercises >>

If

The if statement

if ( thisThing < anotherThing ) {
doSomething...
}

thisThing might be smaller than (<), greater than (>), equal to (==) or not equal to (!=) anotherThing.

If the 'if' statement evaluates to TRUE then doSomething executes. If it evaluates to FALSE nothing happens, that is, the code within the if statement's braces does not execute and the program moves on to the next line.

Java code

Output

Click for source code

Tracing

static final get set

static variables/methods
final variables
get methods
set methods

A static variable has the same value in all of objects created from a class. It is associated with the class rather than with any object so it does not change from object to object. A static method applies to all of the objects created from a class. For example, all bank accounts have the same interest rate.

Static across objects

Instance variables that are not static have unique values in each object. For example, your account number is unique.
Methods that are not static apply to only the account that calls it. For example, a withdrawal method will only operates on your bank balance, not all of them.

A final variable doesn't change over time. Its intial value is its final value and can't be reassigned. For example, your bank account number is yours forever.

An example of a variable that is both static and final is the constant pi = 3.14...

Final over time

Accessor (get) methods retrieve the values of private variables in order to be used by another class. They require an appropriate return type (that matches that of the relevant variable).

public int getAccountNumber() {
return accountNumber;
}

Mutator (set) methods change the values of private variables. Their return type is always void.

public void setAccountNumber(int newAccountNumber) {
accountNumber = newAccountNumber;
}

Objects

Object-oriented programming languages (OOP)

In an object-oriented language you define the data and methods that are permitted to act on that data.
All OOP languages have three traits in common: encapsulation, polymorphism, and inheritance.
In the following section we'll focus on encapsulation.

Encapsulation

Java’s basic unit of encapsulation is the class. An object is the device that supports encapsulation.

A class defines the form of an object. It specifies the member/instance variables (the data) and the methods that will operate on that data. Objects are instances of a class.

Within an object the code may be private or public to that object. Private code is known to and accessible by only that object and cannot be accessed by another part of the program without an accessor/get method. When code is public other parts of the program can access it. Typically, the public parts of an object are used to provide a controlled interface to the private elements of the object.

Example: Dog objects

Java code (class Dog)

This class is the blueprint for creating Dog objects.

We can represent the Dog object like this:

Dog the class
name
breed
the instance variables (state)
bark()
chase()
the methods (behaviour)

We create a Dog object for our doggo Coco from the main method in the calling class DogMain by invoking the constructor in the Dog class:
Dog coco = new Dog("Coco", "Border Collie");

Dog coco is a variable declaration that associates the variable name (coco) with an object type (Dog).

new is a Java operator that creates the new object.

Dog("Coco", "Border Collie") is a call to a constructor that initialises the new object.

The phrase "instantiating a class" means the same thing as "creating an object." When you create an object you are creating an "instance" of a class therefore "instantiating" a class.

We use the dot (.) operator and accessor/get methods to access Coco's methods and variables (that are in the class "Dog") from the main method (in class "DogMain").

Java code (class DogMain)

In this class we actually create the objects.

Output

Click for Dog source code

Click for DogMain source code

Codercise

"get/set" coding exercises >>

"method calling" coding exercises >>

"constructor" coding exercises >>

Looping Constructs


There are 3 types of looping constructs: while, do-while, for.

While loops

A While loop executes a set of statements while a particular boolean condition is true (defined in the brackets). While loops should be used when there is an unknown number of iterations, like when you don't know the length of the array.

initialisation
while (condition) {
// statement/s
increment
}

Example: Searching for an array item

Java code

Output

Tracing

Click here to trace through example >>
Tracing through the while/if loops.

Click for source code

Example: DooBeeDooBeeDo

This example has been taken (and tweaked) from Head First Java by Kathy Sierra & Bert Bates. The aim is to print "DooBeeDooBeeDo" to the terminal.

Java code


Output


When we first run the code the output is only "DooBeeDooBee" without the final "Do". I've added a print statement to help us figure out why. Notice that by the end of the while loop the value of x has increased to 3, which means that the following if statement doesn't execute and we don't get the final "Do".

Here's one solution:

Java code


Output


One possible solution is to create another variable (y) that holds the original value of x to use in the if statement.

Click for source code

For

For loop

The "for" loop provides a compact way to iterate over a range of values. It repeatedly loops until a particular condition is satisfied.
The general form is:

for (initialisation; termination; increment) {
statement/s
}

The "initialisation" expression initialises the loop. It is executed once, as the loop begins.

If the boolean "termination" condition evaluates to true, the "statement/s" execute.
When the boolean "termination" condition evaluates to false, the loop terminates.

The "increment" expression is invoked after each iteration through the loop; it might increment or decrement a value.

If the variable that controls a for loop is not needed outside of the loop, it's best to declare that variable inside the initialisation expression. In the example below that is "int k = 0".

The names i, j, and k are often used to control for loops. Declaring them within the initialisation expression limits their life span and reduces errors.

Reversing values in the array named "a" using a "for" loop

1) Initialise: int k = 0. The loop starts at array index position 0.

2) Iterate over only half of the array. That is, the length of the array divided by 2: a.length/2.

This array has a length of 5:

The middle index is length/2. The division operator returns the lowest non-fractional number; 5 divided by 2 will give 2 (not 2.5).

If k is smaller than the length of the array divided by 2 then, as long as the termination condition evaluates to true, the following statement is executed:

Swap every k-th element with the (a.length-[1+k])th element.
(You may see it written as (a.length-1-k) which means the same thing.)

If k is larger than length/2 (ie, the condition evaluates to false) then the loop terminates.

3) Following this, increment k by 1 and iterate again.

Tracing

Click here to trace through example >>
Tracing through the for loop.

Linked List

Nodes

A linked list (of objects) is a recursive data structure that consists of a sequence of nodes based on their logical (not physical) order.

In this example, each singly-linked (unidirectional) node stores a data value and a reference to the next node. The last node always points to null.

[ headNode data ] --> [ nextNode data ] --> [ anotherNode data ] --> null

The arrows ( --> ) represent the variable 'next'.

Java code

We create the head (first) node using a constructor that initialises the instance variables 'data' (by passing in an argument) and 'next' (to 'null').

Output

Next, if we try to add another node in the same that way we created the head node by calling the constructor Node nextNode = new Node(2); we will just get two unlinked nodes, both pointing to null.

We need two new methods in order to add nodes and then print the linked list of nodes. The printNode method is insufficient because it must be called on a an object with its own unique variable name (ie, headNode). When we create a second node we don't give it a unique name, instead it is assigned to the 'next' variable of the previous node.

Output

Click for source code