Skip to content

Instantly share code, notes, and snippets.

@sumanssaurabh
Forked from aziflaj/1.md
Created March 31, 2019 22:48
Show Gist options
  • Save sumanssaurabh/2ad3b35fc1f65f8113e80879b55ddf50 to your computer and use it in GitHub Desktop.
Save sumanssaurabh/2ad3b35fc1f65f8113e80879b55ddf50 to your computer and use it in GitHub Desktop.
Java Tutorials

Java Programming 1: Get started with Java programming

Java is a general-purpose, OOP language designed with the idea of Write Once, Run Anywhere (WORA), meaning that the Java code would work virtually in every computer without the need of re-compilation like C or C++. In order to obtain this unique portability, the computer needs to have the JVM (Java Virtual Machine) installed. Nowadays, Java is the most used programming language in the world, used for almost anything, from embedded programming to large software development, web application development and supercomputers. Java has 3 main implementation named Java EE, Java SE and Java ME meaning respectively Java Enterprise Edition, Java Standard Edition and Java Micro Edition (used in the abbreviated form as J2EE, J2SE and J2ME). Java, firstly developed at Sun Microsystems which merged into Oracle Corporation, was designed with 5 main principles in mind:

  • Simple, object-oriented and familiar

    Java makes programming simple using its build-in classes, object-oriented programming (high level of code abstraction) and its syntax is derived from C and C++, which makes it simple for programmers to adapt.

  • Robust and secure

    If you develop using Java, you need your software to be reliable. This is achieved using compile-time AND run-time checking, memory leaks don't exist because of Java's garbage collector. If you want to develop client-side application using Java applets, the language itself doesn't allow you to create malware, viruses, or get your hands in the system's files.

  • Architecture neutral and portable

    As stated before, Java code is a WORA code. It doesn't rely on the architecture, so you don't have to recompile the code so you can use it in another computer. The Java Compiler creates bytecode, not machine code. Bytecode runs on the JVM and has nothing to do with the machine where it runs, which makes it architecture neutral, unlike C and C++.

  • High performance

    Performance is what divides good programming languages from better programming languages. Through automatic garbage collector we get rid of any memory leaks. Some parts of the software can be written into lower level languages and compiled into machine code, which makes the software run faster than interpreted softwares.

  • Interpreted, threaded and dynamic

    The Java Interpreter makes the link time shorter, giving you the benefit of faster development, unlike compile-link-test used in C and C++. Also, Java lets you create concurrent applications, using the Thread class, which gives your application higher performance and a shorter execute time.In order to start developing with Java programming, we should firstly obtain JDK from the Oracle website.

Setting up the development environment

By setting up the development environment, you will have to install the JDK (Java Development Kit) and JRE (Java Runtime Environment) and probably even an IDE (Integrated Development Environment).

At this time, the latest Java version is Java 8. You can download it for free here. Make sure to download and install Java SE JDK (which is required to develop) and not JRE (which is required to run Java apps). Keep in mind that JDK includes JRE.

In order to check if Java is installed properly, we open the command-line tool (CMD in Windows, terminal in Linux and Mac OS) and type:

java –version

We can see something similar shows on the terminal:

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) Client VM (build 25.45-b02, mixed mode, sharing)

You can now start developing Java applications, by writing some code, compiling it, and then executing it. You could use an IDE, or a plain editor and command-line compilation. Popular Java IDEs are NetBeans, Eclipse IDE, IntelliJ IDEA, etc.

If you don't want to use an IDE you need to configure the JDK (add it to path). See this article about adding Java to PATH. In order to check if the configuration is done properly, you should close and reopen the terminal and type javac –version. This should show on the terminal something similar to:

javac 1.8.0_45

Now that the JDK is configured properly, you can start programming Java.

Your first program

This first program will only print a string of text in the terminal. Java also supports Graphical User Interface (GUI) programming, but we'll come to that later.

You can write our code in the IDE's text editor or in our favorite text editor (as long as it is not a word processing software like MS Word). If you use a text editor like gedit, Notepad++, emacs or else, you should save your code in a file called <filename>.java. Every Java code has this *.java format. Write this program in the editor:

/*
 * We are ready to create our
 * first Java program
 */
public class FirstJavaProgram {

    public static void main(String args[]) {
        // this line of code prints in the terminal
        System.out.println("We are learning Java programming");
    }
}

Save it as FirstJavaProgram.java. To compile it, open the terminal, go to the directory where FirstJavaProgram.java is saved and execute javac FirstJavaProgram.java. This creates a new file named FirstJavaProgram.class, which is our code compiled into bytecode. To run this program execute:

java FirstJavaProgram

And in the terminal this string of text shows up:

We are learning Java programming

This means that the program works properly; the compiler didn't show up any error or warning. Now I'll will explain the program line by line.

The first three lines are:

/*
 * We are ready to create our
 * first Java program
 */

This is a multiline comment. Everything between /* and */ is a multiline comment that is used for documenting the code.

The next line, public class FirstJavaProgram creates a class named FirstJavaProgram. In every Java program, there must be at least one public class which is the main class of the program. The name of the class and the file storing the code should match. If we declare a public class named Calculator, we should name the source file as Calculator.java, and the compiled class would be Calculator.class.

The next line is the main function. The main function is the entry point of the program; that is, the program execution starts at the top of the main function and ends at the bottom of the main function. The public static part will be clear when dealing with OOP principles and the void part when dealing with methods (functions). The main function has an argument, String args[], which allows the program to be called with command-line arguments.

The next line is a single line comment. Everything in the line after the // is a comment and it is ignored by the compiler (it doesn't affect the code). This single line comment can reach until the end of the line. Beside the multiline comment (between /* and */) and the single line comment (//) there is also another kind of comment, used for generating JavaDoc. The JavaDoc comments goes between /** and */ and its used for generating HTML files used for documenting the code. This is an example of a JavaDoc HTML file.

The other line is a statement inside the main function which is used to print something in the system standard output (stdout), that is the terminal. System.out.println() is the function used for this; it prints a string of text in the terminal (println stands for print line). The next lines of code are brackets, used to end the blocks of code.

The public class starts a block of code with the { and so does the main function. Control statements, functions, classes, interfaces, all of these create blocks of code that should end in }, otherwise you will get compile errors. If you use an IDE, you don't have to worry about the blocks of code; they are automatically created when you press the bracket that opens the block, and in most cases, you will get red notifications even before compiling the code.

Now that you learned this basic program, you are able to write in the terminal window whatever you want using the System.out.println() function. You can also use it to print the result of a mathematical expression. Try this:

public class SimpleMath {
    public static void main(String args[]) {
        System.out.println((10/5) * 2);
    }
}

It will calculate the division in brackets (10/5) and then multiply the result by 2 (* is the multiplication operator for Java). So this program will display 4 in the terminal.

Java Programming 2: Learning Data types, Operators and Standard I/O

