This document is a comprehensive guide to Java fundamentals, specially tailored for mastering Data Structures and Algorithms (DSA). It covers all the essential concepts, syntax, and features of Java, enabling you to build a strong foundation for solving complex DSA problems. Let’s dive into the details!
javac), libraries, and tools required for development.bin directory of your JDK installation to the system PATH.java -version
javac -version
$, or _.$, and _.myVar and MyVar are different).Example:
int age; // Valid
int _salary; // Valid
int $price; // Valid
int 123num; // Invalid (starts with a digit)
int class; // Invalid (keyword)
| Access Modifiers | Control Flow | Primitive Types | Other Keywords |
|---|---|---|---|
public |
if |
int |
class, return |
private |
else |
boolean |
static, void |
protected |
switch |
char |
this, new |
final |
while |
double |
throws, try |
Java has two categories of data types:
byte: 1 byte, values (-128 to 127)short: 2 bytes, values (-32,768 to 32,767)int: 4 bytes, values (-2^31 to 2^31 - 1)long: 8 bytes, values (-2^63 to 2^63 - 1)float: 4 bytes, single-precision decimalsdouble: 8 bytes, double-precision decimalschar: 2 bytes, stores a single Unicode character.boolean: Stores true or false.Example:
byte b = 100;
int num = 100000;
char grade = 'A';
boolean isJavaFun = true;
String name = "Java";int[] arr = {1, 2, 3};Variables are containers for storing data values.
Declaration Syntax:
data_type variable_name = value;
Example:
int age = 25; // Integer variable
double price = 99.99; // Decimal variable
static keyword, shared across all instances.import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hello, " + name);
}
}
import java.io.*;
public class BufferedReaderExample {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter your age: ");
int age = Integer.parseInt(reader.readLine());
System.out.println("Your age is: " + age);
}
}
import java.io.*;
public class PrintWriterExample {
public static void main(String[] args) throws IOException {
PrintWriter out = new PrintWriter(System.out);
out.println("Fast Output Example");
out.flush();
}
}
if (condition) {
// Code when condition is true
} else {
// Code when condition is false
}
int day = 3;
switch (day) {
case 1: System.out.println("Monday"); break;
case 2: System.out.println("Tuesday"); break;
default: System.out.println("Other Day");
}
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
int i = 0;
while (i < 5) {
System.out.println(i);
i++;
}
int i = 0;
do {
System.out.println(i);
i++;
} while (i < 5);
Arithmetic operators are used for mathematical calculations. The following table lists the operators and their usage:
| Operator | Description | Example |
|---|---|---|
+ |
Addition | a + b |
- |
Subtraction | a - b |
* |
Multiplication | a * b |
/ |
Division | a / b |
% |
Modulus (Remainder) | a % b |
Example:
int a = 10, b = 3;
System.out.println("Addition: " + (a + b)); // 13
System.out.println("Subtraction: " + (a - b)); // 7
System.out.println("Multiplication: " + (a * b)); // 30
System.out.println("Division: " + (a / b)); // 3
System.out.println("Remainder: " + (a % b)); // 1
Relational operators compare two values and return a boolean result (true or false).
| Operator | Description | Example |
|---|---|---|
== |
Equal to | a == b |
!= |
Not equal to | a != b |
> |
Greater than | a > b |
< |
Less than | a < b |
>= |
Greater than or equal to | a >= b |
<= |
Less than or equal to | a <= b |
Example:
int x = 5, y = 10;
System.out.println(x > y); // false
System.out.println(x < y); // true
System.out.println(x == y); // false
System.out.println(x != y); // true
Logical operators are used to combine conditional statements.
| Operator | Description | Example |
|---|---|---|
&& |
Logical AND | (a > b) && (c > d) |
|| |
Logical OR | (a > b) || (c > d) |
! |
Logical NOT | !(a > b) |
Example:
int a = 10, b = 20, c = 30;
System.out.println((a > b) && (b < c)); // false
System.out.println((a < b) || (b > c)); // true
System.out.println(!(a < b)); // false
Assignment operators are used to assign values to variables.
| Operator | Description | Example |
|---|---|---|
= |
Assign | a = b |
+= |
Add and assign | a += b |
-= |
Subtract and assign | a -= b |
*= |
Multiply and assign | a *= b |
/= |
Divide and assign | a /= b |
%= |
Modulus and assign | a %= b |
Example:
int a = 10;
a += 5; // a = a + 5
System.out.println(a); // 15
a *= 2; // a = a * 2
System.out.println(a); // 30
Unary operators are applied to a single operand.
| Operator | Description | Example |
|---|---|---|
+ |
Unary plus | +a |
- |
Unary minus | -a |
++ |
Increment | ++a or a++ |
-- |
Decrement | --a or a-- |
! |
Logical NOT | !a |
Example:
int x = 5;
System.out.println(++x); // Pre-increment: 6
System.out.println(x++); // Post-increment: 6 (then x becomes 7)
System.out.println(--x); // Pre-decrement: 6
System.out.println(x--); // Post-decrement: 6 (then x becomes 5)
Bitwise operators perform operations on the binary representation of numbers.
| Operator | Description | Example |
|---|---|---|
& |
AND | a & b |
| |
OR | a | b |
^ |
XOR | a ^ b |
~ |
Complement | ~a |
<< |
Left Shift | a << b |
>> |
Right Shift | a >> b |
Example:
int a = 5, b = 3; // Binary: a = 0101, b = 0011
System.out.println(a & b); // AND: 0001 (1)
System.out.println(a | b); // OR: 0111 (7)
System.out.println(a ^ b); // XOR: 0110 (6)
System.out.println(~a); // NOT: 1010 (-6 in 2's complement)
System.out.println(a << 1); // Left Shift: 1010 (10)
System.out.println(a >> 1); // Right Shift: 0010 (2)
A method is a block of code that performs a specific task. It is reusable and improves modularity.
Syntax:
returnType methodName(parameters) {
// Method body
return value; // if returnType is not void
}
Example:
public class MethodExample {
public static int addNumbers(int a, int b) {
return a + b;
}
public static void main(String[] args) {
int result = addNumbers(5, 10);
System.out.println("Sum: " + result);
}
}
Static methods belong to the class rather than instances of the class. They can be called without creating an object.
Example:
public class StaticExample {
public static void printMessage() {
System.out.println("This is a static method.");
}
public static void main(String[] args) {
printMessage(); // Direct call to static method
}
}
In Java, method arguments are passed by value. Changes made to the parameters inside the method do not affect the original variables.
Example:
public class CallByValue {
public static void modifyValue(int x) {
x = x + 10; // Change only inside the method
}
public static void main(String[] args) {
int num = 5;
modifyValue(num);
System.out.println("Original value: " + num); // Output: 5
}
}
Recursion is a technique where a method calls itself to solve a problem.
Example (Factorial):
public class RecursionExample {
public static int factorial(int n) {
if (n == 0) {
return 1; // Base case
}
return n * factorial(n - 1); // Recursive case
}
public static void main(String[] args) {
int result = factorial(5);
System.out.println("Factorial: " + result); // Output: 120
}
}
Tail recursion is when the recursive call is the last statement in the function. It can be optimized by the compiler to reduce stack usage.
Example:
public class TailRecursion {
public static int factorialTail(int n, int accumulator) {
if (n == 0) {
return accumulator;
}
return factorialTail(n - 1, accumulator * n);
}
public static void main(String[] args) {
int result = factorialTail(5, 1);
System.out.println("Factorial: " + result); // Output: 120
}
}