Object-Oriented Programming with Java, part I + II

cc

This material is licensed under the Creative Commons BY-NC-SA license, which means that you can use it and distribute it freely so long as you do not erase the names of the original authors. If you make changes in the material and want to distribute this altered version of the material, you have to license it with a similar free license. The use of the material for commercial use is prohibited without a separate agreement.

Authors: Arto Hellas, Matti Luukkainen
Translators to English: Emilia Hjelm, Alex H. Virtanen, Matti Luukkainen, Virpi Sumu, Birunthan Mohanathas, Etiënne Goossens
Extra material added by: Etiënne Goossens, Maurice Snoeren, Johan Talboom

The course is maintained by De Haagse Hogeschool


5 Methods

We have so far used many different commands of Java: assignment, calculations, comparison, if structures and while structures. We have been using a “command” System.out.println() to print text. We can also count the maximum of two numbers with the help of the “command” Math.max(). We are also familiar with reader.nextLine(), usually seen together with Integer.parseInt().

If we take a closer look, we notice that those commands differ from if and while (etc). The first difference is that after the command there are brackets () and sometimes an input for the command inside those brackets. Actually, the commands ending with brackets are not called commands, but methods.

Technically speaking, a method is a piece of code that can be called from different places of the program code. The line of code System.out.println("I am a parameter given to the method!") means that we call a method that actually handles the printing. After the method has been executed we go back to where we called the method, and continue executing. The input given to the method inside the brackets is called a method parameter.

In addition to a parameter, the method can also have a return value, for example, a familiar line of code:

int number = Integer.parseInt( reader.nextLine() );

includes two method calls. First the inner method reader.nextLine is called. That method has the integer typed by the user as a return value. Next the outer method Integer.parseInt is called. As a parameter for that method there is the string of characters that was received from the reader.nextLine method as a return value. The return value for the method Integer.parseInt is the string of characters transformed into an integer (whole number).

Method names also seem to include a dot, for example reader.nextLine(). Actually the method name starts after the dot, here it is nextLine(). The first part of the command that comes before the dot shows whose method is in question. Here the method belongs to the reader, which means that we have the reader’s method nextLine. Later we will learn more precisely about the owner of the method (or the name on the left side of the dot). An attentive reader will notice that the method System.out.println() has two dots. Here, the method name is println and System.out is the owner of the method. Roughly System.out means the computer monitor.

This far we have been using ready-made methods from Java libraries. Next we will learn how to create our own methods.

5.1 Self-written methods

This far we have been using a programming style where code is written (and read and executed) from top to bottom.

It was mentioned before that “a method is a piece of code that can be called from different places of the program code”. Ready-made methods of Java have been used since our very first program.

In addition to using these ready-made methods programmers can write their own methods for programs to call. In the real world, it is really exceptional if the program does not include any self-written methods. From now on almost every program we create during this course will include self-written methods.

The methods are written in the program body outside the main’s braces ( { and } ) but still inside the outermost braces, for example like this: :

import java.util.Scanner;

public class ProgramBody {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        // program code
    }

    // self-written methods
}

Let us create a method greet.

public static void greet() {
    System.out.println("Greetings from the world of methods!");
}

And let us place it in the right spot.

import java.util.Scanner;

public class ProgramBody {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        // program code
    }

    // self-written methods
    public static void greet() {
        System.out.println("Greetings from the world of methods!");
    }
}

In order to define a new method we need to write two things. In the first row of the method definition, you will find the name of the method, in this case greet. On the left side of the name you will find the definitions public static void. On the next line, the code block marked by the braces ({ and }). Inside it, the method’s code, or the commands that will be executed when the method is called. Our method greet only writes one line of text to the screen.

It is easy to call a self-written method. It happens by writing the method name, brackets () and a semicolon. In the next example main (or the main program) calls for our method, first once and then several times.

import java.util.Scanner;

public class ProgramBody {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);

        // program code
        System.out.println("Let us try if we can get to the method world:");
        greet();

        System.out.println("It seems like we can, let us try again:");
        greet();
        greet();
        greet();
    }

    // self-written methods
    public static void greet() {
        System.out.println("Greetings from the world of methods!");
    }
}

When the program is executed, we see the following output:

