Methods

So far our experience with methods has been limited to calling them (for example when we use the equals() method on an instance of a String). It is often however useful to be able to create our own methods if we have a particular piece of functionality we want to use more than once. Another good reason to create a method is to document our code. Consider the rather complex piece of code below:

System.out.println("Please type a phrase");
java.util.Scanner scanner = new java.util.Scanner(System.in);
String text = scanner.nextLine();
text = text.toLowerCase();
int count = 0;
for (int i = 0; i<text.length(); i++){
   char letter = text.charAt(i);
   if (letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u' ){
   count++;
   }
}
System.out.println("There are " + count + " vowels in your phrase");
If you read through the code, until you get to the last statement, you may find it is not to easy to understand out what is happening.

Instead it would be easier if the code looked like this:

System.out.println("Please type a phrase");
int count = countOfVowelsInUserInput();
System.out.println("There are " + count + " vowels in your phrase");
In this example the code has been extracted to a method, which we have named countOfVowelsInUserInput(). The name of the method makes it clear what its purpose is, and reduces the amount of comments needed in our code. What it doesn't show however is the method itself.

The new method we would need to create would look like this (the code identical to that above has been made lighter):

public static int countOfVowelsInUserInput(){
    java.util.Scanner scanner = new java.util.Scanner(System.in);
   String text = scanner.nextLine();
   text = text.toLowerCase();
   int count = 0;
   for (int i = 0; i<text.length(); i++){
       char letter=text.charAt(i);
       if (letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u' ){
       count++;
       }
   }
   return count;
}
There are a lot of words in the declaration of the method, taking each one in turn, a brief description is given:

The final thing we need to be aware of, is where to place the method. Typically, it needs to go outside the method we are in, but still within the class. To demonstrate this, the whole file is shown below:

package com.tinyappco;

public class Main {

    public static void main(String[] args) {

        System.out.println("Please type a phrase");
        int count = countOfVowelsInUserInput();
        System.out.println("There are " + count + " vowels in your phrase");

    } //this brace closes the main method

    public static int countOfVowelsInUserInput(){

        java.util.Scanner scanner = new java.util.Scanner(System.in);
        String text = scanner.nextLine();
        text = text.toLowerCase();
        int count = 0;
        for (int i = 0; i<text.length(); i++){
            char letter = text.charAt(i);
            if (letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'){
                count++;
            }
        }
        return count;
        
    } //this brace closes the countOfVowelsInUserInput () method

} //this brace closes the class

Variable names in methods

Names of variables created within methods are independant of those used outside the method, they are also not accessible from outside the methods (their scope is limited to the method they are declared in) - see the modified version of the code below which has identical behaviour to that above

public static void main(String[] args) {
    System.out.println("Please type a phrase");
    int countOfVowels = countOfVowelsInUserInput();
    System.out.println("There are " + countOfVowels + " vowels in your phrase");
}
public static int countOfVowelsInUserInput(){
    java.util.Scanner scanner = new java.util.Scanner(System.in);
    String text = scanner.nextLine();
    text = text.toLowerCase();
    int count = 0;
    for (int i = 0; i<text.length(); i++){
        char letter = text.charAt(i);
        if (letter == 'a' || letter == 'e' || letter == 'i' || letter == 'o' || letter == 'u'){
            count++;
        }
    }
    return count;
}

Refactoring

The process of making improvements to code, without changing its intended function is known as refactoring. When developing software it is important to make sure that code is manageable, this typically means breaking down elements of functionality into small components (methods), so that the intended function is of any given section is clear from the name of the method rather than from heavy commenting. It also makes it easier to isolate and test individual components of code and therefore locate errors.

Tasks

Task 1. Refactoring - method extraction

  1. Using the above code as a starting point, refactor the code by extracting a method from the existing countOfVowelsInUserInput() which reads a line of text from the user and returns a string.

Task 2. User-friendly boolean value

  1. The Scanner provides a method for getting a Boolean value from the user, but it requires the user to type ‘true’ or ‘false’. This is not the most helpful from a user experience point of view.

    Write a method which will return a boolean. The methods should use the scanner to obtain a String from the user (which could be anything from the list below, and not necessarily in lower case, and return a Boolean value appropriate to the response)

    yes
    y
    true
    ok
    
    no
    n
    false
    

    A video walkthough for the first part of this task is available

  2. Modify the above method so that it repeatedly prompts the user, until they enter something that can be determined as an affirmative or negative response

Task 3. Write and refactor

  1. Create a new command line application in IntelliJ IDEA
  2. Write code in the main method to requst a line of text input from ther user, and determine the most common vowel in the text they have input and print a message informing them of this vowel (if there are multiple most common vowels, return the first one alphabetically).
    Spent more than 90 minutes working on this task?A solution ready for refactoring can be viewed here
  3. Refactor the code so that the functionality is split into one or more appropriately named methods. (You may be aware that we can pass parameters into methods, however do not worry about doing this yet)
  4. Test it with the following phrases
    • Beef stew
    • The cat sat on the mat
    • In the bin
    • zoom zoom
    • through and through