We can say that Java has two kinds of data types: build-in and user-defined. The build-in data types are data types defined by the language itself and are also called standard data types:

  • byte : An 8-bit integer
  • short: A 16-bit integer
  • int: A 32-bit integer
  • long: A 64-bit integer
  • float: Floating-point values
  • double: Double-precision float values
  • char: Character values
  • boolean: A boolean data type, can be true or false

The user-defined data types are classes that can be defined by the programmer, using the class keyword.

We now can use these data types in math programs. Math is easy (or it should be for programmers), so we will try some math programs. The first one will be a simple temperature converter, Celsius to Kelvin:

public class TemperatureConverter {

    public static void main(String[] args) {
        // We now declare two double variables for holding the temperature.
        double celsius; // the temperature in celsius
        double kelvin; // the temperature in kelvin

        // we assign a value to the temperature
        celsius = 37.5;
        kelvin = celsius + 273.16; // we find its value in kelvin

        // let's display the result
        System.out.println(celsius + "C = " + kelvin + "K");
    }
}

This program creates the output:

37.5C = 310.66K

You can see here the declaration of two variables named celsius and kelvin. By declaring variables, we assign them some place in the memory of the computer, without giving an initial value (i.e. we don't initialize them). We could also declare them in only one line of code, separating their names by coma like this:

double celsius, kelvin;

After declaring them, we assign a value (initialize) to the temperature in Celsius, that is 37.5, and after we use this:

kelvin = celsius + 273.16;

to find the value of the temperature in Kelvin. Changing their places (celsius + 273.16 = kelvin;) would be a compile-time error and the code won't compile.

We assign the right value (celsius + 273.16) to the left variable (kelvin). The + operator is the operator used for adding numbers. This table shows the mathematical operators used by Java:

Operator Function
  •    | Addition
    
  •    | Subtraction
    
  •    | Multiplication
    

/ | Division % | Modulus (remainder) ++ | Addition by 1 (increment) -- | Subtraction by 1 (decrement)

In the System.out.println() function, we see that the + operator is used. This is an OOP concept that is called polymorphism (one interface, multiple methods), which means that one operator can be used for many functions. In this case, we concatenate strings with the + operator. The argument of System.out.println() function is celsius + "C = " + kelvin + "K" that creates a string with the value of celsius (37.5), followed by "C = ", followed by the value of kelvin, followed by the letter "K". This string is printed on the terminal. We can also use the + operator to concatenate two strings. Try this line of code in a program:

System.out.println("These two strings will " + "show in the same line");

Even though they are written in two lines of code, the + operator joins them into one single string, which shows in the terminal in only one line of text.

Now that we know these operators, we can try to use them in some programs. We know how to find the area of a right triangle, given the length of each leg. This we will do using the next program.

public class RightTriangleArea {

    public static void main(String[] args) {
        int leg1, leg2;
        double area;

        leg1 = 12;
        leg2 = 5;
        area = (leg1 * leg2) / 2;

        System.out.println("The right triangle with legs " + leg1
                    + " and " + leg2 + " has an area equal to " + area);
    }
}

In the line of code where we find the area, we used brackets ( and ). These brackets force Java to multiply leg1 and leg2 and then divide the result by 2, and assign the result to the area. You can test the program with other values for leg1 and leg2.

Naming conventions

Java does not allow you to use any kind of word as variable identifier. There are some restrictions and conventions in naming the variables. Firstly, you cannot use operators as part of the variable identifier. Names like triangle-area, triangle*area, this/variable, are not allowed. Also, you cannot use dot (.) in the name of a variable. The dot is a kind of operator (called dot operator) that is used by class members to access their methods and fields (we will deal with these later). Also, you cannot name variables with names used by Java as keywords (see the full list here).

Using any of these words as variable names would cause errors. Another rule is that the variable must not start with a number, but may have numbers in their identifier (like leg1). Also, you have to follow these conventions:

  • Constants (defined with the keyword final) are named using capitals. E.g. final float PI = 3.14.
  • Variables and functions are named using camelCase (e.g. nameOfStudent instead of name_of_student or NameOfStudent).
  • Classes and interfaces are named using PascalCase, e.g. a class would be Student, or TechCompany (like camelCase with the first letter capitalized).

Getting input from the user

Until now, you hard-coded the values in your programs. Take a look at RightTriangleArea.java. You defined the lengths of legs in the code and if you want to find the area of another right triangle, you have to change the values and re-compile the code. There is a simpler way (of course!), getting input from the user. Java uses System.out to write to the default output device (terminal) and System.in to read from the default input device (keyboard). In order to use the System.in, we will create a Scanner instance:

import java.util.Scanner;

public class RightTriangleArea {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        double leg1, leg2;
        double area;

        System.out.print("Enter the length of leg1: ");
        leg1 = stdIn.nextDouble();

        System.out.print("Enter the length of leg2: ");
        leg2 = stdIn.nextDouble();

        area = (leg1 * leg2) / 2;
        System.out.println("The right triangle with legs " + leg1
                    + " and " + leg2 + " has an area equal to " + area);
    }
}

In the first line of code we import a Java class: java.util.Scanner. This class is used to "scan" the console for input entered from the user.

Java comes with a rich API (Application Program Interface) with plenty of classes and methods you could use. java.util.Scanner is just one of them. In order to use the classes defined in the API, you would have to import them into the files where they need to be used.

We create a Scanner object named stdIn (stands for standard input) using the new operator. You can see a different function to print here, the System.out.print() function. The difference between this and the System.out.println() function is that the System.out.println() adds a newline in the end of the string, while the System.out.print() doesn't. You can also witness the usage of the dot operator. The Scanner class has methods (functions) that are used to read input, and any object (instance) of this class (like stdIn) can access these methods using the dot operator. Some methods of Scanner are listed here:

Method What it does
nextInt() Returns the next integer in the input string
nextDouble() Returns the next double in the input string
next() Returns the next word in the input string
nextLine() Returns the next line in the input string
nextBoolean() Returns the next boolean in the input
nextLong() Returns the next long in the input string

Now you can use these methods in order to make your programs get input from the user. We will now make a simple program that gets some information from the user and then prints what it learned:

import java.util.Scanner;

public class TalkToTheUser {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        String firstName, lastName;
        int age;

        System.out.print("Hello user! What's your first name? ");
        firstName = stdIn.nextLine();

        System.out.println("Nice to meet you, " + firstName);
        System.out.print("What's your last name, " + firstName + "? ");
        lastName = stdIn.nextLine();

        System.out.println("I want to know more about you " + firstName);
        System.out.print("How old are you? ");
        age = stdIn.nextInt();

        System.out.println("So, you are " + firstName + " " + lastName + ".");
        System.out.println("You are " + age + " years old.");
    }
}

Now you may try to make some programs on your own. Try to make a program that gets two numbers and shows their sum, difference, product, remainder (only for integers), etc.