Let us try if we can get to the method world:
Greetings from the world of methods!
It seems like we can, let us try again:
Greetings from the world of methods!
Greetings from the world of methods!
Greetings from the world of methods!

What is noteworthy here is the execution order of the program code. The execution starts with the main program’s (or main’s) lines of code, from top to bottom, one by one. When the line of code to be executed happens to be a method call, the lines of code in the method block are executed again one by one. When the method block ends, the execution continues from the place where the method was called. To be exact, the execution continues from the next line after the original method call.

To be even more exact, the main program is also a method. When the program starts, the operation system calls for the main method. That means that the main method is the starting point of the program and the execution starts from the first code line of main. The program execution ends when it reaches the end of main.

From now on when we introduce methods, we will not point out that they need to be written in the right place inside the program code. For example, a method cannot be defined inside another method.

Exercise 3-1: Printing out text

Create a method printText that prints the following string of characters: “In the beginning there were the swamp, the hoe and Java.” and a line break.

public static void main(String[] args) {
   printText();
}

public static void printText() {
   // write your code here
}

The program output:

In the beginning there were the swamp, the hoe and Java.

Exercise 3-2: Many prints

Develop the program by adding the following feature: the main program should ask the user how many times the text should be printed (meaning how many times the method is called).

public static void main(String[] args) {
   // ask the user how many times the text should be printed
   // use the while structure to call the printText method several times
}

public static void printText() {
   // write your code here
}

The program output:

How many?
~~7~~
In the beginning there were the swamp, the hoe and Java.
In the beginning there were the swamp, the hoe and Java.
In the beginning there were the swamp, the hoe and Java.
In the beginning there were the swamp, the hoe and Java.
In the beginning there were the swamp, the hoe and Java.
In the beginning there were the swamp, the hoe and Java.
In the beginning there were the swamp, the hoe and Java.

Note: you should print the assisting question How many? on its own line!

5.2.1 Method parameters

We can make our methods more useful by giving it parameters! Parameters are variables that we define inside brackets in the first line, just after the method name. When the method is called, the parameters are assigned values.

In the next example we define a method with a parameter, its name will be greet and its parameter will be a variable of the type String called name.

public static void greet(String name) {
    System.out.println("Hi " + name + ", greetings from the world of methods!");
}

Let us next call the greet method so that on the first try we give its parameter the value Matt and on the second try Arthur.

public static void main(String[] args) {
    greet("Matt");
    greet("Arthur");
}
Hi Matt, greetings from the world of methods!
Hi Arthur, greetings from the world of methods!

More complicated expressions can also be used as a parameter for our self-written methods, the same way we used them together with the ready-made System.out.println() method.

public static void main(String[] args) {
    String name1 = "Anne";
    String name2 = "Green";
    greet( name1 + " " + name2 );

    int age = 24;
    greet("John " + age + " years");
}
Hi Anne Green, greetings from the world of methods!
Hi John 24 years, greetings from the world of methods!

In both cases the method has only one parameter. The value for the parameter is calculated before calling the method. In the first case the parameter value comes from the String concatenation (a cool word that means putting the text together) name1 + " " + name2. The value for the concatenation is Anne Green. In the second case we get the parameter value from the String concatenation "John " + age + " years".

5.2.2 Many parameters

A method can be defined to have more than one parameter. In this case, the parameters are always listed in the same order.

public static void greet(String name, String greetingsFrom) {
    System.out.println("Hi " + name + ", greetings from " + greetingsFrom);
}
String who = "Matt";
String greetings = "Alabama";

greet(who, greetings);
greet(who, greetings + " from Nevada");

In the last greet function (or method) call the second parameter is formed by concatenating (or adding) the text “from Nevada” to the variable greetings. This is done before the actual function call.

Hi Matt, greetings from Alabama
Hi Matt, greetings from Alabama from Nevada

5.2.3 Method calling another method

Methods can also be called outside of main. Methods can call each other! Let us create a method greetManyTimes that greets the user many times getting assistance from the method greet:

public static void greet(String name) {
    System.out.println("Hi " + name + ", greetings from the world of methods!");
}

public static void greetManyTimes(String name, int times) {
    int i = 0;
    while ( i < times ) {
        greet(name);
        i++;
    }

}

public static void main(String[] args) {
    greetManyTimes("Anthony", 3);
    System.out.println("and");
    greetManyTimes("Martin", 2);
}

