top of page

Week 6

In Week 6 you will learn about input and output in Java. We will then cover loop invariants and introduce Arrays.

Input and Output

Introduction

Until now we have used the println and print methods to put output onto the console. This is output. We however also want to get input from the user to be able to write any meaningful programs. In Java input is handled by the Scanner class which allows us to use predefined methods to retrieve input from the user.

In a first stage this input will mostly be focused on the console and in a later stage we will also discuss how to to input and output to files.

Scanner

Introduction

ScannerExample.png

We can use the Scanner class to retrieve input from the user. We will first discuss how to retrieve input from the console. The scanner class requires an object of the class to exist for use to be able to use its utility similar to the Random class.

We initialise the Scanner object using System.in which is the console input, analogous to System.out being the console output. You should then always prompt the user for the wanted input. We can then use a multitude of input methods specifically written to input int, double, String, etc. The methods and their usage is listed below. It is good practice to close the scanner when we are done using it via the method close().

  • nextInt(): Inputs the next int if the next input is representable as int. Otherwise it produces an error.

  • nextDouble(): Inputs the next double if the next input is representable as double. Otherwise produces an error.

  • next(): Inputs the next string, where the next string is all characters in sequence until a whitespace or a newline.

  • nextLine(): Input the next line in its entirety as a string, i.e. inputs all characers including whitespaces until it a newline.

Scanner

Checking input

ScannerHasNext.png

In addition to retrieving inputs the Scanner class allows us to check if the next input has a certain type. This allows us to correctly input sequences which contains multiple types of values. One can find this and much more on the Java Documentation for the Scanner class. Some of the methods to check the next inputs are listed below

  • hasNextInt(): Returns true if the next input is representable as int.

  • hasNextDouble(): Returns true if the next input is representable as double.

  • hasNext(): Returns true if there is a next input.

Scanner

Whitespaces

1 2 8 hello ! 7.52
1 2 8 "hello" '!' 7.52
"1" '2' 8 "hello" "!" 7.52

Whitespaces are the spaces between characters. We can insert space either by simply pressing the space bar or by putting \s between two characters. The whitespace character is what is used by the Scanner to differentiate between two elements in the input. 

To the left you can see how input can be parsed in different ways by changing the methods called from the Scanner object. One can also pass regular expressions to the methods to make the input recognition even more specific. 

Each sequence of symbols is called a token. And depending on what method we use a token might look different. When we use nextLine() the entire line is a token, if we use next() all characters up to the next space are a token.

Scanner

Incorrect Parsing

Screenshot_20230908_091753.png

When you are calling a method from the Scanner class and this method expects an input of some type and it cannot find it then the method will produce an error. This happens for example because one might think that the dot in a double value can be parsed as a char character, but because there is no space in between the individual characters the Scanner class does not recognise that these are individual characters and will attempt to interpret the entire input as a certain type which will fail.

One can input char type values by using a case from short, as they are both 16 bit variables and thus we do not lose any information. We use char c = (char) scanner.nextShort() for that purpose.

Scanner

Line Scanning

LineScanning.png

When the input is composed of multiple lines of tokens with a similar format, e.g. with personal information, we use a line per line approach by using one Scanner object to consume lines and then pass this line as a String to an internal Scanner object that can then parse the line itself. This approach is less prone to errors as we do not have to consume end-of-line symbols to get to the next line which might cause complications.

You should always when presented with input consisting of multiple lines use this approach as it is much more structured and makes the input process simpler.

Output

Generalisation

PrintStream.png

Every basic output method is handled by the PrintStream class in Java. This includes the usual System.out which itself is a PrintStream object which gets assigned the console as medium of output. Any PrintStream object uses the same print and println methods as you previously used with the System.out PrintStream object. 

In this context we often write to a file. Java has a File class which allows you to open / create / write to files. This file can be given as input when creating a File object. Whenever a PrintStream object receives a file as input when being created we must add the throws FileNotFoundException to the method signature, why that is will be discussed later.

Loop Invariants

Quickguide Reference

To learn about loop invariants, which are a very important part of the lecture please read this quickguide explaining how to construct them. Loop invariants are one of the most underestimated topics and most often people struggle with them both in the exercises and during the exam. 

Arrays

Introduction

Array.png

int[] intArray = new int [5];
intArray[2] = 2;
char[] cArr = new char[] {'a', 'b', 'c' }

Java arrays is the first data structure you will learn about. Arrays are a sequence of elements of the same type (not necessarily primitive) positioned one after the other. We start at index 0 as is common in computer science.

We can initialise arrays using the new keyword and by specifying the number of elements in the brackets [ and ] after the new keyword. This can be seen to the left. We can replace int with any type, i.e. type[ ] yields an array containing elements of the type given. We then access the elements (write / read) by using the brackets [ and ] as well.

We can also instead of specifying the number of element directly initialise the array by giving a list of its elements.

Arrays

Default types

Screenshot_20230909_130204.png

Having a look at the Java documentation on datatypes we can see that there are default values for all primitive types and any reference variable to an object. When we declare a primitive type inside a method we may notice that it does not have such a default type.

Whenever we have a primitive type variable or a reference variable as a class member variable (a variable declared outside of any method inside a class - more on that later) or inside an array it receives one of the default values shown to the left. 

If we declare an int array x as new int[5] then all five of its values will be set to zero, doing the same with String will result in all reference variables being null.

Arrays

length

int[] intArr = new int[4];
int l = intArr.length;

Once the length of an array is set it cannot change. This is the reason why every array contains a fixed value length accessible through the reference variable to the array.

One might ask why we would not have a length() method instead which is based on this value not being able to change. It would then also make more sense to have this as well for Strings but String is a class so we use a method instead. 

Arrays

Bounds

OutOfBounds.png

Seeing as arrays have a fixed size it is reasonable to ask what happens if we attempt to access elements outside of the arrays bounds.

Whenever we attempt to access an element out of bounds Java will produce an error letting us know that we cannot access elements out of the bounds of an array.

Arrays

Arrays and For Loops

IterateArray.png

Whenever we want to do an operation on each element inside a for loop and we access each of its elements in order we want to use a for loop, we use the length of the array given to use by calling .length for this purpose.

The elements in the array go from index 0 (inclusive) to index length (exclusive). To the left one can see an example of a for loop going over all elements in an array.

bottom of page