James (Siyuan) Guo     Home | CV | Research | Notes | Projects | Teaching | Blogs | Contact



Basic Java Notes

Basic Text Output

Java uses System.out.* statements to print a text to the screen.

Unformatted Print

Print within the same line: System.out.print();

Print with a new line at the end: System.out.println();

Formatted Print

Print formatted: System.out.printf(); or System.out.format();

Format specifiers and formatting

Format specifier Data type(s) Notes
%c char Prints a single Unicode character
%d int, long, short Prints a decimal integer value.
%o int, long, short Prints an octal integer value.
%h int, char, long, short Prints a hexadecimal integer value.
%f float, double Prints a floating-point value.
%e float, double Prints a floating-point value in scientific notation.
%s String Prints the characters in a String variable or literal.
%%   Prints the “%” character.
%n   Prints the platform-specific new-line character.


Sub-specifier Description
width Specifies the minimum number of characters to print. With longer characters, the value will be unchanged; with fewer characters, the output will be padded with spaces (or 0’s if the ‘0’ flag is specified).
.precision (For floating-point:) Specifies the number of digits to print following the decimal point. The default precision of 6 is used.
(For String:) Specifies the maximum number of characters to print, truncate the extra characters.
flags -: Left aligns the output given the specified width, padding the output with spaces.
+: Prints a preceding + sign for positive values. Negative numbers are always printed with the - sign.
0: Pads the output with 0’s when the formatted value has fewer characters than the width.
space: Prints a preceding space for positive value.


Output Format

System.out.printf("%(flags1)(width1)(.precision1)specifier1...%(flags2)(width2)(.precision2)specifier2", var1, var2);

Flushing Output

The PrintStream method flush() flushes the stream’s buffer contents. System.out.flush(); is called when a newline is printed.

Variables

In a program, a variable is a named item used to hold a value.

Variable Assignments

An assignment assigns a variable with a value. That assignment means the variable is assigned with something, while keeping that value during subsequent assignments, until it is assigned again.

In programming, = is an assignment of a left-side variable with a right-side value.

Reserved Keywords

abstract
assert
boolean 
break 
byte 
case 
catch 
char 
class 
const 
continue 
default 
do 
double 
else 
enum 
extends 
final 
finally 
float 
for 
goto 
if 
implements 
import 
instanceof 
int 
interface 
long 
native 
new 
package 
private 
protected 
public 
return 
short 
static 
strictfp 
super 
switch 
synchronized 
this 
throw 
throws 
transient 
try 
void 
volatile 
while

Constant Variables

Constant variables, known as final variables, should not be chanced in the code by adding final before variable declaration.

Primitives Type

A primitive type variable directly stores the data for that variable type.

boolean

char

byte, short, int, and long

float and double

Wrapper Class Java provides several wrapper classes that are built-in reference types that augment the primitive types. The wrapper class has the only field of primitive type with relations below.

Primitive type char int double boolean long
Wrapper Class Character Integer Double Boolean Long

Overflow

A variable cannot store a number larger than the maximum supported by the variable’s data type. An overflow occurs when the value being assigned to a variable is greater than the maximum value the variable can store. This will error in being too large.

Reference Type

Classes

To use a class, a program must include an import statement that informs the compiler of the class’ location.

Math Class

From java.lang.Math, imported by defult.

Fields:

Methods:

Scanner Class

Import by import java.util.Scanner;.

Initialize by Scanner keyboard = new Scanner(System.in); for input.

Methods:

Random Class

Import by import java.util.Random;.

Initialize by Random rand = new Random();.

Methods:

String Class

From java.lang.String, import by defult.

Methods:

Selection

In a program, a branch is a sequence of statements only executed under a certain condition.

If-Else If-Else-branch

if (expression) {
	// Statements
} else if (expression) {
	// Statements
} ... else {
	// Statements
}

Switch Statement

A switch statement can more clearly represent multi-branch behavior involving a variable being compared to constant values.

Omitting the break statement for a case will cause the statements within the next case to be executed.

switch (expression) {
   case constantExpr1: 
      // Statements
      break;
   case constantExpr2:
      // Statements
      break;
   ...
   default: // If no other case matches
      // Statements
      break;
}

Order of Evaluation

In the code, the order is followed as:

DeMorgan’s Law

Specifically, this means that (!(A || B)) is equivalent to (!A && !B) and (!(A && B)) is equivalent to (!A || !B).

Loops