Output:

Hi Anthony, greetings from the world of methods!
Hi Anthony, greetings from the world of methods!
Hi Anthony, greetings from the world of methods!
and
Hi Martin, greetings from the world of methods!
Hi Martin, greetings from the world of methods!

Exercise 3-3: Printing

Exercise 3-3.1: Printing stars

Create a method printStars that prints the given amount of stars and a line break.

Create the method in the following body:

private static void printStars(int amount) {
   // you can print one star with the command
   // System.out.print("*");
   // call this command amount times
}

public static void main(String[] args) {
   printStars(5);
   printStars(3);
   printStars(9);
}

The program output:

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

Note: you can return exercises that contain many parts to the exercise robot even though you are not finished with all parts. In that case, the robot complains about tests in the unfinished parts of the exercise, but gives you points for all tests that pass.

Exercise 3-3.2: Printing a square

Create a method printSquare(int sideSize) that prints a square using our previous method printStars. The method call printSquare(4), for example, prints the following:

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

Note: in order to complete the exercise it is not enough that the outprint looks good. Inside the printSquare method the printing must be done using the printStars method.

When you are in the middle of making your program, you should verify the correctness of your methods by writing some test code into your main method.

Exercise 3-3.3: Printing a rectangle

Create a method printRectangle(int width, int height) that prints a rectangle using the printStars method. The call printRectangle(17,3), for example, has the following output:

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

Exercise 3-3.4: Printing a left-aligned triangle

Create the method printTriangle(int size) that prints a triangle using the printStars method. The method call printTriangle(4), for example, has the following output:

*
**
***
****

Exercise 3-4: Printing Like A Boss

like a boss

Exercise 3-4.1: Printing stars and whitespaces

Create a method printWhitespaces(int size) that prints the given amount of whitespaces. Them method should not print a line break.

Reimplement or copy the method printStars(int size) from the previous exercise. Make sure this method prints a line break (newline)

Exercise 3-4.2: Printing a right-aligned triangle

Create the method printTriangle(int size) that prints a triangle using the methods printWhitespaces and printStars. Note: do not print anything in the method itself, just call the helper methods to do the actual printing.

For example, the method call printTriangle(4) has the following output:

   *
  **
 ***
****

Exercise 3-4.3: Printing a Christmas tree

Create the method xmasTree(int height) that prints a Christmas tree using the methods printWhitespaces and printStars. A Christmas tree consists of a triangle of given height and a stand. The stand is two stars tall and three stars wide and it is located in the center of the bottom of the triangle. Note: do not print anything in the method itself, just call the helper methods to do the actual printing.

The method call xmasTree(4), for example, has the following output:

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

The method call xmasTree(10) has the following output:

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

Second note: You don’t need to worry about heights below 3!

Exercise 3-5: Guessing a number game

In this exercise the following game is created:

Guess a number: ~~73~~
The number is lesser, guesses made: 1
Guess a number: ~~22~~
The number is greater, guesses made: 2
Guess a number: ~~51~~
The number is greater, guesses made: 3
Guess a number: ~~62~~
The number is greater, guesses made: 4
Guess a number: ~~68~~
The number is greater, guesses made: 5
Guess a number: ~~71~~
The number is lesser, guesses made: 6
Guess a number: ~~70~~
Congratulations, your guess is correct!

Exercise 3-5.1: Guessing a number

The program that comes with the exercise contains a command called drawNumber. It draws a number, which is in the range 0 to 100 (both 0 and 100 are possible). Create a program that draws a number. Then the user has the chance to guess once, what the number is. The program should to print “The number is lesser”, “The number is greater” or “Congratulations, your guess is correct!” depending on the number the user typed.

Guess a number: ~~12~~
The number is greater

Guess a number: ~~66~~
The number is lesser

Guess a number: ~~42~~
Congratulations, your guess is correct!

Exercise 3-5.2: Repeated guessing

Develop your program by adding the following functionality: the guessing should be made repeatedly until the user types the right number. Note that you need to draw the number by using the drawNumber command before the repetition. Why? What happens if you draw the number inside the repetition?

In the example below, the command call drawNumber returned the value 83.