Java Programming 3: Shorthand operators and String and Math classes

We introduced some operators before, now we will show their shorthand form. It may seem a bit harder in the beginning, but you will adapt them soon and then you will use them as often as you can.

If you have a variable named v and want to add its value by 9, you would use the expression v = v + 9; Just like that, you can use the shorthand operator +=. In this case, the expression would be v += 9;.

The table below shows all the shorthand operators and an example of their usage:

Operator Example Equivalent
+= v += 9 v = v + 9
-= v -= 9 v = v – 9
*= v *= 9 v = v * 9
/= v /= 9 v = v / 9
%= v %= 9 v = v % 9

This example shows how to use them in a program:

public class ShorthandOperators {

    public static void main(String[] args) {
        int value = 10;

        //show the initial value
        System.out.println("value=" + value);

        //add 12 to the value
        value += 12;
        System.out.println("value=" + value);

        //subtract 5 from the value
        value -= 5;
        System.out.println("value=" + value);

        //make value 10 times bigger
        value *= 10;
        System.out.println("value=" + value);

        //make value 17 times smaller
        value /= 17;
        System.out.println("value=" + value);
    }
}

There are also two operators you need to learn, the ++ operator and the -- operator. The first one is the increment operator; the second one is the decrement operator. The increment operator adds 1 to the value where it is used, while the decrement operator subtracts 1. They may be used as v++ and v--, or as ++v and --v. Where is the difference? This program shows it:

public class IncrementDifferences {
    public static void main(String[] args) {
        int a = 10, b;
        b = a++;
        System.out.println("a=" + a + " b=" + b);

        a = 10; //reset the value of a
        b = ++a;
        System.out.println("a=" + a + " b=" + b);
    }
}

The output is:

a=11 b=10
a=11 b=11

When we use b = a++; Java firstly makes b equal to a, and then adds 1 to the value of a. When we use b = ++a; Java firstly adds 1 to the value of a, and then makes b equal to a. This is not crucial information, but it may be useful. The same thing happens when we use the decrement operator, but in this time, it subtracts instead of adding.

Using the String and Math classes

Classes are building blocks of Java. One class we have been using since the beginning of Java programming is the String class. We have been passing String objects as arguments of the main function and the System.out.println() function. Now you will learn how to use String in our program. Strings are nothing more than arrays of characters; that is, words, sentences, text, etc. We learned that the + operator is used to concatenate strings. This program shows how to define and concatenate strings:

public class LearningStrings {

    public static void main(String[] args) {
        String s1 = "Java "; //defining a string
        String s2 = "Programming ";
        String s3 = "Language";

        String s4 = s1 + s2 + s3; //concatenate 3 strings into a fourth
        System.out.println(s4);

        s4 += " is awesome!"; //concatenate using shorthand
        System.out.println(s4);
    }
}

We've learned how to read strings from the user, using the next() and nextLine() functions of the Scanner class.

The Math class is a special kind of class. You cannot create objects of this class, but you can use its methods by calling them as Math.method(args...) and its constants as Math.CONSTANT. See the program below:

public class MathExample {

    public static void main(String[] args) {
        double sin90;
        sin90 = Math.sin(Math.PI / 2);
        System.out.println(sin90);
    }
}

In this program we use the Math.sin() method and the Math.PI constant defined in the Math class. Here is a list of some methods in the Math class:

Method What it does
Math.sin(arg) Returns the sine of arg (in radian)
Math.cos(arg) Returns the cosine of arg (in radian)
Math.tan(arg) Returns the tangent of arg (in radian)
Math.sqrt(arg) Returns the square root of arg
Math.pow(arg1, arg2) Returns arg1 in power of arg2
Math.random() Returns a random number between 0 and 1

The Math.random() is a method that returns a random number between 0 and 1, but with a little work we can obtain more values. Consider the following program:

public class RandomNumbers {

    public static void main(String[] args) {
        double rnd1 = Math.random();
        System.out.println("This is a random number between 0 and 1: " + rnd1);

        int rnd2 = (int) (Math.random() * 100);
        System.out.println("This is a random integer between 0 and 100:" + rnd2);

        int rnd3 = (int) (Math.random() * 100) + 20;

        System.out.println("This is a random integer between 20 and 120:" + rnd3);
    }
}

When I run this the first time, it creates this output:

This is a random number between 0 and 1: 0.2139571054316357
This is a random integer between 0 and 100: 56
This is a random integer between 20 and 120: 98

The second time it creates this output:

This is a random number between 0 and 1: 0.3273192730084672
This is a random integer between 0 and 100: 63
This is a random integer between 20 and 120: 24

As you can see, there is a different number generated every time we run the program. Let explain this line of code: int rnd2 = (int) (Math.random() * 100);

You can see there is a (int) added before the (Math.random() * 100). This is called a casting operator. The Math.random() method returns a double, not an int. By casting, we get the value of Math.random() * 100 and force it to be an integer value, which is assigned to the rnd2.

We will now make a simple power calculator using the Math.power() function. We will make a program that asks us for two numbers, and then adds them, subtracts them, multiplies them.

import java.util.Scanner;

public class SimpleMath {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int num1, num2;
        System.out.print("Enter two numbers divided by space: ");
        num1 = stdIn.nextInt();
        num2 = stdIn.nextInt();

        System.out.println(num1 + "+" + num2 + "=" + (num1 + num2) );
        System.out.println(num1 + "-" + num2 + "=" + (num1 - num2) );
        System.out.println(num1 + "*" + num2 + "=" + (num1 * num2) );
        System.out.println(num1 + "^" + num2 + "=" + Math.pow(num1, num2));
    }
}

One sample run is shown below:

Enter two numbers divided by space: 5 7
5+7=12
5-7=-2
5*7=35
5^7=78125.0

This other program is a simple lottery. We choose 5 numbers between 1 and 53, and another Magic number between 1 and 42. Now, this is a relatively long and repetitive code for this kind of task. Later, you will use loops, a control statement that makes you use the same part of the program as long as you want.

public class Lottery {
    public static void main(String[] args) {
        int number, magicNumber;

        //we choose the numbers
        number = (int) (Math.random() * 53) + 1; //1st
        System.out.print(number+" ");

        number = (int) (Math.random() * 53) + 1; //2nd
        System.out.print(number+" ");

        number = (int) (Math.random() * 53) + 1; //3rd
        System.out.print(number+" ");

        number = (int) (Math.random() * 53) + 1; //4th
        System.out.print(number+" ");

        number = (int) (Math.random() * 53) + 1; //5th
        System.out.print(number+" ");

        System.out.println(); //an empty line
        //we choose the Magic number
        magicNumber = (int) (Math.random() * 42) + 1;
        System.out.println("Magic number: " + magicNumber);
    }
}

One output is:

25 3 39 22 14
Magic number: 16

Another one is:

24 23 19 3 43
Magic number: 24