Code that will be run repetitively until a specified condition is met.

While Loop

A while loop repeatedly executes a list of sub-statements (loop body) while the loop’s expression evaluates to true. Each loop is an iteration.

Once entering the loop body, execution continues to the body’s end, even if the expression would become false midway through.

while (expression) {
	// Statements
}

Do-While Loop

Do-While loop works like the while loop but the statement is excuted at least once.

do {
	// Statements
} while (expression);

For Loop

A for loop is a loop with three parts at the top: a loop variable initialization, a loop expression, and a loop variable update.

A for loop describes iterating a specific number of times more naturally than a while loop.

for (initialExpression; conditionExpression; updateExpression) {
	// Statements
}

Nested Loops

A nested loop is a loop that appears in the body of another loop. The nested loops are commonly referred to as the inner loop and outer loop.

Break and Continue

A break statement in a loop causes an immediate exit of the loop. A break statement can sometimes yield a loop that is easier to understand.

A continue statement in a loop causes an immediate jump to the loop condition check. A continue statement can sometimes improve the readability of a loop.

Method

A method is a named list of statements.

public static returnType methodName(paramType paramName, ...) {
	// Statements
}

Each method call creates a new set of local variables, forming part of what is known as a stack frame. A return causes those local variables to be discarded.

Recursion Methods

A method may call other methods, including calling itself. A method that calls itself is a recursive method.

Method Overloading

Sometimes a program has two methods with the same name but differing in the number or types of parameters, known as method name overloading or just method overloading.

Testing

Testing tests if the code works properly. The test involves:

Unit Testing

Each sub-routine should be thoroughly tested independent of the other sub-routines.

Apply Black-box and White-box testing to each unit.

Regression Testing

Re-test the cases in the previous versions.

Apply the original test suite of the previous version.

Black-box Testing

Program code is hidden from the testers.

Being comprehensive, meaning to throw as many testing to check if the output is the same as expected.

White-box Testing

Program code known to the testers.

Throw targeted input at the code to thoroughly test all the execution branch that has been written in the program (i.e., all decisions, repetition between starting and ending values).

Test the correctness of the code that has been written thus far.

File I/O

InputStream and OutputStream are necessary for information to flow in JAVA.

FileInputStream Class

FileInputStream opens a file. The class can be imported by import java.io.FileInputStream.

FileInputStream could throw IOExceptions. The class can be imported by import java.io.IOException.

When methods includes FileInputStream, the method throws IOException.

Reading FileInputStream involves a Scanner, therefore meaning to be imported by import java.util.Scanner.

A FileInputStream is initialized and followed by:

FileInputStream fileInputStream = new FileInputStream(filename);
Scanner inFS = new Scanner(fileInputStream);

Then, the Scanner can be read by the Scanner class.

Afterwards, the Scanner and FileInputStream can be closed by:

inFS.close();
fileInputStream.close();

FileOutputStrean Class

FileOutputStream writes a file. The class can be imported by import java.io.FileOutputStream.

FileOutputStream could throw IOExceptions. The class can be imported by import java.io.IOException.

When methods includes FileOutputStream , the method throws IOException.

Writing in a file involves PrintWriter, therefore meaning to be imported by import java.io.PrintWriter.

A FileOutputStream is initialized and followed by:

FileOutputStream fileOutputStream = new FileOutputStream(filename);
PrintWriter outFS = new PrintWriter(FileOutputStream);

Then, the PrintWriter can be written by the same approach of System.out class.

Afterwards, the PrintWriter and FileOutputStream can be closed by:

outFS.close();
fileOutputStream.close();

Arrays

An array is a special variable having one name, but storing a list of data items, with each item being directly accessible.

1-D Array

An array is an ordered list of items of a given data type. Each item in an array is called an element. It can be initialized by:

dataType[] arrayName = new dataType[numElements];

or

dataType[] arrayName = {a, ..., c};

As a reference type, the array as a parameter of a method is modified in the function.

Printing through loop:

public static void print(arrayName.length) {
	System.out.print("[")
	for (int i = 0; i < arrayName.length; i++) {
		System.out.print(arrayName[i]);
		if (i != arrayName.length - 1) {
			System.out.print(", ");
		}
	}
	System.out.println("]");
}

Perfect Size Array

A perfect size array is an array where the number of elements is exactly equal to the memory allocated.

Oversize Array

An oversize array is an array where the number of elements used is less than or equal to the memory allocated.