Guess a number: ~~55~~
The number is greater
Guess a number: ~~85~~
The number is lesser
Guess a number: ~~77~~
The number is greater
Guess a number: ~~81~~
The number is greater
Guess a number: ~~83~~
Congratulations, your guess is correct!

Exercise 3-5.3: Counting the guesses

Develop your program by adding the following functionality: the program needs to include a variable of type int, which is used to count the guesses the user has made. The program should always print the number of guesses along with the answer.

Guess a number: ~~55~~
The number is greater, guesses made: 1
Guess a number: ~~85~~
The number is lesser, guesses made: 2
Guess a number: ~~77~~
The number is greater, guesses made: 3
Guess a number: ~~81~~
The number is greater, guesses made: 4
Guess a number: ~~83~~
Congratulations, your guess is correct!

Exercise 3-6: A text-based user interface for the Hangman game

Your friend has programmed a Hangman game for you, but the game lacks the user inferface. The Hangman has the following methods:

  • hangman.gameOn()
    Shows if the game is on
  • hangman.printStatus()
    Prints the game status. Shows how many guesses have been made and the letters that have not been used yet.
  • hangman.printWord()
    Prints the word the user tries to guess. The letters that have not been guessed yet are hidden as question marks, like “v?ri?ble”.
  • hangman.printMan()
    Prints the Hangman.
  • hangman.guess(String letter)
    Guesses the letter that is given as a parameter.

You will get a program body from the exercise robot. It already contains some functionalities:

        Scanner reader = new Scanner(System.in);
        Hangman hangman = new Hangman();

        System.out.println("************");
        System.out.println("* Hangman *");
        System.out.println("************");
        System.out.println("");
        printMenu();
        System.out.println("");

        // ADD YOUR IMPLEMENTATION HERE

    System.out.println("Thank you for playing!");

In addition to the program body, you will get the method called printMenu:

    public static void printMenu() {
        System.out.println(" * menu *");
        System.out.println("quit   - quits the game");
        System.out.println("status  - prints the game status");
        System.out.println("a single letter uses the letter as a guess");
        System.out.println("an empty line prints this menu");
    }

The exercise is completed in small steps.

Exercise 3-6.1: Loops and ending loops

Create a loop in the program that works as a base for the rest of the user interface. Ask the user to submit the command inside the loop. If the command is “quit”, break the loop.

Use the command hangman.gameOn as the condition for the while structure. The loop should look like:

while (hangman.gameOn()) {
    String command = reader.nextLine();
    // ...
}

In the next set (week) of exercises, we will find out what this peculiar-looking condition for ending the loop is about.

This far the program should produce the following output:

************
* Hangman *
************

 * menu *
quit   - quits the game
status - prints the game status
a single letter uses the letter as a guess
an empty line prints this menu

Type a command:
do not quit

Type a command:
quit
Thank you for playing!

Exercise 3-6.2: Printing the status

If the user gives the command “status”, print the status using the method hangman.printStatus().

************
* Hangman *
************

* menu *
quit   - quits the game
status - prints the game status
a single letter uses the letter as a guess
an empty line prints this menu

Type a command:
status
You have not made any guesses yet.
Unused letters: abcdefghijklmnopqrstuvwxyz

Type a command:
quit
Thank you for playing!

Exercise 3-6.3: Making a guess

If the user types in a single letter as a command, use it to make a guess. Guessing a letter occurs in the method hangman.guess(command). The guessing command has its own printing functionality, which it uses to print more information about the guess.

Hint: finding out if the command is a single letter is done as follows:

String command = reader.nextLine();

if(command.length() == 1) {  // command has only one letter, so it must be a guess
    hangman.guess(command);
}
...
Type a command:
a
The letter a is not in the word.

Type a command:
b
The letter b is not in the word.

Type a command:
c
The letter c was found in the word!

Type a command:
quit
Thank you for playing!

Exercise 3-6.4: Printing out the menu

If the user types an empty string of characters, meaning a string that has zero length, you need to call the method printMenu. Note that the method printMenu is not in the Hangman game but in your own program.

Note: checking if the string is empty is done as follows:

String winnie = "the pooh";
if(winnie.isEmpty()) {
    System.out.println("String was empty");
} else {
    System.out.println("I found something!");
}

Exercise 3-6.5: Printing the man and the word