There are plenty of combinations and the Math.random() function doesn't return the same result twice.

Java Programming 4: The if, switch and ternary operator

When we introduced the Scanner class, we wrote this program:

import java.util.Scanner;

public class RightTriangleArea {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        double leg1, leg2;
        double area;

        System.out.print("Enter the length of leg1: ");
        leg1 = stdIn.nextDouble();

        System.out.print("Enter the length of leg2: ");
        leg2 = stdIn.nextDouble();

        area = (leg1 * leg2) / 2;
        System.out.println("The right triangle with legs " + leg1
                    + " and " + leg2 + " has an area equal to " + area);
    }
}

This program is correct, but what if we enter a negative value for a leg? We will get an error in the result. This is why we need to make the program check the input before we go on processing the input. We can check this input by using the if statement. The if statement makes the program "think" about the input. If the input is correct, the program skips the if, otherwise it does what we tell it to do. Consider this program, which is the same as RightTriangleArea, but includes the if statement:

import java.util.Scanner;

public class RightTriangleArea {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        double leg1, leg2;
        double area;

        System.out.print("Enter the length of leg1: ");
        leg1 = stdIn.nextDouble();
        if (leg1 < 0) {
            System.err.println("Error! Negative length");
            System.exit(1);
        }

        System.out.print("Enter the length of leg2: ");
        leg2 = stdIn.nextDouble();
        if (leg2 < 0) {
            System.err.println("Error! Negative length");
            System.exit(1);
        }

        area = (leg1 * leg2) / 2;
        System.out.println("The right triangle with legs " + leg1
                + " and " + leg2 + " has an area equal to " + area);
    }
}

We included two if blocks (remember that everything between { and } is a block) and another method of the System class, the System.exit() method. We need to use the blocks of code every time we need to execute more than one statement if a condition happens. The System.exit() method is used to make the program exit with an integer value. Usually, we use System.exit(0) if the exit is made in a proper way, while a number rather than 0 if the exit is made because of an error. You can also see that we didn't use System.out.println( ) in the if blocks. We used System.err.println() because we were printing errors. It is a good practice to use System.err.println() anytime you print errors in the screen, and System.out.println() in other cases.

Let's take a look at the if structure and how do we use it. Its general structure is

if (test) {
    statements;
}

The test is a boolean value, so it can take values true or false. You can see that in the above example we didn't use any of these keywords, but an expression with a comparison operator (leg1 < 0). This expression is turned into boolean by Java. The table below shows other comparison operators, their meaning and an example with the corresponding boolean value:

value = 4

Operator Name Example Boolean
< Smaller than value < 0 false
<= Smaller than or equal to value <= 4 true
> Greater than value > 3 true
>= Greater than or equal to value >= 1 true
== equal to value == 5 false
!= not equal to value != 4 false

Be careful to use == (two equal signs) instead of = (one equal sign) to compare values! The first one is a comparison operator; the second one is the assignment operator.

Now we shall use these comparison operators to create a solver for quadratic equations. A quadratic equation is an equation having the form Ax^2 + Bx + C = 0, where A, B and C are constants with A different than 0. If A = 0 the equation is called linear. Our program should get these constants from the user and find the value of x:

import java.util.Scanner;

public class EquationSolver {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        double A,B,C; //declare the constants
        double D; //discriminant
        double x1,x2; //values of x

        //read the input from the user
        System.out.print("A= ");
        A = stdIn.nextDouble();
        System.out.print("B= ");
        B = stdIn.nextDouble();
        System.out.print("C= ");
        C = stdIn.nextDouble();


        if (A == 0) { // linear equation
            x1 = -C / B;
            System.out.println("x = " + x1);
        }

        else { //quadratic
            D = (B * B) - 4 * A * C;

            if (D>0) { //two real solutions
                x1 = (-B + Math.sqrt(D) ) / (2 * A);
                x2 = (-B - Math.sqrt(D) ) / (2 * A);
                System.out.println("x1 = " + x1);
                System.out.println("x2 = " + x2);
            }
            else if (D == 0) { //one real solution
                x1= (-B) / (2 * A);
                System.out.println("x= " + x1);
            }
            else System.out.println("No real solution");
        }
    }
}

You may see some things you don't understand in this program. There is used the if-else statement. If we have more than one condition to check (like the discriminant value in our case), we use the if-else statement. Its form is:

if (case1) {
...
}
else if (case2) {
...
}
...
else if (caseN) {
...
}
else {
...
}

There is no limitation on how many else if cases you can use. Also you can see the nested ifs. The nested if is an if statement inside an if block, just like this:

if (case1) {
    if (case2) {
    ...
    }
}

Also there is no limitation on how many ifs you can nest.

There is a difference between these two programs below:

//Program_1
if (case1) {
    ...
}
else if (case2) {
    ...
}
...


//Program_2
if (case1) {
    ...
}
if (case2) {
    ...
}
...

The difference is that in the Program_1, only one of the blocks would be executed. If one condition is true, the corresponding block will be executed and the others would be skipped. In the Program_2 may be executed more than one block. This next program would show the difference in the output:

public class IfDifference {

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

        System.out.println("if-else");
        if (number > 2)
            System.out.println(number + ">2");
        //Java will skip these else-ifs
        else if (number > 3)
            System.out.println(number + ">3");
        else if (number > 4)
            System.out.println(number + ">4");

        System.out.println(); //empty line
        System.out.println(); //empty line

        System.out.println("if-if");
        if (number > 2)
            System.out.println(number + ">2");

        if (number > 3)
            System.out.println(number + ">3");

        if (number > 4)
            System.out.println(number + ">4");
    }
}

The output is:

if-else
4>2

if-if
4>2
4>3

Boolean values

We can also use boolean values instead of comparison expressions in the if statement. If the boolean value is true, the if block executes. If the boolean value is false, the if block doesn't execute. Consider the following program:

import java.util.Scanner;

public class UsingBooleans {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter an integer: ");
        int value = stdIn.nextInt();
        boolean b = (value > 100);
        if (b) System.out.println(value + " is greater than 100");
        else System.out.println(value + " is not greater than 100");
    }
}

We can also write this program like this:

import java.util.Scanner;

public class NotOperator {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter an integer: ");
        int value = stdIn.nextInt();

        boolean b = (value > 100);
        if (!b) System.out.println(value + " is not greater than 100");
        else System.out.println(value + " is greater than 100");
    }
}

The difference is that in the first program, we tested if the boolean b was true using if (b). In the second program, we tested if the boolean b was not true using if(!b), as the ! operator is the logical operator NOT. This table shows the logical operators:

Logical operator Operator’s meaning
&& AND
|| OR
! NOT

This is the truth table of these operators:

A B A && B A || B ! A
false false false false true
false true false true true
true false false true false
true true true true false

This following program is the lottery program we created before, but with a slight difference. Now we will get numbers from user and use the if statement to check if the numbers correspond to the lottery numbers.

