Introduction to Java¶
Part 2 · Programming languages · Chapter 8 · Lecture notes, volume 2 (PDF) · Exercises: Introduction to Java
Introduction¶
In the chapters «Introduction to C++» and «Introduction to Python» we translated the pseudo-code of our algorithms into a compiled and into an interpreted programming language. In this chapter we introduce a third programming language, Java, which is in between: its programs are compiled into an intermediate code, which is then executed by a virtual machine. Its syntax is very close to the syntax of C++, but every program is organized into classes.
The chapter follows the same path as the two previous chapters, so that the three languages can be compared section by section:
-
the main characteristics of the language and the structure of a program;
-
variables, data types, input and output;
-
operators, conditional statements and loops;
-
arrays, and the dynamic lists of the class
ArrayList; -
methods (the
Javaname for functions), their parameters and their return values; -
a complete algorithm, the search of the maximum value in an array, written in pseudo-code and in
Java; -
the bitwise operators and a summary table that compares
JavawithC++andPython.
Every fragment of code of the chapter has been compiled with the javac compiler and executed with the java virtual machine (OpenJDK 25): the outputs reported in the examples are the ones printed by the programs.
In pseudo-code the entries of an array \(a[1..n]\) are indexed from \(1\) to \(n\); in Java, as in C++ and Python, the elements of an array of size \(n\) are indexed from \(0\) to \(n-1\). The entry \(a[i]\) of the pseudo-code corresponds to the element a[i-1] of the Java code.
8.1 Main characteristics of the programming language¶
The main characteristics of Java are the following.
-
Javais a compiled and interpreted language: the source code (.javafiles) is first compiled into bytecode (.classfiles) by theJavacompilerjavac, and then the bytecode is executed by the Java Virtual Machine (JVM). This makesJavaprograms platform-independent: the same bytecode runs on any machine that has a JVM installed (“write once, run anywhere”). -
Javais a strongly and statically typed language: every variable must be declared with its data type before use, and its data type cannot change during the execution. -
Javais object-oriented: every program is organized into classes. The entry point of everyJavaprogram is themainmethod of a class. -
Javasupports methods (theJavaterm for functions), enabling a modular and reusable approach to programming. -
As in
C++, the block structure of the code is defined by curly braces{}, and each instruction must end with the reserved symbol “;”. -
As in
C++, a single-line comment starts with the reserved symbol “//”, and multi-line comments are enclosed between the reserved symbols “/*” and “*/”.
Example 8.1: comments in Java
This is an example of a single-line comment:
This is an example of a multi-line comment:
8.1.1 The structure of a program¶
Before describing the single instructions, we look at the skeleton that every program shares. A Java program is made of one or more classes; the execution starts from the method public static void main(String[] args) of the class that is launched.
Example 8.2: the skeleton of a program
public class HelloWorld {
public static void main(String[] args) {
// The instructions of the program are written here
System.out.println("Hello, world!");
}
}
A class declared public must be saved in a file with the same name as the class: here HelloWorld.java. The program is compiled and executed with the commands
The first command produces the bytecode file HelloWorld.class; the second one executes it (note that the extension is not written). The output is
In the following examples we write only the instructions that matter: unless they contain a complete program, the fragments of code are meant to be placed inside the curly braces of main.
Every Java instruction belongs to a method, and every method belongs to a class. Each instruction ends with “;”.
8.2 Variables and data types¶
The source code operates on variables, and every variable has a data type.
-
The four fundamental data types of
Javaare:-
The data type “
int” represents an integer stored with \(32\) bits: a whole number from \(-2^{31} = -2147483648\) to \(2^{31}-1 = 2147483647\). For larger integers the data typelong(\(64\) bits) is used. -
The data type “
boolean” represents a Boolean value:trueorfalse(lowercase). -
The data type “
double” represents a floating-point number with double precision (\(64\) bits), as inC++. The data typefloathas single precision, and its values are written with the suffixf(e.g.,3.14f). -
The data type “
char” represents a single character, enclosed in single quotes (e.g.,'A','7').
-
-
The data type “
String” (with capitalS) represents a sequence of characters enclosed in double quotes, and it is the standard way to handle text inJava. -
A variable acts as a container that stores a value of a specific data type for later use.
-
Variables are assigned values using the assignment operator “
=”. When a new value is assigned, the previous value is overwritten. -
The compiler checks the data types: assigning a value of a wrong type (for example the string
"five"to a variable of typeint) or using a variable that has not received a value is a compilation error, and the program is not produced.
Variables must be declared with their data type before use, as in C++.
Example 8.3: variable declarations and assignments
int age = 25; // Integer variable
boolean isRaining = false; // Boolean variable
double pi = 3.14159; // Double-precision floating-point
float small = 3.14f; // Single-precision floating-point
double large = 123456.789; // Double-precision floating-point
char letter = 'A'; // Character variable
String name = "Alice"; // String variable
age = 26; // The previous value 25 is overwritten
System.out.println(age + " " + isRaining + " " + pi + " " + small);
System.out.println(large + " " + letter + " " + name);
Output:
Unlike C++, the Boolean value is displayed as false and the number 123456.789 is displayed with all its digits.
Example 8.4: the limits of the data type int
int big = Integer.MAX_VALUE; // The largest int
System.out.println(big);
System.out.println(big + 1); // Overflow: the result does not fit in 32 bits
long bigger = (long) big + 1; // Computed with 64 bits
System.out.println(bigger);
Output:
When the result of an operation between int values does not fit in \(32\) bits, it “wraps around” to the other end of the interval, without any error message. The integers of Python never overflow.
8.3 Input and output¶
-
The object
System.out(the standard output, provided by the classSystem) has the methods that display values on the screen. The most common are:-
System.out.println(): prints a value followed by a new line; -
System.out.print(): prints a value without the new line.
-
-
Values and strings are concatenated with the
+operator inside a print statement: when one of the two operands of+is aString, the other one is converted into text. The expression is evaluated from left to right, so an arithmetic operation inside a concatenation must be enclosed in parentheses. -
The method
System.out.printf()prints a formatted text: in the first string,%dis replaced by an integer,%sby a string,%.kfby a floating-point number with exactly \(k\) digits after the decimal point, and%nby a new line.
Example 8.5: screen output
int n = 42;
System.out.println("The value of the variable is " + n);
System.out.println("n = " + n + ", doubled = " + (n * 2));
System.out.println("n + 1 = " + n + 1); // Concatenation: "42" then "1"
System.out.println("n + 1 = " + (n + 1)); // Addition, then concatenation
System.out.print("No new line ");
System.out.println("after print");
System.out.printf("%d divided by %d is %.2f%n", 10, 3, 10.0 / 3);
Output:
-
The decimal separator printed by
printfdepends on the language settings of the computer: on a computer set to Italian the last line is10 divided by 3 is 3,33, with a comma. The methodprintlnalways uses the point. -
To read input from the keyboard, the class
Scannerof the packagejava.utilis used. It must be imported with the instructionimport java.util.Scanner;, written at the beginning of the file, before the class. The methodsnextLine(),nextInt()andnextDouble()read a line of text, an integer and a floating-point number.
Example 8.6: keyboard input with Scanner
import java.util.Scanner;
public class InputExample {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = sc.nextLine(); // Reads a String
System.out.print("Enter an integer: ");
int n = sc.nextInt(); // Reads an int
System.out.print("Enter a real number: ");
double x = sc.nextDouble(); // Reads a double
System.out.println("Hello " + name + ", n = " + n + ", x = " + x);
sc.close();
}
}
Example of execution (the user types Ada, 7 and 2.5):
Like printf, the method nextDouble() follows the language settings: on a computer set to Italian the real number must be typed as 2,5.
8.4 Operators¶
Operators are symbols that perform operations on variables and values. The operators of Java are the same as those of C++: arithmetic, assignment, increment and decrement, relational and logical operators.
8.4.1 Arithmetic operators¶
Arithmetic operators, used to perform basic mathematical operations:
-
+(Addition) \(\rightsquigarrow\) Adds two values. -
-(Subtraction) \(\rightsquigarrow\) Subtracts one value from another. -
*(Multiplication) \(\rightsquigarrow\) Multiplies two values. -
/(Division) \(\rightsquigarrow\) Divides one value by another. Integer division when both operands are integers. -
%(Modulus) \(\rightsquigarrow\) Returns the remainder of a division.
Example 8.7: arithmetic operators
int a = 10, b = 3;
System.out.println("Addition: " + (a + b));
System.out.println("Subtraction: " + (a - b));
System.out.println("Multiplication: " + (a * b));
System.out.println("Division: " + (a / b)); // Integer division
System.out.println("Modulus: " + (a % b)); // Remainder of division
System.out.println("Real division: " + ((double) a / b));
Output:
-
As in
C++, the division operator/performs integer division when both operands are integers, and the quotient is truncated toward zero:10 / 3is3and-7 / 2is-3(with remainder-7 % 2equal to-1). To obtain a floating-point result, at least one operand must be of typedouble, for example with the type conversion (cast)(double) a / b. -
The conversion
(int)removes the decimal part of adouble:(int) 3.9is3. There is no operator for the power: the methodMath.pow(x, y)returns \(x^y\) as adouble.
Example 8.8: integer and floating-point division
int a = 10, b = 3;
System.out.println(a / b); // Integer division
System.out.println(10.0 / 3); // Floating-point division
System.out.println((double) a / b); // Conversion of a to double
System.out.printf("%.2f%n", (double) a / b); // Two decimals
System.out.println(-7 / 2 + " " + -7 % 2); // Truncation toward zero
System.out.println((int) 3.9 + " " + Math.pow(2, 10));
Output:
8.4.2 Assignment operators¶
Assignment operators, used to assign values to variables:
-
=(Assignment) \(\rightsquigarrow\) Assigns a value to a variable. -
+=(Addition assignment) \(\rightsquigarrow\) Adds a value and assigns the result. -
-=(Subtraction assignment) \(\rightsquigarrow\) Subtracts a value and assigns the result. -
*=(Multiplication assignment) \(\rightsquigarrow\) Multiplies and assigns the result. -
/=(Division assignment) \(\rightsquigarrow\) Divides and assigns the result. -
%=(Modulus assignment) \(\rightsquigarrow\) Applies the modulus and assigns the result.
Example 8.9: assignment operators
int x = 10; // Assignment
System.out.println("Initial value: " + x);
x += 5; System.out.println("After += 5: " + x); // x = x + 5
x -= 3; System.out.println("After -= 3: " + x); // x = x - 3
x *= 2; System.out.println("After *= 2: " + x); // x = x * 2
x /= 4; System.out.println("After /= 4: " + x); // x = x / 4
x %= 4; System.out.println("After %= 4: " + x); // x = x % 4
Output:
Two instructions can be written on the same line, since each of them ends with “;”.
8.4.3 Increment and decrement operators¶
Increment and decrement operators:
-
++(Increment) \(\rightsquigarrow\) Increases the value of a variable by 1. -
- -(Decrement) \(\rightsquigarrow\) Decreases the value of a variable by 1.
- As in
C++, the pre-increment (++x) increments the value before returning it, and the post-increment (x++) returns the value first, then increments it. The same logic applies to the decrement operator (- -xandx- -).
Example 8.10: increment and decrement operators
int x = 5;
System.out.println("Initial value: " + x);
System.out.println("Pre-increment (++x): " + ++x);
System.out.println("Post-increment (x++): " + x++);
System.out.println("Value after post-increment: " + x);
System.out.println("Pre-decrement (--x): " + --x);
System.out.println("Post-decrement (x--): " + x--);
System.out.println("Value after post-decrement: " + x);
Output:
8.4.4 Relational operators¶
Relational operators, used to compare values and return a boolean result:
-
==(Equal to) \(\rightsquigarrow\) Checks if two values are equal. -
!=(Not equal to) \(\rightsquigarrow\) Checks if two values are different. -
<(Less than) \(\rightsquigarrow\) Checks if one value is smaller than another. -
>(Greater than) \(\rightsquigarrow\) Checks if one value is larger than another. -
<=(Less than or equal to) \(\rightsquigarrow\) Checks if one value is smaller than or equal to another. -
>=(Greater than or equal to) \(\rightsquigarrow\) Checks if one value is larger than or equal to another.
-
Relational operators return a value of type
boolean, displayed astrueorfalse(not as1and0as inC++). These operators are commonly used in conditional statements and loops. -
The operator
==compares the values of the primitive data types (int,double,char,boolean); twoStringvalues are compared with the methodequals, for examplename.equals("Alice").
Example 8.11: relational operators
int a = 10, b = 5;
System.out.println("a == b: " + (a == b)); // Equal to
System.out.println("a != b: " + (a != b)); // Not equal to
System.out.println("a < b: " + (a < b)); // Less than
System.out.println("a > b: " + (a > b)); // Greater than
System.out.println("a <= b: " + (a <= b)); // Less than or equal to
System.out.println("a >= b: " + (a >= b)); // Greater than or equal to
Output:
8.4.5 Logical operators¶
Logical operators, used for logical operations, often in conditional statements:
-
&&(Logical AND) \(\rightsquigarrow\) Returnstrueif both conditions aretrue. -
||(Logical OR) \(\rightsquigarrow\) Returnstrueif at least one condition istrue. -
!(Logical NOT) \(\rightsquigarrow\) Reverses the Boolean value.
Example 8.12: logical operators
boolean c1 = true, c2 = false;
System.out.println("c1: " + c1);
System.out.println("c2: " + c2);
System.out.println("c1 && c2: " + (c1 && c2)); // True only if both are true
System.out.println("c1 || c2: " + (c1 || c2)); // True if at least one is true
System.out.println("!c1: " + (!c1)); // Reverses the value
System.out.println("!c2: " + (!c2));
Output:
8.5 Conditional statements¶
The relational and logical operators produce the conditions that decide which instructions are executed.
-
The
ifstatement evaluates a condition inside parentheses(). If the condition istrue, the block inside the curly braces{}is executed. The optionalelse ifclause checks additional conditions, and the optionalelseclause handles all the remaining cases. -
Unlike
C++, the condition must be of typeboolean: an integer is not accepted as a condition, soif (n % 2)is a compilation error and the test must be writtenif (n % 2 != 0).
Example 8.13: conditional statement
int number = 10;
// Check if number is positive
if (number > 0) {
System.out.println("The number is positive.");
} else {
System.out.println("The number is non-positive.");
}
Output:
Example 8.14: if / else if / else
int score = 85;
String grade;
if (score >= 90) { grade = "A"; }
else if (score >= 80) { grade = "B"; }
else if (score >= 70) { grade = "C"; }
else if (score >= 60) { grade = "D"; }
else { grade = "F"; }
System.out.println("Score: " + score + ", Grade: " + grade);
Output:
The conditions are evaluated from top to bottom, and only the block of the first true condition is executed. The variable grade is declared without a value: the compiler accepts it because every branch assigns a value to it before it is printed.
8.5.1 Ternary operator (conditional operator)¶
- The ternary operator
?:is the same as inC++. Syntax:condition ? value_if_true : value_if_false.
Example 8.15: ternary operator
int number = 10;
// condition ? value_if_true : value_if_false
String result = (number > 0) ? "positive" : "non-positive";
System.out.println("The number is " + result);
// Finding the maximum of two numbers
int a = 15, b = 20;
int maximum = (a > b) ? a : b;
System.out.println("Maximum: " + maximum);
// Checking even or odd
int n = 7;
String parity = (n % 2 == 0) ? "even" : "odd";
System.out.println(n + " is " + parity);
// Absolute value
int x = -5;
int absValue = (x >= 0) ? x : -x;
System.out.println("Absolute value of " + x + " is " + absValue);
Output:
The class Math also provides the methods Math.max(a, b) and Math.abs(x), which return the same values.
8.6 Loops¶
Conditional statements choose whether a block of code is executed; loops decide how many times it is executed.
- Loops are used to execute a block of code repeatedly while a condition is met. As in
C++, the most commonly used loops ofJavaare thewhileloop and theforloop.
8.6.1 The while loop¶
- The
whileloop executes a block of code as long as the condition inside the parentheses()evaluates totrue. When the condition isfalse, the loop terminates.
Example 8.16: while loop
int i = 1; // Initialization
while (i <= 5) { // Condition
System.out.println("Number: " + i);
i++; // Increment
}
Output:
8.6.2 The for loop¶
- The
forloop combines initialization, condition, and increment (or decrement) in one statement, exactly as inC++.
Example 8.17: for loop
// Initialization; Condition; Increment
for (int i = 1; i <= 5; i++) {
System.out.println("Number: " + i);
}
The output is the same as in the while loop of Example 8.16.
8.6.3 The break and continue statements¶
-
The
breakstatement immediately terminates the loop. -
The
continuestatement skips the rest of the current iteration and moves to the next one.
Example 8.18: break and continue
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // Skip the even numbers
}
if (i > 7) {
break; // Stop the loop at the first odd number greater than 7
}
System.out.print(i + " ");
}
System.out.println();
Output:
The output is the same as in the C++ and Python versions: the value 9 triggers the break.
8.7 Arrays¶
Loops become really useful when they visit collections of values. A collection of variables of the same data type is stored in an array.
-
An array in
Javais an ordered collection of elements of the same data type, with a size fixed at creation time: the size cannot change afterwards. -
The data type of an array of integers is written
int[]. An array is allocated with thenewoperator, for examplenew int[n], where the sizencan be decided during the execution, as for the dynamic-size arrays ofC++. The elements of a new array are initialized to0(tofalseforboolean). -
Elements are accessed using their index inside square brackets
[], starting from0: the elements of an array of size \(n\) area[0],a[1], …,a[n-1]. Every array knows its size: the length of an arrayaisa.length. -
Unlike
C++, the memory of an array must not be freed withdelete[]: it is released automatically by the garbage collector of the JVM when the array is no longer used.
Arrays are allocated with new before use (or created with a list of values in curly braces). Indices start at 0, the size is fixed and is given by a.length.
Example 8.19: creating and accessing an array
int n = 5;
int[] a = new int[n]; // Allocation of an array of n integers
for (int i = 0; i < n; i++) {
a[i] = i * 2; // Example of value assignment
}
System.out.println("Length: " + a.length);
System.out.println("a[0] = " + a[0]); // First element
System.out.println("a[4] = " + a[4]); // Last element, index n-1
Output:
Accessing an index that does not exist, for example a[5], stops the program with the error ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 (in C++ the same access is not checked).
-
An array whose values are known when the program is written can be created by listing its values inside curly braces, as in
C++. -
The enhanced
forloopfor (int x : a)visits the elements of the arrayadirectly, without using their indices, like theforloop over a list ofPython. -
The method
Arrays.toString(a), of the classArraysof the packagejava.util, returns the elements of an array as a text in square brackets.
Example 8.20: array literal and iteration
import java.util.Arrays;
int[] a = {9, 12, 3, 16, 19, 11, 12};
int n = a.length;
for (int i = 0; i < n; i++) { // Loop over the indices
System.out.println("a[" + i + "] = " + a[i]);
}
for (int x : a) { // Loop over the elements
System.out.print(x + " ");
}
System.out.println();
System.out.println(Arrays.toString(a));
Output:
a[0] = 9
a[1] = 12
a[2] = 3
a[3] = 16
a[4] = 19
a[5] = 11
a[6] = 12
9 12 3 16 19 11 12
[9, 12, 3, 16, 19, 11, 12]
The import instruction is written at the beginning of the file, before the class.
8.7.1 Two-dimensional arrays¶
-
Two-dimensional arrays (matrices) are declared with two pairs of square brackets
[][], and allocated withnew int[m][n](\(m\) rows and \(n\) columns) in a single instruction. The element in row \(i\) and column \(j\) is accessed asmatrix[i][j], with both indices starting from \(0\);matrix.lengthis the number of rows andmatrix[i].lengthis the number of columns of row \(i\). -
A two-dimensional array can also be created by listing its values row by row:
int[][] c = {{3, 1, 4}, {1, 5, 9}};creates an array with \(2\) rows and \(3\) columns, andc[1][2]is the element in the second row and third column, equal to \(9\).
Example 8.21: two-dimensional array (matrix)
int m = 3; // Number of rows
int n = 2; // Number of columns
int[][] matrix = new int[m][n]; // Allocation of an m x n matrix
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = i * j; // Example of value assignment
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.println("matrix[" + i + "][" + j + "] = " + matrix[i][j]);
}
}
Output:
8.7.2 Lists of variable size: ArrayList¶
-
When the number of elements is not known in advance, the class
ArrayListof the packagejava.utilprovides a list that grows during the execution, like the lists ofPython. The data type of a list of integers isArrayList<Integer>: the elements of anArrayListare objects, andIntegeris the class that corresponds toint. -
The method
add(x)appends the elementxat the end of the list,get(i)returns the element of index \(i\),set(i, x)replaces it, andsize()returns the number of elements.
Example 8.22: a list of variable size
import java.util.ArrayList;
ArrayList<Integer> list = new ArrayList<>(); // Empty list
for (int i = 1; i <= 4; i++) {
list.add(i * i); // The list grows
}
list.set(0, 100); // Replaces the element of index 0
System.out.println(list + " has " + list.size() + " elements");
System.out.println("list.get(2) = " + list.get(2));
Output:
8.8 Methods (functions)¶
As in pseudo-code, an algorithm is written as a function that receives the input and returns the output. In Java, functions are called methods and must always be defined inside a class.
-
A method in
Javaconsists of:-
an optional access modifier (e.g.,
public,private) and the keywordstaticwhen the method belongs to the class rather than to an object of the class (all the methods of this chapter arestatic); -
a return type: specifies the type of the returned value (
voidif nothing is returned); -
a method name: the unique identifier of the method;
-
a parameter list (optional): specifies the input values, each one with its data type;
-
a body: the block of code executed when the method is called;
-
a
returnstatement, mandatory if the return type is notvoid.
-
-
The entry point of every
Javaprogram is the methodpublic static void main(String[] args), which plays the role of themainfunction ofC++. The parameterargscontains the words written after the name of the class in the commandjava. -
Unlike
C++, a method can be called before the point where it is defined in the class: the order of the methods inside a class does not matter. -
Javasource code can also be compiled and executed online, for example at the following address:
www.mycompiler.io/online-java-compiler
Example 8.23: methods
public class Main {
// Method definition
static int addition(int a, int b) {
return a + b; // Returns the sum
}
// Method definition
static int multiplication(int a, int b) {
return a * b; // Returns the product
}
public static void main(String[] args) {
int sum = addition(5, 10); // Method call
System.out.println("Sum: " + sum);
int prod = multiplication(5, 10); // Method call
System.out.println("Prod: " + prod);
}
}
Output:
Example 8.24: method operating on a two-dimensional array
public class Main {
static int sumMatrix(int[][] matrix, int rows, int cols) {
int sum = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sum += matrix[i][j];
}
}
return sum;
}
public static void main(String[] args) {
int m = 3, n = 2;
int[][] matrix = new int[m][n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
matrix[i][j] = i * j;
int total = sumMatrix(matrix, m, n);
System.out.println("Sum of matrix elements: " + total);
}
}
Output:
The body of a for loop made of a single instruction can be written without curly braces, as in C++.
8.8.1 Parameters and return values¶
-
In
Javaevery parameter is passed by value: the method receives a copy of the argument. For the primitive data types (int,double,boolean,char) the changes made to the copy do not affect the variable of the caller; there is no passing by reference as with the symbol&ofC++. -
A variable of type
int[]does not contain the elements, but a reference to the array (similar to the pointer ofC++). The method receives a copy of the reference, which points to the same array: the changes made to the elements of the array are visible to the caller. -
A method returns at most one value. When a method has to give back several results, it can return them in an array, for example
new int[]{q, r}.
Example 8.25: parameters and multiple results
public class Main {
static void increment(int x) {
x = x + 1; // Modifies only the local copy
}
static void fillWithZeros(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] = 0; // Modifies the array of the caller
}
}
static int[] divide(int n, int m) {
return new int[]{n / m, n % m}; // Two results in an array
}
public static void main(String[] args) {
int k = 5;
increment(k);
System.out.println("After increment: " + k);
int[] b = {4, 7, 1};
fillWithZeros(b);
System.out.println("Array: " + b[0] + " " + b[1] + " " + b[2]);
int[] qr = divide(17, 5);
System.out.println("Quotient and remainder: " + qr[0] + " " + qr[1]);
}
}
Output:
8.9 A complete algorithm: the maximum value in an array¶
We now put all the pieces together: a method, a loop, a conditional statement and an array.
We consider the problem of finding the maximum value in an array \(a\) of \(n \ge 1\) integer numbers.
- This is the pseudo-code of the algorithm
FindMaximumof the chapter «Pseudo-code»: the entries are indexed from \(1\) to \(n\).
Algorithm: FindMaximum
-
This is the
Javaimplementation. The elements are indexed from \(0\) to \(n-1\), so the initialization usesa[0]and the loop starts fromi = 1. The size \(n\) is not passed as a parameter, because the method obtains it witha.length. The method assumes \(n \ge 1\), as the pseudo-code does: for an empty array the access toa[0]stops the program with anArrayIndexOutOfBoundsException.public class Main { // Method to find the maximum value in an array static int arrayMaxValue(int[] a) { int max = a[0]; // Initialize with the first element for (int i = 1; i < a.length; i++) { if (a[i] > max) { max = a[i]; // Update the maximum } } return max; } public static void main(String[] args) { int[] a = {9, 12, 3, 16, 19, 11, 12}; int max = arrayMaxValue(a); System.out.println("Maximum value: " + max); } }Output:
-
The test instance can also be generated at random with the class
Randomof the packagejava.util: ifrandis an object of this class,rand.nextInt(100)returns a random integer between \(0\) and \(99\), sorand.nextInt(100) + 1is between \(1\) and \(100\). The object created withnew Random(2026)starts from the fixed value \(2026\) (the seed), so that every execution produces the same array; the object created withnew Random()produces a different array at every execution.
Example 8.26: a random instance
import java.util.Arrays;
import java.util.Random;
public class Main {
static int arrayMaxValue(int[] a) {
int max = a[0];
for (int i = 1; i < a.length; i++) {
if (a[i] > max) {
max = a[i];
}
}
return max;
}
public static void main(String[] args) {
int n = 10; // Size of the array
int[] a = new int[n];
Random rand = new Random(2026); // Same random array at every execution
for (int i = 0; i < n; i++) {
a[i] = rand.nextInt(100) + 1; // Random integer between 1 and 100
}
System.out.println(Arrays.toString(a));
System.out.println("Maximum value: " + arrayMaxValue(a));
}
}
Output:
Example 8.27: step-by-step execution
In each table, the column \(i\) is the index of the Java loop and the column \(i+1\) is the corresponding index of the pseudo-code. The first row is the initialization max = a[0].
Instance 1: \(a = [9, 12, 3, 16, 19, 11, 12]\), \(n=7\)
\(i\) (Java) |
\(i+1\) (pseudo-code) | a[i] |
a[i] > max? |
max |
|---|---|---|---|---|
| – | – | – | – | \(9\) |
| \(1\) | \(2\) | \(12\) | Yes | \(12\) |
| \(2\) | \(3\) | \(3\) | No | \(12\) |
| \(3\) | \(4\) | \(16\) | Yes | \(16\) |
| \(4\) | \(5\) | \(19\) | Yes | \(19\) |
| \(5\) | \(6\) | \(11\) | No | \(19\) |
| \(6\) | \(7\) | \(12\) | No | \(19\) |
Return: max \(= 19\)
Instance 2: \(a = [3, 7, 2, 9, 1]\), \(n=5\)
\(i\) (Java) |
\(i+1\) (pseudo-code) | a[i] |
a[i] > max? |
max |
|---|---|---|---|---|
| – | – | – | – | \(3\) |
| \(1\) | \(2\) | \(7\) | Yes | \(7\) |
| \(2\) | \(3\) | \(2\) | No | \(7\) |
| \(3\) | \(4\) | \(9\) | Yes | \(9\) |
| \(4\) | \(5\) | \(1\) | No | \(9\) |
Return: max \(= 9\)
8.10 Bitwise operators¶
The bitwise operators of the chapter «Introduction to C++» exist in Java with the same symbols and the same meaning: & (AND), | (OR), (XOR), ~ (NOT), < < (left shift) and > > (right shift). The method Integer.toBinaryString(x) returns the binary representation of an integer.
-
A value of type
inthas \(32\) bits, so~12flips \(32\) bits and gives-13; the \(8\)-bit result ofC++is obtained with the mask0xFF, as inPython. -
Javahas a third shift operator,> > >(unsigned right shift), which always adds zeros on the left, also for negative numbers; for non-negative numbers it coincides with> >. -
Since a condition must be of type
boolean, the test of the least significant bit is written(n & 1) == 1, and not(n & 1)as inC++.
Example 8.28: bitwise operators
int a = 12; // Binary: 1100
int b = 10; // Binary: 1010
System.out.println((a & b) + " " + (a | b) + " " + (a ^ b)); // AND, OR, XOR
System.out.println(Integer.toBinaryString(a & b)); // 1000
System.out.println((5 << 2) + " " + (20 >> 2) + " " + (20 >> 3)); // Shifts
System.out.println(~a + " " + (~a & 0xFF)); // NOT, and its 8-bit version
System.out.println((-8 >> 1) + " " + (-8 >>> 28)); // Signed and unsigned shift
int n = 15;
System.out.println(((n & 1) == 1) ? "odd" : "even"); // Least significant bit
Output:
The number \(-8\) is stored as \(11\dots11000\) (\(32\) bits): -8 > > 1 keeps the sign and gives \(-4\), while -8 > > > 28 keeps only the \(4\) leftmost bits \(1111\), that is \(15\).
8.11 Java, C++ and Python side by side¶
The following table summarizes the main differences among the three languages of this part of the course.
C++ |
Java |
Python |
|
|---|---|---|---|
| Execution | compiled (g++) |
compiled into bytecode (javac), executed by the JVM (java) |
interpreted (python3) |
| Data types | declared | declared | not declared |
| Blocks | {} |
{} |
: and indentation |
| End of instruction | ; |
; |
end of the line |
| Boolean values | true, false (printed 1, 0) |
true, false |
True, False |
10 / 3 |
3 |
3 |
3.3333333333333335 |
-7 / 2 (integer) |
-3 |
-3 |
-7 // 2 is -4 |
| Largest integer | \(2^{31}-1\) for int |
\(2^{31}-1\) for int |
no limit |
| Logical operators | &&, ||, ! |
&&, ||, ! |
and, or, not |
| Collections | arrays, freed with delete[] |
arrays (a.length) and ArrayList, freed automatically |
lists (len(a)), freed automatically |
| Out-of-range index | not checked | exception | exception |
| Several results | parameters by reference | return of an array | return of a tuple |
| Entry point | function main |
method main of a class |
top level of the file |
Key points of the chapter
-
A
Javaprogram is made of classes; it is compiled into bytecode withjavacand executed by the JVM withjava, starting from the methodpublic static void main(String[] args). -
Every variable is declared with its data type, which is checked by the compiler; the data type
inthas \(32\) bits, and the division between two integers is the integer division. -
Conditional statements (
if,else if,else,?:) and loops (while,for, and the enhancedfor) have the same syntax as inC++, but a condition must be of typeboolean. -
The arrays of
Javaare allocated withnew, know their sizea.length, are indexed from \(0\) to \(n-1\) and are freed automatically; the classArrayListprovides lists of variable size. -
Parameters are passed by value; a method that receives an array can modify its elements, and several results are returned together in an array.
Exercises on this chapter: Introduction to Java