If the user has not typed the command quit, you should call the Hangman game commands hangman.printMan() and hangman.printWord()` at the end of the loop.

...
Type a command:
a
The letter a is not in the word.
 ____
 |
 |
 |
 |
/|\
Word to be guessed: ????

Type a command:
m
The letter m was found in the word!
 ____
 |
 |
 |
 |
/|\
Word to be guessed: m???

Type a command:
quit
Thank you for playing!

5.3 More about methods

5.3.1 Methods and visibility of variables

Let us try to change from within a method the value of a variable located in the main program.

// main program
public static void main(String[] args) {
    int number = 1;
    addThree();
}

// method
public static void addThree() {
    number = number + 3;
}

Unfortunately this program will not work, because the method cannot “see” the variable number located in the main program.

This holds generally. Variables defined in the main program are not visible for other methods. Also, the other way is similar: variables defined in methods are not visible for other methods or the main program. The only way to give information to a method from the outside is to use parameters.

// main program
public static void main(String[] args) {
    int number = 1;
    System.out.println("Main program variable number holds the value: " + number);
    addThree(number);
    System.out.println("Main program variable number holds the value: " + number);
}

// method
public static void addThree(int number) {
    System.out.println("Method parameter number holds the value: " + number);
    number = number + 3;
    System.out.println("Method parameter number holds the value: " + number);
}

In the program above the method addThree has a parameter called number. This parameter is copied (duplicated) for the method to use. When the program above is executed we see the following output:

Main program variable number holds the value: 1
Method parameter number holds the value: 1
Method parameter number holds the value: 4
Main program variable number holds the value:  1

The number we gave as a parameter to the method was copied for the method to use. If we would like the main program to be able to use the new value generated by the method, the method needs to return that value.

5.3.2 Return values

A method can return a value. In the examples above, methods have not been returning anything. This is expressed by writing void in the first line of the method, just before it’s name.

public static void addThree() {
  ...

When defining a method that returns a value, we also have to define the type of the return value. We can define the type of the return value by writing it just before the name of the method. Next, we have a method that always returns the number 10 (type int). Returning a value is accomplished with the command return:

public static int alwaysReturnTen() {
    return 10;
}

If we want to use the returned value later, we have to catch the return value and store it into a variable:

public static void main(String[] args) {
    int number = alwaysReturnTen();

    System.out.println( "method returned the number " + number );
}

The return value of the method is assigned to a variable of type int just like any other integer. The return value can also be a part of a sentence:

double number = 4 * alwaysReturnTen() + (alwaysReturnTen() / 2) - 8;

System.out.println( "calculation total " + number );

Every variable type we have seen this far can be used as a return value:

public static void methodThatReturnsNothing() {
  // method body
}

public static int methodThatReturnsInteger() {
  // method body, needs a return statement
}

public static String methodThatReturnsText() {
  // method body, needs a return statement
}

public static double methodThatReturnsFloatingpoint() {
  // method body, needs a return statement
}

If the method is defined to have a return value, it also has to return a value. The following method is incorrect:

public static String wrongMethod() {
    System.out.println("I tell you that I will return a String but I do not!");
}

In the following example, we define a method for calculating a sum. Then, we use the method to calculate 2 + 7. The return value (returned after the method call) is assigned to a variable called sumNumbers.

public static int sum(int first, int second) {
    return first + second;
}

Method call:

int sumNumbers = sum(2, 7);
// sumNumbers now holds the value 9
Let us expand the example program so that the user types the numbers.

public static void main(String[] args) {
    Scanner reader = new Scanner(System.in);

    System.out.print("Type the first number: ");
    int first = Integer.parseInt( reader.nextLine() );

    System.out.print("Type the second number: ");
    int second = Integer.parseInt( reader.nextLine() );

    System.out.print("Total: " + sum(first,second) );
}

public static int sum(int first, int second) {
    return first + second;
}

As we can see, the return value of the method does not always need to be assigned to a variable. It can also act as a part of the printing command just like any other integer value.

In the next example, we call the method sum using integers that we get as return values from the method sum.

int first = 3;
int second = 2;

sum(sum(1, 2), sum(first, second));
// 1) the inner methods are executed:
//    sum(1, 2) = 3   and sum(first, second) = 5
// 2) the outer method is executed:
//    sum(3, 5) = 8

5.3.3 The method’s own variables

The following method calculates the average of the numbers the method gets as parameters. The method uses helper variables sum and average. The method’s own variables can be introduced just like any other variables.

public static double average(int number1, int number2, int number3) {

    int sum = number1 + number2 + number3;
    double average = sum / 3.0;

    return average;
}

Exercise 3-7: Sum of numbers

Create the method sum that calculates the sum of numbers the method receives as parameters.

Place the method in the following program body:

public static int sum(int number1, int number2, int number3, int number4) {
    // write program code here
    // remember that the method needs a return in the end
}

public static void main(String[] args) {
    int answer = sum(4, 3, 6, 1);
    System.out.println("sum: " + answer);
}

Example output:

sum: 14

Note: if an exercise involves a method returning something, it means that the return type needs to be defined for the method, and that the method needs to return a value of that type using the return command. In this case, the method does not print (or use the command System.out.println(..)), the method caller handles printing, here, the main program.

Exercise 3-8: Least

Create the method least, which returns the least of the numbers given as parameters. If the parameters are equal, you can decide which one is returned.

public static int least(int number1, int number2) {
    // write program code here
    // do not print anything inside the method

    // method needs a return in the end
}

public static void main(String[] args) {
    int answer =  least(2, 7);
    System.out.println("Least: " + answer);
}

Example output:

Least: 2

Exercise 3-9: Greatest

Create the method greatest, which gets three integers as parameters and then returns the greatest of them. If there are several parameters that are equally great, you can decide which one is returned. Printing should be done in the main program.

public static int greatest(int number1, int number2, int number3) {
    // write your code here
}

public static void main(String[] args) {
    int answer =  greatest(2, 7, 3);
    System.out.println("Greatest: " + answer);
}

Example output:

Greatest: 7

Exercise 3-10: Average of given numbers

Create the method average, which calculates the average of the numbers it gets as parameters. Inside the method you should use the method sum as a helper!

Place the method in the following program body:

public static double average(int number1, int number2, int number3, int number4) {
    // write your code here
}

public static void main(String[] args) {
    double answer = average(4, 3, 6, 1);
    System.out.println("average: " + answer);
}

Program output:

average: 3.5

Make sure you remember how you can transform a whole number (int) into a decimal number (double)!

5.4 String methods

5.4.1 Comparison, length and position

In this section, we take a closer look at strings of characters in Java, which are called Strings. We have already used variables of String type when printing, and learned how to compare Strings. Comparing two strings is performed by calling the equals() method of the string.

String animal = "Dog";

if( animal.equals("Dog") ) {
    System.out.println(animal + " says bow-wow");
} else if ( animal.equals("Cat") ) {
    System.out.println(animal + " says meow meow");
}

It is possible to ask the string how many characters long it is by writing .length() after it’s name. In other words, we are calling its length() method.

String banana = "banana";
String cucumber = "cucumber";
String together = banana + cucumber;

System.out.println("The length of banana is " + banana.length());
System.out.println("The length of  cucumber is " + cucumber.length());
System.out.println("The word " + together + " length is " + together.length());

In the above code, the method length() is called for three different strings. The call banana.length() calls only the method that gives the length of the string banana, while cucumber.length() calls the method that gives the length of the string cucumber etc. The left part before the dot says whose method is called.

Java has a special data type, called char, to be used for characters. A char variable can store only one character. A string variable can return a character from a specific location in itself with the method charAt() that uses the index of the location as a parameter. Note that counting the index of the character starts from zero!

String word = "Supercalifragilisticexpialidocious";

char character = word.charAt(3);
System.out.println("The 4th character of the word is " + character); //prints "e"

The characters in a string are numbered (indexed) starting from 0. This means that we can reach the last character in a string with number (or index) “the length of the word minus one”, or word.charAt(word.length()-1). The following example will make the program crash, because we are trying to get a character from an index that does not exist.

char character = word.charAt(word.length());

Exercise 3-11: The length of a name

Create a program that asks for the user’s name and says how many characters the name contains.

Type your name: ~~Paul~~
Number of characters: 4
Type your name: ~~Catherine~~
Number of characters: 9

Note! Your program should be structured so that you put the calculating of the name length in it’s own method: public static int calculateCharacters(String text). The tests will be testing both the method calculateCharacters and the program overall.

Exercise 3-12: First character

Create a program that asks for the user’s name and gives the first character.

Type your name: ~~Paul~~
First character: P
Type your name: ~~Catherine~~
First character: C

Note! Your program should be structured so that you put the search for the first character in its own method: public static char firstCharacter(String text). The tests will be testing both the method firstCharacter and the program overall

Exercise 3-13: Last character

Create a program that asks for the user’s name and gives the last character.

Type your name: Paul
Last character: l
Type your name: Catherine
Last character: e

Note! Your program should be structured so that you put the search for the last character in its own method: public static char lastCharacter(String text). The tests will be testing both the method lastCharacter and the program overall.

Exercise 3-14: Separating first characters

Create a program that asks for the user’s name and gives its first, second and third characters separately. If the name length is less than three, the program prints nothing. You do not need to create methods in this exercise.

Type your name: ~~Paul~~
1. character: P
2. character: a
3. character: u
Type your name: ~~me~~

Note: watch closely at the output in this and the following exercise. The print needs to contain a space after the dot and the colon!

Exercise 3-15: Separating characters

Create a program that asks for the user’s name and gives its characters separately. You do not need to create methods in this exercise.

Type your name: ~~Paul~~
1. character: P
2. character: a
3. character: u
4. character: l

Hint: using a while loop helps in this exercise!

Type your name: ~~Catherine~~
1. character: C
2. character: a
3. character: t
4. character: h
5. character: e
6. character: r
7. character: i
8. character: n
9. character: e

Exercise 3-16: Reversing a name

Create a program that asks for the user’s name and prints it in reverse order. You do not need to create a separate method for this.

Type your name: ~~Paul~~
In reverse order: luaP
Type your name: ~~Catherine~~
In reverse order: enirehtaC

Hint: You can print one character using the command System.out.print()

5.4.2 Other methods for strings

We often want to read only a specific part of a string. A method in the String class called substring makes this possible. It can be used in two ways:

String word = "Supercalifragilisticexpialidocious";
System.out.println(word.substring(14)); //prints "listicexpialidocious"
System.out.println(word.substring(9,20)); //prints "fragilistic"

We can store the return value in a variable, because the return value of the substring method is of type String.

String book = "Mary Poppins";
String endpart = book.substring(5);
System.out.println("Harry " + endpart); // prints "Harry Poppins"

Methods in the String class also make it possible to search for a specific word in text. For example, the word “or” can be found in the word “Horse”. A method called indexOf() searches for the word given as a parameter in a string. If the word is found, it returns the starting index (location), remember that the numbering starts from 0 of the word. If the word is not found, the method returns the value -1.

String word = "aesthetically";

int index = word.indexOf("tic"); // index value will be 6
System.out.println(word.substring(index)); //prints "tically"

index = word.indexOf("ally"); //index value will be 9
System.out.println(word.substring(index)); //prints "ally"

index = word.indexOf("book"); // string "aesthetically" does not include "book"
System.out.println(index); //prints -1
System.out.println(word.substring(index)); //error!

Exercise 3-17: First part

Create a program that prints the first part of a word. The program asks the user for the word and the length of the first part. Use the substring method in your program.

Type a word: ~~example~~
Length of the first part: 4
Result: exam
Type a word: ~~example~~
Length of the first part: 6
Result: exampl

Exercise 3-18: The end part

Create a program that prints the end part of a word. The program asks the user for the word and the length of the end part. Use the substring method in your program.

Type a word: ~~example~~
Length of the end part: 4
Result: mple
Type a word: ~~example~~
Length of the end part: 6
Result: xample

Exercise 3-19: A word inside a word

Create a program that asks the user for two words. Then the program tells if the second word is included in the first word. Use String method indexOf in your program.

Type the first word: ~~glitter~~
Type the second word: ~~litter~~
The word 'litter' is found in the word 'glitter'.
Type the first word: ~~glitter~~
Type the second word: ~~clean~~
The word 'clean' is not found in the word 'glitter'.

Note: Make your program outputs (prints) match exactly the example above!

Exercise 3-20: Reversing text

Create the method reverse that puts the given string in reversed order. Use the following program body for the method:

public static String reverse(String text) {
    // write your code here
}

public static void main(String[] args) {
    System.out.print("Type in your text: ");
    String text = reader.nextLine();
    System.out.println("In reverse order: " + reverse(text));
}

Hint: you probably need to build the reversed string character by character in your method. You can use a String-type variable as a helper during the building process. In the beginning, the helper variable should have an empty string of characters as a value. After this, new characters are added to the string one by one.

String help = "";

// ...
// adding a character to the help variable
help = help + character;

Program output:

Type a text: ~~example~~
elpmaxe

5.5 Math Library

A lot of functionality can be implemented by now, using the basic code stuctures that we’ve encountered so far. We could for example, write a method to determine the absolute value of a number. The code for such a method could be as follows

public static int abs(int number)
{
    if(number < 0) {
        return -number;
    } else {
        return number;
    }
}

Writing these methods for all basic math concepts is not very hard, but it is a lot of work to write them. Fortunately, a lot of this has already been written, and combined in the Math structure. We can find a lot of information on this in the documentation. In this documentation, we can typically find some very important information on these method. The document starts with a long list of available methods, followed by a short description. Clicking on a method will show a longer description

abs

In the line public static int abs(int a) we can see the parameter type, and a description of the parameter. We can also see the return type, which will be covered next week. Also a precise description is available, to see exactly what this method will do.

Some convenient methods are:

Also you can use Math.PI as a value of

5.6 Debugging using a debugger

To see the contents of variables so far, we’ve been using the System.out.println() command. This works fine for showing the contents of simple variables, or the flow of execution in a simple program, but when programs get more complicated, the output will also get more complicated. This is why there are other tools available to debug your program, a debugger.

A debugger can pause the execution of your program, so you can view the values of variables, and then allow you to run your code line by line to see the flow of execution.

So far we’ve been using the TMC plugin’s run buttons tmc to start our program. In order to run the program with debugging, we have to use the debug tmc button, or use the debug option in the run menu. Running the program with a debugger won’t change anything about the execution of your program, so you won’t see a difference by just pressing debug

breakpointTo pause the execution to inspect, a breakpoint can be added to the code. This is done by clicking in the gutter of your code window (just right of the line number). A red dot will appear to show the position of the breakpoint. To remove the breakpoint, just click the red dot to remove it. When running the code with a debugger and a breakpoint, the execution will pause the moment java starts executing that line. The line with the breakpoint will not have been executed yet.

When pausing execution, a debugging window will appear in the bottom of IntelliJ. This is a powerful view into your application, with a lot of buttons and features.

debugger

On the left side are buttons for

On the top are buttons for

The main view consists of 2 parts, on the left is the call stack (we’ll go more in depth into the callstack in chapter 2-9), and the variables windows. The variables windows is used to view the contents of variables. By default, all the ‘used’ variables are shown, so if your program uses a variable called months, this variable will automatically be shown here. It is also possible to add variables or expressions in the watch, by double-clicking and typing the name of the variable, or the expression

The process of debugging is usually used to see if the program is doing what you have in mind, validate the code execution path and check the variable contents to see if they are valid. This means a lot of manual stepping through the code, step by step, and takes a lot of time. This is why debugging can take a lot of time, and is better avoided by thinking before you start typing

5.7 Call stack

When methods call each other, they form what is called a calls stack. This is a list of methods, where each method has been called by the entry over it in the list. The call stack in IntelliJ is shown when the application is paused in the debugger. Concider the following program

public class Main {
    public static void main(String[] args) {
        method1(10);
    }

    public static void method1(int value) {
        method2(value+1);
    }

    public static void method2(int value) {
        method3(value/2);
    }

    public static void method3(int value) {
        System.out.println(value);
    }
}

If we put a breakpoint at the line with the System.out.println code, and look at IntelliJ, we get the following callstack:

callstack

Here you can see the main method called the method1, which in turn called method2, which in turn called method3. You can also see the linenumbers in this callstack, and even click on a line in the callstack to see the variables in that context. By clicking through the different methods, you can see the variable value change in every method, so it is very easy to trace back what happened

Some other debugging features that can help you debug your code with methods are the stepping features

This call stack can also be retrieved while the application is running. Usually you will be viewing this call stack after the program is done running (because the call stack will be printed out), and this is referred to as a back trace or a stack trace. Usually when something goes wrong in your program, java will print out a stack trace


end of week 3