import java.util.Scanner;
public class Lottery {
    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        //lottery numbers

        int n1, n2, n3, n4, n5, magicNumber;
        //we choose the numbers
        n1 = (int) (Math.random() * 53) + 1; //1st
        n2 = (int) (Math.random() * 53) + 1; //2st
        n3 = (int) (Math.random() * 53) + 1; //3st
        n4 = (int) (Math.random() * 53) + 1; //4st
        n5 = (int) (Math.random() * 53) + 1; //5st

        //we choose the Magic number
        magicNumber = (int) (Math.random() * 42) + 1;

        //our numbers
        int ourNum1, ourNum2, ourNum3, ourNum4, ourNum5, ourMagicNum;
        System.out.print("Enter your first 5 numbers: ");
        ourNum1 = stdIn.nextInt();
        ourNum2 = stdIn.nextInt();
        ourNum3 = stdIn.nextInt();
        ourNum4 = stdIn.nextInt();
        ourNum5 = stdIn.nextInt();
        System.out.print("Enter your magic number: ");
        ourMagicNum = stdIn.nextInt();

        if (n1 == ourNum1 && n2 == ourNum2
            && n3 == ourNum3 && n4 == ourNum4
            && n5 == ourNum5 && magicNumber==ourMagicNum) {
                System.out.println("YOU WON THE LOTTERY!");
            }

        else System.out.println("Sorry, better luck next time");
    }
}

There are some common mistakes that young programmers do when they use the if statement. These are some of them:

  • Forgetting to use brackets.

If there is more than one statement that is executed with the if, you must use a block of code. If you want to execute all three statements, this is wrong:

if (test)
    statement1;
    statement2;
    statement3;

While this is right:

if (test) {
    statement1;
    statement2;
    statement3;
}

In the first case, if test is not true, statement2 and statement3 will execute because they are not in the if block. Since there is no block of code, only statement1 is connected to the if. On the other hand, if test is not true in the second case, none of the statements in the block would execute.

  • Semicolon after the if.

There is no semicolon needed after the if. It isn't a compile-time error, nor a runtime error, so it is hard to find this kind of mistake if you do it.

if (test); {
    statement1;
    statement2;
    ...
}

This is the same as

if (test) { }
{
    statement1;
    statement2;
    ...
}

Adding a semicolon in this case is just like adding an empty block code: nothing will happen. This kind of error is a logic error; this is what programmers call bugs.

  • Using one equal sign to test equality.

In the EquationSolver.java we used this statement in order to check if the discriminant is 0:

if (D == 0) {
    ...
}

Using one equal sign instead of two would not check if D is equal to 0, but would assign 0 to D. This would generate a compile-time error. But if you make the same mistake with a boolean value, no error is generated, a bug is created. Consider this line of code in the UsingBooleans.java:

if (b) System.out.println(value+" is greater than 100");

If we make it:

if (b=true) System.out.println(value+" is greater than 100");

the program will always execute this line of code, even if b was false before this if. This is why we don't check booleans like this, but we type only if (b).

This program is a learning tool for younger kids who want to learn math:

import java.util.Scanner;

public class SimpleMath {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        //generate 2 random ints between 1 and 20
        int num1 = (int) (Math.random() * 19) + 1;
        int num2 = (int) (Math.random() * 19) + 1;

        int result = num1 + num2;
        System.out.print("What is " + num1 + " + " + num2 + "? ");
        int answer = stdIn.nextInt();
        if (answer == result) System.out.println("** Correct **");
        else System.out.println("Wrong! The answer is " + result);
    }
}

You can also change it to create multiplication and subtraction.

This other program checks if the input is odd or even:

import java.util.Scanner;

public class OddOrEven {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter an integer to check: ");

        int number = stdIn.nextInt();
        boolean isEven = (number % 2 == 0);

        if (isEven) System.out.println(number + " is even");
        else System.out.println(number + " is odd");
    }
}

In this line of code:

boolean isEven = (number % 2 == 0);

we check if the remainder of number divided by 2 is 0. If yes, the number is a multiple of 2, hence even.

Switch statements

Another way of controlling the program flow is the switch statement. Its meaning is the same as the if statement, but by using switch we can only check for equality. Consider the following program:

import java.util.Scanner;

public class SwitchCaseStatement {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter a number between 1 and 4: ");
        int num = stdIn.nextInt();

        switch (num) {
            case 1:
                System.out.println("You entered 1");
                break;

            case 2:
                System.out.println("You entered 2");
                break;

            case 3:
                System.out.println("You entered 3");
                break;

            case 4:
                System.out.println("You entered 4");
                break;

            default:
                System.out.println("Invalid input!");
        }
    }
}

Using the if statements, this program would be:

import java.util.Scanner;

public class EquivalentOfSwitchCase {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter a number between 1 and 4: ");
        int num = stdIn.nextInt();

        if (num == 1)
            System.out.println("You entered 1");

        else if (num == 2)
            System.out.println("You entered 2");

        else if (num == 3)
            System.out.println("You entered 3");

        else if (num == 4)
            System.out.println("You entered 4");

        else System.out.println("Invalid input!");
    }
}

This program has no practical use, it is only for demonstration. The syntax is like:

switch (variable) {
    case value1:
        statements;
        break;

    case value2:
        statements;
        break;
    ...

    case valueN:
        statements;
        break;

    //this is optional
    default:
        statements;
}

One common mistake with the switch-case statement is that most of beginners forget to add the break statement in the end of the case block. If you don't add the break, all of the statements in the next case block will be executed. If we delete the break keywords from SwitchCaseStatement.java, this would be the output for every integer input:

You entered 1
You entered 2
You entered 3
You entered 4
Invalid input!

The ternary operator

The ternary operator is the ?: operator. It is a special operator that shortens your code by using it instead of a simple if-else statement. Consider this program for finding the biggest number out of two:

import java.util.Scanner;

public class Ternary {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int num1, num2;

        System.out.print("num1=");
        num1 = stdIn.nextInt();

        System.out.print("num2=");
        num2 = stdIn.nextInt();

        int max = (num1 > num2) ? num1 : num2;
        System.out.print("maximum: " + max);
    }
}

Our interest is in this line of code, where you can see the ternary operator in action:

int max = (num1 > num2) ? num1 : num2;

The ternary operator syntax is:

(booleanExpression) ? valueIfTrue : valueIfFalse;

As you can figure out, the booleanExpression is evaluated first. If it is true, valueIfTrue is returned. Otherwise, valueIfFalse is returned. We may write the same expression like this:

if (num1 > num2)
    max = num1;

else max = num2;

You may use the ternary operator even as an argument of the System.out.println() function, like this:

import java.util.Scanner;

public class EvenTest {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter an integer: ");
        int num = stdIn.nextInt();

        System.out.println( (num % 2 == 0) ? num + " is even" : num + " is odd");
    }
}