Since the number of elements used in an oversize array is usually less than the array’s length, a separate integer variable is used to keep track of how many array elements are currently used.

The Oversize Array are initialized as:

dataType[] arrayName = new dataType[totalNumElements];
int arrayNameLength = 0;

Oversize arrays are useful when the number of elements stored in the array is not known in advance, or when the number of elements stored in an array varies over time.

To assign a new element to the array, the approach is:

arrayName[arrayNameLength++] = newElement;

2-D Array

An array can be declared with two dimensions. Object[][] myArray = new Object[R][C] represents a table of int variables with R rows and C columns, so \(R\times C\) elements total.

Or the initialization can be:

dataType[][] arrayName = {{a, ..., b}, ..., {c, ..., d}};

The definition, access, and initialization works the same for higher dimensions.

When printing for searching values, there should be a nested for loop.

Advanced Classes

Creating an object consists of two steps: declaring a reference variable of the class type, and assigning the variable with an explicitly allocated instance of the class type.

A reference variable can refer to an instance of a class.

The new operator explicitly allocates an object of the specified class type.

Class Components

A class contains fields, constructors, mutators, accessors, and helper methods.

Field:

Constructor:

Mutator:

Accessor:

Helper Method:

Derived Class

A derived class (or subclass) is a class that is derived from another class, called a base class (or superclass).

With multiple classes, this refers to the fields or method in the current class, while super refers to the fields or method in the base class.

Static and Non-Static

The data types are static and non-static.

Static fields and method

The variable is allocated in memory only once during a program’s execution. Static variables reside in the program’s static memory region and have a global scope. Thus, static variables can be accessed from anywhere in a program.

Non-Static fields and method

The variable are different for each instance of the data. The variables will change at different with the reference type to the same class.

Accessibility

Access specifier specifies the accessibility of the data:

Specifier Description
private Accessible by self.
protected Accessible by self, derived classes, and other classes in the same package.
public Accessible by self, derived classes, and everyone else.
no specifier Accessible by self and other classes in the same package.

Polymorphism

Polymorphism refers to determining which program behavior to execute depending on data types.

Is-a versus Has-a

Is-a indicates a relationship of some class being a subclass extended from base class. Has-a indicates if the class is using other classes as fields.

Object Class

All the classes extends from Object Class.

Override and Overload

Overrride means that a method is overriding another method from the base class with the same parameters.

Overload means that a method is overloading another method from the base class with different parameters.

instanceof

The real type and the container type of a variable can be different, but the real type must be the container type or its subclasses.

When testing if an Object is an instance of a class, use var.instanceof(class).

If an Object is an instance of a class, we cast by (class) var.

Algorithm

An algorithm is a sequence of steps for accomplishing a task.

Big O Notation

Big O notation is a mathematical way of describing how a function (running time) generally behaves in relation to the input size.

In Big O notation, all functions that have the same growth rate (as determined by the highest order term of the function) are characterized using the same Big O notation. All functions with the same growth rate are equivalent in Big O notation.

Properties:

Growth rate:

\[O(1) < O(N) < O(N\log N) < O(N^2) < O(N^3) < \cdots < O(e^N).\]
Composite function \(C\cdot O(f(x))\) \(C+ O(f(x))\) \(g(x)\cdot O(f(x))\) \(g(x)+O(f(x))\)
Big O Notation \(O(f(x))\) \(O(f(x))\) \(O(g(x)\cdot O(f(x)))\) \(O(g(x)+O(f(x)))\)

Sorting Algorithms

Bubble Sort

int temp;
for (i = 0; i < numbers.length - 1; ++i) {
	// Nested loop with less in search each iteration
	for (j = 1; j < numbers.length - i; ++j) {
		if (numbers[j-1] > numbers[j]) {
			// Swap numbers[j] and numbers[j-1]
			temp = numbers[j];
			numbers[j] = numbers[j-1];
			numbers[j-1] = temp;
		}
	}
}

Selection Sort

int temp;
int indexSmallest;

for (i = 0; i < numbers.length - 1; ++i) {
		// Find index of smallest remaining element
	indexSmallest = i;
	for (j = i + 1; j < numbers.length; ++j) {
		if (numbers[j] < numbers[indexSmallest]) {
			indexSmallest = j;
		}
	}
	// Swap numbers[i] and numbers[indexSmallest]
	temp = numbers[i];
	numbers[i] = numbers[indexSmallest];
	numbers[indexSmallest] = temp;
}