Java Programming 5: Loops

Sometimes we need to do the same thing more than once. Our original Lottery program was one of these cases:

public class Lottery {

    public static void main(String[] args) {
        int number, magicNumber;

        //we choose the numbers
        number = (int) (Math.random() * 53)  +  1; //1st
        System.out.print(number  +  " ");
        number = (int) (Math.random() * 53)  +  1; //2st
        System.out.print(number  +  " ");
        number = (int) (Math.random() * 53)  +  1; //3st
        System.out.print(number + " ");
        number = (int) (Math.random() * 53) + 1; //4st
        System.out.print(number + " ");
        number = (int) (Math.random() * 53) + 1; //5st
        System.out.print(number + " ");

        System.out.println(); //an empty line
        //we choose the Magic number
        magicNumber = (int) (Math.random() * 42) + 1;

        System.out.println("Magic number: " + magicNumber);
    }
}

As you can see, there are two lines of code repeated 5 times. What if we needed to generate 20 numbers? Or 100 numbers? Copying and pasting those lines 100 times would be a really bad programming technique. Instead, we can use loops, which repeat a block of statements as many times we want.

Java has 3 kind of loops, named the while loop, the for loop and the do-while loop. Once you learn the logic of a loop, then you can learn any other loop, the difference is only in the syntax. Consider this modification of the above program:

public class Lottery {

    public static void main(String[] args) {
        int number, magicNumber;
        int i=0; //a variable to control the loop

        //we choose the numbers using a while loop
        while (i < 5) {
            number = (int) (Math.random() * 53) + 1;
            System.out.print(number + " ");
            i++;
        }

        System.out.println(); //an empty line

        //we choose the Magic number
        magicNumber = (int) (Math.random() * 42) + 1;
        System.out.println("Magic number: " + magicNumber);
    }
}

This program does exactly the same thing as before, but it's shorter and practical. Now let's explain this program. We firstly declare a variable named i in order to control the loop. This variable is what makes the loop continue as much as we want. Then we use the while loop:

while (boolean expression or value) {
    statements;
    statements to control the loop;
}

This while loop will go on as long as i is smaller than 5 (as long as i < 5 is true). We add in the while block the two statements we want to execute 5 times, and in the end we add the statement(s) which will be used to control the loop. In this case, we just increase the variable i by one using i++, in order to say that the loop is done once. This loop will go on for as long as the boolean expression i < 5 is true, which means that if i is one of the values {0, 1, 2, 3, 4}. So, firstly the boolean expression is checked. If true, the statements in the loop block will execute, then the boolean expression is checked again. If still true, the statements execute again; if false, the loop is skipped and the rest of the program is executed.

Whenever you use the while loop just like we did, don't forget to define the value of the variable. Also, don't forget to add the statements to control the loop in the end of the loop block. If you just declare the variable (int i;) and don't assign it a value later (i=0;) and you use it to control the loop, you will get this compile-time error:

error: variable i might not have been initialized

If you define it as it is needed, but forget to add the i++ in the end of the loop, the loop will go on infinitely, because the value of i is still 0, and 0<5 returns true. This won't generate compile-time errors. This is a typical bug made by novice programmers. Try to compile this program:

public class Lottery {

    public static void main(String[] args) {
        int number, magicNumber;
        int i = 0;

        //we choose the numbers using a while loop
        while (i<5) {
            number = (int) (Math.random() * 53) + 1;
            System.out.print(number + " ");
        }

        System.out.println(); //an empty line
        //we choose the Magic number
        magicNumber = (int) (Math.random() * 42) + 1;
        System.out.println("Magic number: " + magicNumber);
    }
}

You won't get any errors, but if you try to run it, this program will print random numbers infinitely in your terminal, because you just forgot to add the loop-control statements (in this case is i++).

This program is a guessing game, where the computer will "think" of a number and the user will find it.

import java.util.Scanner;

public class GuessingGame {

    public static void main(String[] args) {
        Scanner stdIn=new Scanner(System.in);
        int number = (int) (Math.random() * 100);
        int guess = -1;

        System.out.println("I'm thinking a number. Can you guess it?");
        while (guess != number) {
            System.out.print("Your guess: ");
            guess = stdIn.nextInt();
            if (guess == number)
                System.out.println("**CORRECT**");

            else if (guess < number)
                System.out.println("Your guess is too small");

            else System.out.println("Your guess is too big");
        }
    }
}

We initialize the guess as -1 and we know that the number generated won't be equal to it, so the loop can run at least once. If we guess the number, the expression guess != number will return false, so the loop will end. We can also modify it, so the program counts the number of guesses:

import java.util.Scanner;

public class GuessingGame {

    public static void main(String[] args) {
        Scanner stdIn=new Scanner(System.in);
        int number = (int) (Math.random() * 100);
        int guess = -1;
        int count = 1;

        System.out.println("I'm thinking a number. Can you guess it?");

        while (guess != number) {
            System.out.print("Your guess: ");
            guess = stdIn.nextInt();
            if (guess == number)
                System.out.println("**CORRECT**");

            else if (guess < number) {
                System.out.println("Your guess is too small");
                count++;
            }

            else {
                System.out.println("Your guess is too big");
                count++;
            }
        }
        System.out.println("You found it in " + count + " tries");
    }
}

We are now able to create a math learning tool:

import java.util.Scanner;

public class LearningMath {

    public static void main(String[] args) {
        final int QUESTIONS = 10;
        int correctAnswers = 0, i = 0;
        int max;
        Scanner stdIn = new Scanner(System.in);

        System.out.print("Choose the level (1,2,3): ");
        int level = stdIn.nextInt();

        //level selection
        if (level == 1) {
            System.out.println("Level: Beginner");
            max = 10;
        }

        else if (level == 2) {
            System.out.println("Level: Intermediate");
            max = 25;
        }

        else {
            System.out.println("Level: Advanced");
            max=100;
        }

        while (i < QUESTIONS) {
            //generate 2 numbers and add them
            int num1 = (int) (Math.random() * max);
            int num2 = (int) (Math.random() * max);
            int result = num1 + num2;

            System.out.print(num1 + " + " + num2 + "=");
            int answer = stdIn.nextInt();

            //answer is correct
            if (answer == result) {
                System.out.println("Correct!");
                correctAnswers++;
            }

            //answer is wrong
            else System.out.println("Wrong! Answer is " + result);
            i++;
        }

        //show the grade
        System.out.print("You solved " + correctAnswers + " out of " + QUESTIONS);
    }
}

We used here the final keyword, which creates a constant. This means that you can assign a value to QUESTIONS, but you can't change its value. In order to change the number of questions, we should change the value of QUESTIONS in the code, and then recompile it.

The do-while loop

The do-while is a variation of the while loop. Its syntax is:

do {
    statements;
} while (boolean expression);

The difference from the while loop is that in the do-while, the boolean expression is checked in the end, not in the beginning. This means that the do-while loop will run at least one, even though the boolean expression might be false. Using the do-while loop we can change the GuessingGame program so we don't have to define the guess variable as -1:

import java.util.Scanner;

public class GuessingGame {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int number = (int) (Math.random() * 100);
        int guess, count=1;

        System.out.println("I'm thinking a number. Can you guess it?");

        do {
            System.out.print("Your guess: ");
            guess = stdIn.nextInt();

            if (guess == number)
                System.out.println("**CORRECT**");

            else if (guess<number) {
                System.out.println("Your guess is too small");
                count++;
            }

            else {
                System.out.println("Your guess is too big");
                count++;
            }
        } while (guess != number);

        System.out.println("You found it in " + count + " tries");
    }
}

This program does exactly the same thing as the one we had before, but now we don't have to assign a pointless value to the variable guess, because we know that the statements in the loop will run at least one time.

The for loop

The while and the do-while loops are error-prone. You may sometimes forget to initialize the variable that controls the loop, or even forget to increment it in the end of the loop. This is where the for loop comes into action. These pieces of code show the same thing, using different kinds of loops:

// Program_1:
int i=0;
while (i<5) {
    statements;
    i++;
}

// Program_2:
for (int i=0; i<5; i++) {
    statements;
}

What you may forget to write when using the while loop, are mandatory to the for loop. The syntax of the for loop is:

for (initial case; boolean expression; action after each iteration) {
    statements;
}

When the program enters the loop, the initial case is set. Then the statements of the block are executed, and then the action after each iteration takes place. Then the boolean expression is checked. If it is still true, statements are re-executed, and the action takes place again, and so it goes on.

We now rewrite the Lottery program using the for loop:

public class Lottery {
    public static void main(String[] args) {
        int number, magicNumber;

        //we choose the numbers using a while loop
        for (int i=0; i<5; i++) {
            number = (int) (Math.random() * 53) + 1;
            System.out.print(number + " ");
        }

        System.out.println(); //an empty line
        //we choose the Magic number

        magicNumber = (int) (Math.random() * 42) + 1;
        System.out.println("Magic number: " + magicNumber);
    }
}

The for loop may be used in different ways:

  • The full form:
for (initialization; expression; increment) {
    // code goes here
}
  • Two (or more) initializations:
for (initialization1, initialization2; expression; increment1, increment2) {
    // code goes here
}

We divide initializations by comma.

  • Forward initialization;
initialization;

for (;expression; increment) {
    // code goes here
}
  • Increment inside the loop:
for (initialization; expression; ) {
    // code goes here
    increment;
}
  • Empty:
for (; ; ) {
    // code goes here
}

This will run infinitely, just like:

while (true) {
    //code goes here
}

You are free to choose any loop you want to, and also you can nest them (a loop inside a loop).

break and continue

You must remember that we used the keyword break with the switch-case statements. There is also another use of this keyword: to end a loop. Take a look at this version of GuessingGame:

import java.util.Scanner;

public class GuessingGame {

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        int number = (int) (Math.random() * 100);
        int guess, count = 1;
        System.out.println("I'm thinking a number. Can you guess it?");

        while (true) {
            System.out.print("Your guess: ");
            guess = stdIn.nextInt();

            if (guess == number) {
                System.out.println("**CORRECT**");
                break;
            }

            else if (guess < number) {
                System.out.println("Your guess is too small");
                count++;
            }

            else {
                System.out.println("Your guess is too big");
                count++;
            }
        }
        System.out.println("You found it in " + count + " tries");
    }
}

You can see that we created an infinite loop and when guess is equal to the number generated by the program, the break keyword is used. When this keyword is reached, the loop ends, it is broken.

Another keyword similar to the break, is the keyword continue. The keyword break ends the loop, while the keyword continue ends only the current iteration. This program prints numbers from 1 to 20, except the multiples of 5:

public class UsingContinue {

    public static void main(String[] args) {
        int i = 0;
        while (i <= 20) {
            if (i%5 == 0) {
                i++;
                continue;
            }

            System.out.print(i + " ");
            i++;
        }
    }
}

This task is a simulation program. Imagine if we had a square divided in numbered parts just like in the picture. We throw a dart in the picture. What is the probability for the dart to hit an odd-numbered area? (Hint: you can use a Monte Carlo Simulation)

Monte Carlo

Java Programming 6: Methods

We stated before that math is easy for programmers, or so it must be. Now we are going to make a program that calculates the factorial of an integer (the factorial of a number is the product of every integer from 1 to that number):

public class Factorial {

    public static void main(String[] args) {
        int fact = 1;
        for (int i=1; i<=5; i++) fact *= i;
        System.out.println("5!=" + fact);
    }
}

What if we need to do it for more than one number? This is the same program but also calculates the factorial of 9 and 13:

public class Factorial {

    public static void main(String[] args) {
        int fact = 1;
        for (int i=1; i<=5; i++) fact *= i;
        System.out.println("5!=" + fact);

        //reset for 9!
        fact = 1;
        for (int i=1; i<=9; i++) fact *= i;
        System.out.println("9!=" + fact);

        //reset for 13!
        fact = 1;
        for (int i=1; i<=13; i++) fact *= i;
        System.out.println("13!=" + fact);
    }
}

We are using the same block of code, but this time we can't use a loop to repeat the same instructions. This is where methods (or functions, as they are called by C/C++ programmers) come into play. Methods create reusable blocks of code. In this case, we can create a method that returns the value of the factorial. This other program will show how to create functions:

public class FactorialMethod {

    public static int factorial(int n) {
        if (n<2) return 1;

        int fact=1;
        for (int i=1; i<=n; i++) fact *= i;
        return fact;
    }

    public static void main(String[] args) {
        System.out.println("5!=" + factorial(5));
        System.out.println("9!=" + factorial(9));
        System.out.println("13!=" + factorial(13));
    }
}

As you can see, we didn't paste the same block of code, but we created a method to return the factorial, and just called that method. We've been calling some methods so far, like System.out.print(), Math.random(), etc.

Let's now analyze the method. In the first line, we write

public static int factorial(int n)

This tells us that the method called factorial returns an integer (that is, we can assign its value to an int variable) and also has an integer argument (what we pass to the function). The public keyword is related to OOP principles which will be explained later. The static keyword allows us to call the method without having to create instances of the class (objects). You will understand these keywords better when we use classes and non-static methods.

After this, we start writing the code for the method, and we use the keyword return two times. The first time, the function returns 1, and the other time, the function returns a variable. If n is smaller than 2, we give the value 1 to the method, otherwise we calculate the product of every integer from 1 to n, and return this product. When the keyword return is reached, the method exits, so any other statement won't execute. In our case, if n = 0 or n = 1, the loop won't execute because the method ends with the return. In general, the syntax of the function is

modifier returnValueType methodName (parameter-list) {
    statements;
}