Insertion Sort

for (i = 1; i < numbers.length; ++i) {
	j = i;
	// Insert numbers[i] into sorted part
	// stopping once numbers[i] in correct position
	while (j > 0 && numbers[j] < numbers[j - 1]) {
	
		// Swap numbers[j] and numbers[j - 1]
		temp = numbers[j];
		numbers[j] = numbers[j - 1];
		numbers[j - 1] = temp;
		--j;
	}
}

Merge Sort

public static void merge(int [] numbers, int i, int j, int k) {
  int mergedSize = k - i + 1;       // Size of merged partition
  int mergedNumbers [] = new int[mergedSize];
  							// Temporary array for merged numbers
  int mergePos;           	// Position to insert merged number
  int leftPos;            	// Position of elements in left partition
  int rightPos;           	// Position of elements in right partition
  mergePos = 0;
  leftPos = i;            	// Initialize left partition position
  rightPos = j + 1;       	// Initialize right partition position
 // Add smallest element from left or right partition
  while (leftPos <= j && rightPos <= k) {
     if (numbers[leftPos] < numbers[rightPos]) {
        mergedNumbers[mergePos] = numbers[leftPos];
        ++leftPos;
     } 
     else {
        mergedNumbers[mergePos] = numbers[rightPos];
        ++rightPos;
     }
     ++mergePos;
  }
 // If left partition is not empty, add remaining elements
  while (leftPos <= j) {
     mergedNumbers[mergePos] = numbers[leftPos];
     ++leftPos;
     ++mergePos;
  }
 // If right partition is not empty, add remaining elements
  while (rightPos <= k) {
     mergedNumbers[mergePos] = numbers[rightPos];
     ++rightPos;
     ++mergePos;
  }
 // Copy merge number back to numbers
  for (mergePos = 0; mergePos < mergedSize; ++mergePos) {
     numbers[i + mergePos] = mergedNumbers[mergePos];
  }
}

public static void mergeSort(int [] numbers, int i, int k) {
  int j;
 if (i < k) {
     j = (i + k) / 2;  // Find the midpoint in the partition
    // Recursively sort left and right partitions
     mergeSort(numbers, i, j);
     mergeSort(numbers, j + 1, k);
    // Merge left and right partition in sorted order
     merge(numbers, i, j, k);
  }
}

Searching Algorithms

Linear Search

public static int linearSearch(int [] numbers, int key) {
	int i;
	
	for (i = 0; i < numbers.length; ++i) {
		if (numbers[i] == key) {
		return i;
		}
	}
	
	return -1; /* not found */
}

Binary Search

private static int search(String[] data, String target,
							int lo, int hi) {
	// possible target indices in [lo, hi)
	int middleIndex = (lo + hi) / 2;
	if (lo == hi) return -1;
	String middle = data[middleIndex];
	if (target.equals(middle)) {
		return middleIndex;
	}
	if (target.compareTo(middle) < 0) {
		return search(data, target, lo, middleIndex);
	}
	if (target.compareTo(middle) > 0) {
		return search(data, target, middleIndex + 1, hi);
	}
	return -1;
}

Exceptions

An exception is an unexpected incident that stops the normal execution of a program.

Checked/Unchecked Exceptions

Checked Exceptions are the exceptions that are checked at compile time. If some code within a method throws a checked exception, then the method must either handle the exception or it must specify the exception using the throws keyword.

List of checked exceptions

- ClassNotFoundException,
- InterruptedException,
- InstantiationException,
- IOException,
- SQLException,
- IllegalAccessException,
- FileNotFoundException ...

Unchecked exceptions in Java are those exceptions that are checked by JVM, not by java compiler. They occur during the runtime of a program.

List of unchecked exceptions

- ArithmeticException,
- ClassCastException,
- NullPointerException,
- ArrayIndexOutOfBoundsException,
- NegativeArraySizeException,
- ArrayStoreException,
- IllegalThreadStateException,
- SecurityException ...

Try-Catch Block

To avoid having a program end when an exception occurs, a program can use try and catch blocks to handle the exception during program execution.

Throwable Class

The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class can be errors or exceptions.

Only this class or one of its subclasses can be the argument type in a catch clause.

Exception Class

Exception class subclass of Throwable class.

Style

Each programming team has style guidelines for writing code.

Whitespace

Braces

Naming

Code




🌞
If you find any questions, please contact me via Contact tab.