In our case, the modifier is public static, return type is int, method name is factorial and the parameter list (the only parameter) is int n.

This other method has a longer parameter list (or argument list):

public static int max(int a, int b) {
    if (a > b) return a;
    else return b;
}

We must use public static int max(int a, int b) instead of public static int max(int a, b), even though the type of a and b is the same. Using the ternary operator ?: we can rewrite the above method as:

public static int max(int a,int b) {
    return (a > b) ? a : b;
}

Now we will use this method to create a simple program:

import java.util.Scanner;

public class Maximum {

    public static int max(int a, int b) {
        return (a>b) ? a : b;
    }

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("Enter an integer: ");
        int n1 = stdIn.nextInt();

        System.out.print("Enter another integer: ");
        int n2 = stdIn.nextInt();

        int maximum = max(n1, n2);
        System.out.println("The maximum is " + maximum);
    }
}

When we call the function, the value of n1 is passed in the method as a, and the value of n2 is passed as b. The method creates a copy of each variable n1 and n2, and processes their copies, not the real variables. To witness this, consider the following program:

public class SwapValues {

    public static void swap(int a,int b) {
        int temp = a;
        a = b;
        b = temp;
        System.out.println("Values are: " + a + " " + b);
    }

    public static void main(String[] args) {
        int n1 = 10, n2 = 20;
        System.out.println("Before swap: " + n1 + " " + n2);
        System.out.print("Swap! ");
        swap(n1, n2);
        System.out.println("After swap: " + n1 + " " + n2);
    }
}

As you can see, values are not changed outside the method, since the method works with copies of variables and not with variables themselves.

We can create methods that don't return a value. These kinds of methods are called void methods (or procedures, as called by C/C++ programmers). The first void method we've used is the main method. As you can see, it has the modifier public static, a void return type, a name (main), a parameter String[] args (an array of Strings) and a method body. This other program creates a void method:

import java.util.Scanner;

public class Grader {

    public static void getGrade(double score) {
        char grade;

        if (score >= 90.0) grade = 'A';
        else if (score >= 80.0) grade = 'B';
        else if (score >= 70.0) grade = 'C';
        else if (score >= 60.0) grade = 'D';
        else grade = 'F';

        System.out.println("Your grade is " + grade);
    }

    public static void main(String[] args) {
        Scanner stdIn = new Scanner(System.in);
        System.out.print("How many points did you score? ");
        double grade = stdIn.nextDouble();
        getGrade(grade);
    }
}

Whether we write the main, then the function, or the method then the main, it makes no difference. The above program would work even if it was:

import java.util.Scanner;

public class Grader {

    public static void main(String[] args) {
        //...
    }

    public static void getGrade(double score) {
        //...
    }
}

There is no return statement needed in void methods, but one can add it to terminate the method. Since the maximum of points is 100, the method getGrade() should terminate and print an error if we pass a value greater than 100 (or smaller than 0). To handle this error, we rewrite the method in this way:

public static void getGrade(double score) {
    if (score > 100 && score < 0) {
        System.err.println("Invalid score: " + score);
        return;
    }

    char grade;
    if (score >= 90.0) grade = 'A';
    else if (score >= 80.0) grade = 'B';
    else if (score >= 70.0) grade = 'C';
    else if (score >= 60.0) grade = 'D';
    else grade = 'F';

    System.out.println("Your grade is " + grade);
}

If the method reaches return; it will exit the method.

Method overloading

We created before a method that returns the maximum of two ints. But since it accepts only integer arguments, we can't use it to find the maximum of two doubles. So we need to create another function, named with the same name but with different return type and parameter types:

public static double max(double a, double b) {
    return (a>b) ? a : b;
}

We can also use the same name (max) for another method that finds the maximum of three numbers, just like this:

public class MaxOverloaded {

    public static int max(int a, int b) {
        return (a > b) ? a : b;
    }

    public static double max(double a, double b) {
        return (a > b) ? a : b;
    }

    public static double max(double a,double b, double c) {
        double maxOfTwo=(a > b) ? a : b;
        return (maxOfTwo > c) ? maxOfTwo : c;
    }

    public static void main(String[] args) {
        System.out.println("max(2, 4) = " + max(2, 4));
        System.out.println("max(3.5, 3.4) = " + max(3.5, 3.4));
        System.out.println("max(1.2, 1.5, 2.0) = " + max(1.2, 1.5, 2.0));
    }
}

The Java compiler decides which one of the methods to use in any case. This is what is called method overloading. Method overloading allows us to create methods with the same name that differ in the parameter list. You can't create overloaded methods with the same parameter list. If you make this:

public static double max(int a,double b) {
    //...
}

public static double max(double a,int b) {
    //...
}

the compiler won't know which one of the functions to use, resulting in a compile-time error.

As you can see, we are using the same names for variables: a and b in the integer max, a and b in the double max. Even though we use the same name for two variables, they don't generate a compile-time error. How? It is all related to the variable's scope. The scope of a variable is the "area" of code where we can reference the variable. Variables like a and b in this case are called local variables, since they can be referenced only in the method. The scope of a variable is a block of code. If we declare the variable in a method, we can only reference it in that method. If we declare it in the class, it can be referenced through the class. If we declare it in a loop, it can only be referenced in the loop. Take this for example:

for (int i=0; i<20; i++) {
    //...
} //end of scope for i

//i doesn’t exist here

someMethod(i); //this creates error

We can create another loop after that using i:

for (int i=0;i<10;i++)

Since these variables, both named i, are not in the same scope, they cannot create compile-time errors. The Java Garbage Collector takes care to destroy variables when they are no longer used, e.g. out of their scope. This means that in the end of the for loop, the variable named i will no longer exist. But, if you decide to make this:

int i=1;
//some code here...
for (int i=0; i<20; i++) { //error!
    //...
}

you will definitely get a compile-time error. The second i is in the scope of the first i, and this causes the error.

Recursion

We introduced the factorial function before. We can also use another way of calculating the factorial, the recursive way:

public static int factorial(int n) {
    return (n < 2) ? 1 : n * factorial(n-1);
}

This recursive way is very used in programming, and it is a powerful programming technique. As you can see, we call the factorial method inside the factorial method. This method works exactly the same as the one we had before.

In mathematics, you may have seen plenty of recursive series. One of them is the Fibonacci series. We are now going to write a Java program to print some Fibonacci numbers:

public class FibonacciNumbers {

    public static int F(int n) {
        if (n == 1) return 0;
        else if (n == 2) return 1;
        else return F(n-1)+F(n-2);
    }

    public static void main(String[] args) {
        for (int i=1; i<20; i++)
        System.out.print(F(i) + " ");
    }
}

If you are wondering which one to use, recursion or iteration, then you should chose whatever you think is more intuitive. Recursion may take too much time and too much memory, but it may solve problems that are relatively hard using iteration. If you are concerned about performance, try to avoid recursion. You can read more about recursion here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment