Download as pdf or txt
Download as pdf or txt
You are on page 1of 40

Java Notes

First Code in Java


To get started with Java, you need to write a simple program. Below is the traditional "Hello,
World!" program in Java:

public class HelloWorld {


public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

Explanation:

public class HelloWorld : Defines a class named HelloWorld .

public static void main(String[] args) : The main method where the program execution begins.

System.out.println("Hello, World!"); : Prints "Hello, World!" to the console.

How Java Works


Java is a high-level, object-oriented programming language that is platform-independent thanks to
the Java Virtual Machine (JVM). Here's a brief overview of how Java works:

1. Writing Code: Write Java code in .java files.

2. Compiling: Use the Java compiler ( javac ) to compile the code into bytecode, which is stored in
.class files.

3. Executing: The JVM interprets or just-in-time compiles the bytecode to machine code specific
to the operating system and hardware.

Variables in Java
Variables are used to store data. They must be declared before use.

int number; // Declaration


number = 10; // Initialization
int anotherNumber = 20; // Declaration and initialization

Data Types in Java


Java has two categories of data types: primitive and non-primitive.
Primitive Data Types:

byte : 8-bit integer

short : 16-bit integer

Java Notes 1
int : 32-bit integer

long : 64-bit integer

float : 32-bit floating point

double : 64-bit floating point

char : 16-bit Unicode character

boolean : true or false

int age = 25;


float price = 10.99f;
char grade = 'A';
boolean isJavaFun = true;

Non-Primitive Data Types:

String, Arrays, Classes, etc.

Literals
Literals are fixed values assigned to variables.

int num = 100; // Integer literal


float pi = 3.14f; // Float literal
char letter = 'A'; // Char literal
boolean flag = true; // Boolean literal
String greeting = "Hello"; // String literal

Type Conversion
Type conversion can be implicit or explicit.
Implicit Conversion:

int num = 10;


double d = num; // Automatic conversion from int to double

Explicit Conversion (Casting):

double d = 9.78;
int num = (int) d; // Casting double to int

Java Notes 2
Assignment Operators
Assignment operators are used to assign values to variables.

int a = 10; // Assign 10 to a


a += 5; // Equivalent to a = a + 5
a -= 3; // Equivalent to a = a - 3
a *= 2; // Equivalent to a = a * 2
a /= 2; // Equivalent to a = a / 2
a %= 3; // Equivalent to a = a % 3

Relational Operators
Relational operators compare two values and return a boolean result.

int a = 10, b = 20;


System.out.println(a == b); // false
System.out.println(a != b); // true
System.out.println(a > b); // false
System.out.println(a < b); // true
System.out.println(a >= b); // false
System.out.println(a <= b); // true

Logical Operators
Logical operators are used to combine multiple boolean expressions.

boolean x = true, y = false;


System.out.println(x && y); // false
System.out.println(x || y); // true
System.out.println(!x); // false

If-Else
If-else statements are used for conditional execution.

int age = 18;


if (age >= 18) {
System.out.println("You are an adult.");
} else {
System.out.println("You are not an adult.");

Java Notes 3
}

If-Else If
If-else if statements handle multiple conditions.

int score = 85;


if (score >= 90) {
System.out.println("Grade A");
} else if (score >= 80) {
System.out.println("Grade B");
} else if (score >= 70) {
System.out.println("Grade C");
} else {
System.out.println("Grade D");
}

Ternary Operator
The ternary operator is a shorthand for the if-else statement.

int age = 18;


String result = (age >= 18) ? "Adult" : "Not an Adult";
System.out.println(result);

Switch Statement
Switch statements are used for multiple conditions based on a single variable.

int day = 2;
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
default:
System.out.println("Other day");
break;

Java Notes 4
}

Need for Loop


Loops are used to execute a block of code repeatedly.

While Loop
Executes a block of code as long as a condition is true.

int i = 0;
while (i < 5) {
System.out.println(i);
i++;
}

Do-While Loop
Executes a block of code at least once, then repeatedly as long as a condition is true.

int i = 0;
do {
System.out.println(i);
i++;
} while (i < 5);

For Loop
Executes a block of code a specific number of times.

for (int i = 0; i < 5; i++) {


System.out.println(i);
}

Which Loop to Use


For Loop: When the number of iterations is known.

While Loop: When the number of iterations is not known and depends on a condition.

Do-While Loop: When the loop needs to run at least once regardless of the condition.

Class and Object Theory

Java Notes 5
In Java, a class is a blueprint for creating objects (a particular data structure), providing initial
values for state (member fields or attributes), and implementations of behavior (member functions
or methods). An object is an instance of a class.

Class Example:

public class Car {


// Attributes
String color;
String model;
int year;

// Constructor
public Car(String color, String model, int year) {
this.color = color;
this.model = model;
this.year = year;
}

// Method
public void displayDetails() {
System.out.println("Color: " + color + ", Model: " + model + ", Yea
r: " + year);
}
}

Object Example:

public class Main {


public static void main(String[] args) {
Car car1 = new Car("Red", "Tesla Model S", 2020);
car1.displayDetails(); // Output: Color: Red, Model: Tesla Model S,
Year: 2020
}
}

Class and Object Practical


Creating and using objects:

public class Main {


public static void main(String[] args) {
// Creating objects
Car car1 = new Car("Red", "Tesla Model S", 2020);

Java Notes 6
Car car2 = new Car("Blue", "Ford Mustang", 1969);

// Using object methods


car1.displayDetails(); // Output: Color: Red, Model: Tesla Model S,
Year: 2020
car2.displayDetails(); // Output: Color: Blue, Model: Ford Mustang,
Year: 1969
}
}

JDK, JRE, JVM


JDK (Java Development Kit): A software development kit used to develop Java applications. It
includes JRE, an interpreter/loader (Java), a compiler (javac), an archiver (jar), a documentation
generator (Javadoc), and other tools needed for Java development.

JRE (Java Runtime Environment): Provides libraries, Java Virtual Machine (JVM), and other
components to run applications written in Java. It does not contain tools for Java development.

JVM (Java Virtual Machine): An abstract machine that enables your computer to run a Java
program. It converts Java bytecode into machine language.

Methods
Methods in Java are blocks of code that perform a specific task. They are used to define the
behavior of objects created from a class.

public class Calculator {


// Method to add two numbers
public int add(int a, int b) {
return a + b;
}
}

Method Overloading
Method overloading allows a class to have more than one method with the same name, as long as
their parameter lists are different.

public class Calculator {


public int add(int a, int b) {
return a + b;
}

public double add(double a, double b) {


return a + b;

Java Notes 7
}

public int add(int a, int b, int c) {


return a + b + c;
}
}

Stack and Heap


Stack: Stores primitive data types and references to objects. Each thread has its own stack.

Heap: Stores objects and class instances. It is a shared memory area used by all threads.

Need of an Array
Arrays store multiple values of the same type in a single variable, allowing efficient storage and
retrieval of data.

Creation of Array

int[] numbers = new int[5]; // Array of integers with 5 elements


numbers[0] = 10; // Assigning value to the first element

Multi-Dimensional Array

int[][] matrix = new int[3][3]; // 2D array with 3 rows and 3 columns


matrix[0][0] = 1; // Assigning value to the first element

Jagged and 3D Array


Jagged Array:

int[][] jaggedArray = new int[3][];


jaggedArray[0] = new int[2];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[3];

3D Array:

int[][][] threeDArray = new int[2][3][4]; // 3D array with dimensions 2x3x4

Java Notes 8
Drawbacks of Array
Fixed size: Once declared, the size of the array cannot be changed.

Homogeneous: All elements must be of the same type.

No built-in methods for common operations like searching or sorting.

Array of Objects

class Student {
String name;
int age;

Student(String name, int age) {


this.name = name;
this.age = age;
}
}

public class Main {


public static void main(String[] args) {
Student[] students = new Student[3];
students[0] = new Student("Alice", 20);
students[1] = new Student("Bob", 22);
students[2] = new Student("Charlie", 21);

for (Student student : students) {


System.out.println(student.name + " is " + student.age + " year
s old.");
}
}
}

Enhanced For Loop


Enhanced for loop (for-each loop) is used to traverse arrays or collections.

int[] numbers = {1, 2, 3, 4, 5};


for (int num : numbers) {
System.out.println(num);
}

What is String
A string is a sequence of characters. In Java, strings are objects of the String class.

Java Notes 9
String greeting = "Hello, World!";

Mutable vs Immutable String


Immutable String: Strings in Java are immutable, meaning once a String object is created, it
cannot be changed.

String str = "Hello";


str = str.concat(" World"); // str now refers to "Hello World", original "H
ello" remains unchanged

Mutable String: StringBuffer and StringBuilder are used to create mutable strings.

StringBuffer and StringBuilder


StringBuffer: Thread-safe and synchronized, but slower.

StringBuilder: Not thread-safe, but faster.

StringBuffer Example:

StringBuffer sb = new StringBuffer("Hello");


sb.append(" World");
System.out.println(sb); // Output: Hello World

StringBuilder Example:

StringBuilder sb = new StringBuilder("Hello");


sb.append(" World");
System.out.println(sb); // Output: Hello World

Static Variable
A static variable is a class-level variable that is shared among all instances of the class. It is
declared using the static keyword.

public class Counter {


static int count = 0;

Counter() {

Java Notes 10
count++;
}

public static void main(String[] args) {


Counter c1 = new Counter();
Counter c2 = new Counter();
System.out.println(Counter.count); // Output: 2
}
}

Static Block
A static block is used to initialize static variables. It runs only once when the class is loaded into
memory.

public class StaticBlockExample {


static int data;

static {
data = 50;
System.out.println("Static block executed.");
}

public static void main(String[] args) {


System.out.println("Value of data: " + data);
}
}

Static Method
A static method belongs to the class rather than any instance. It can be called without creating an
instance of the class.

public class Utility {


public static int add(int a, int b) {
return a + b;
}

public static void main(String[] args) {


int sum = Utility.add(5, 10);
System.out.println("Sum: " + sum); // Output: Sum: 15
}
}

Java Notes 11
Encapsulation
Encapsulation is the process of wrapping data (variables) and code (methods) together into a
single unit called a class. It restricts direct access to some of an object's components.

public class EncapsulationExample {


private int age;

public int getAge() {


return age;
}

public void setAge(int age) {


if (age > 0) {
this.age = age;
}
}
}

Getters and Setters


Getters and setters are methods used to access and update the private variables of a class.

public class Person {


private String name;

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}
}

this Keyword
The this keyword refers to the current instance of the class. It can be used to refer to instance
variables, methods, and constructors.

public class Example {


private int x;

public Example(int x) {

Java Notes 12
this.x = x; // Refers to the instance variable
}

public void display() {


System.out.println("Value of x: " + this.x);
}
}

Constructor
A constructor is a special method that is called when an object is instantiated. It initializes the
object.

public class ConstructorExample {


private String name;

public ConstructorExample(String name) {


this.name = name;
}

public void display() {


System.out.println("Name: " + name);
}
}

Default vs Parameterized Constructor


Default Constructor: A constructor with no parameters.

Parameterized Constructor: A constructor with parameters.

Default Constructor:

public class DefaultConstructor {


public DefaultConstructor() {
System.out.println("Default Constructor called");
}
}

Parameterized Constructor:

public class ParameterizedConstructor {


private String name;

Java Notes 13
public ParameterizedConstructor(String name) {
this.name = name;
}
}

this and super Method


this Method: Refers to the current class instance variable, method, or constructor.

super Method: Refers to the parent class instance variable, method, or constructor.

class Parent {
String name = "Parent";

void display() {
System.out.println("Parent class method");
}
}

class Child extends Parent {


String name = "Child";

void display() {
System.out.println("Child class method");
}

void show() {
System.out.println(super.name); // Refers to Parent class variable
super.display(); // Calls Parent class method
System.out.println(this.name); // Refers to Child class variable
this.display(); // Calls Child class method
}
}

Naming Convention
Class Names: PascalCase (e.g., MyClass )

Method Names: camelCase (e.g., myMethod )

Variable Names: camelCase (e.g., myVariable )

Constant Names: UPPER_CASE (e.g., MY_CONSTANT )

Anonymous Object
An anonymous object is an instance of a class without storing its reference in a variable. It is used
only once.

Java Notes 14
new Example().display();

Need of Inheritance
Inheritance promotes code reusability by allowing new classes to inherit properties and methods
from existing classes. It also helps in achieving runtime polymorphism.

What is Inheritance
Inheritance is a mechanism in which one class acquires the properties (fields) and behaviors
(methods) of another class. The class which inherits is called the subclass (child class) and the
class being inherited from is called the superclass (parent class).

class Animal {
void eat() {
System.out.println("Eating...");
}
}

class Dog extends Animal {


void bark() {
System.out.println("Barking...");
}
}

Single and Multilevel Inheritance


Single Inheritance: A subclass inherits from one superclass.

class Animal {
void eat() {
System.out.println("Eating...");
}
}

class Dog extends Animal {


void bark() {
System.out.println("Barking...");
}
}

Java Notes 15
Multilevel Inheritance: A class is derived from another class, which is also derived from
another class.

class Animal {
void eat() {
System.out.println("Eating...");
}
}

class Dog extends Animal {


void bark() {
System.out.println("Barking...");
}
}

class Puppy extends Dog {


void weep() {
System.out.println("Weeping...");
}
}

Multiple Inheritance
Java does not support multiple inheritance (a class inheriting from more than one class) directly
due to ambiguity issues, but it can be achieved through interfaces.

interface Printable {
void print();
}

interface Showable {
void show();
}

class A implements Printable, Showable {


public void print() {
System.out.println("Printing...");
}

public void show() {


System.out.println("Showing...");
}
}

Java Notes 16
Method Overriding
Method overriding occurs when a subclass provides a specific implementation of a method already
defined in its superclass. The method in the subclass should have the same name, return type, and
parameters as the method in the superclass.

class Animal {
void eat() {
System.out.println("Eating...");
}
}

class Dog extends Animal {


void eat() {
System.out.println("Eating dog food...");
}
}

public class Main {


public static void main(String[] args) {
Dog d = new Dog();
d.eat(); // Output: Eating dog food...
}
}

Packages
Packages are used to group related classes and interfaces together. They help in organizing code
and avoiding name conflicts.

Creating a Package:

package com.example;

public class MyClass {


public void display() {
System.out.println("Hello from MyClass");
}
}

Using a Package:

import com.example.MyClass;

public class Main {

Java Notes 17
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.display();
}
}

Access Modifiers
Access modifiers determine the visibility of classes, methods, and variables. Java has four access
modifiers:

1. public: Accessible from any other class.

2. protected: Accessible within the same package and subclasses.

3. default (no modifier): Accessible only within the same package.

4. private: Accessible only within the same class.

public class Example {


public int publicVar;
protected int protectedVar;
int defaultVar;
private int privateVar;
}

Polymorphism
Polymorphism allows methods to do different things based on the object it is acting upon, even
though the method name remains the same. It is achieved through method overloading and method
overriding.

Method Overloading: Same method name with different parameters.

public class MathUtils {


public int add(int a, int b) {
return a + b;
}

public double add(double a, double b) {


return a + b;
}
}

Method Overriding: Subclass method overrides the superclass method.

Java Notes 18
class Animal {
void makeSound() {
System.out.println("Animal sound");
}
}

class Dog extends Animal {


@Override
void makeSound() {
System.out.println("Bark");
}
}

Dynamic Method Dispatch


Dynamic method dispatch is a mechanism by which a call to an overridden method is resolved at
runtime rather than compile-time. It allows Java to support runtime polymorphism.

class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog extends Animal {


void sound() {
System.out.println("Dog barks");
}
}

class Cat extends Animal {


void sound() {
System.out.println("Cat meows");
}
}

public class Main {


public static void main(String[] args) {
Animal a;
a = new Dog();
a.sound(); // Dog barks
a = new Cat();
a.sound(); // Cat meows
}

Java Notes 19
}

Final Keyword
The final keyword can be used with variables, methods, and classes to indicate that they cannot
be changed, overridden, or inherited.

// Final variable
final int MAX_VALUE = 100;

// Final method
class A {
final void display() {
System.out.println("This is a final method.");
}
}

// Final class
final class B {
// Class definition
}

Object Class equals , toString , hashCode


equals Method: Checks if two objects are equal.

toString Method: Returns a string representation of the object.

hashCode Method: Returns the hash code value for the object.

public class Example {


private int id;
private String name;

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Example example = (Example) obj;
return id == example.id && Objects.equals(name, example.name);
}

@Override
public int hashCode() {
return Objects.hash(id, name);

Java Notes 20
}

@Override
public String toString() {
return "Example{id=" + id + ", name='" + name + "'}";
}
}

Upcasting and Downcasting


Upcasting: Casting a subclass object to a superclass reference.

Downcasting: Casting a superclass reference back to a subclass reference.

class Animal {
void makeSound() {
System.out.println("Animal sound");
}
}

class Dog extends Animal {


void makeSound() {
System.out.println("Bark");
}
}

public class Main {


public static void main(String[] args) {
Animal a = new Dog(); // Upcasting
a.makeSound(); // Bark

Dog d = (Dog) a; // Downcasting


d.makeSound(); // Bark
}
}

abstract Keyword
The abstract keyword is used to declare abstract classes and methods. Abstract classes cannot be
instantiated and abstract methods must be implemented by subclasses.

abstract class Animal {


abstract void makeSound();

void sleep() {

Java Notes 21
System.out.println("Sleeping...");
}
}

class Dog extends Animal {


void makeSound() {
System.out.println("Bark");
}
}

Inner Class
An inner class is a class defined within another class. It can access all the members of the outer
class.

public class OuterClass {


private int data = 10;

class InnerClass {
void display() {
System.out.println("Data: " + data);
}
}
}

Anonymous Inner Class


An anonymous inner class is a class without a name and is used to instantiate objects with certain
"extras" or modifications for methods of a class.

abstract class Person {


abstract void display();
}

public class Main {


public static void main(String[] args) {
Person p = new Person() {
void display() {
System.out.println("Anonymous Inner Class");
}
};
p.display();
}

Java Notes 22
}

Abstract and Anonymous Inner Class


An abstract class can be instantiated using an anonymous inner class to provide the
implementation of abstract methods.

abstract class Animal {


abstract void makeSound();
}

public class Main {


public static void main(String[] args) {
Animal a = new Animal() {
void makeSound() {
System.out.println("Anonymous Inner Class Implementation");
}
};
a.makeSound();
}
}

What is Interface
An interface is a reference type in Java, similar to a class, that can contain only constants, method
signatures, default methods, static methods, and nested types. Methods in interfaces are abstract
by default.

interface Animal {
void eat();
void travel();
}

More on Interfaces
Implementing an Interface: A class uses the implements keyword to implement an interface.

class Dog implements Animal {


public void eat() {
System.out.println("Dog eats");
}

Java Notes 23
public void travel() {
System.out.println("Dog travels");
}
}

Default Methods: Interfaces can have default methods with implementations.

interface Animal {
void eat();
default void travel() {
System.out.println("Animal travels");
}
}

Static Methods: Interfaces can have static methods.

interface Animal {
static void description() {
System.out.println("Animal interface");
}
}

Need of Interface
Interfaces provide a way to achieve abstraction and multiple inheritance in Java. They allow
different classes to implement the same set of methods, ensuring a contract for the classes.

What is Enum
An enum (short for "enumeration") is a special data type that enables a variable to be a set of
predefined constants.

enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

Enum in if and switch


Enums can be used in if and switch statements for control flow.

public class EnumExample {

Java Notes 24
enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}

public static void main(String[] args) {


Day today = Day.FRIDAY;

// Using if statement
if (today == Day.FRIDAY) {
System.out.println("It's Friday!");
}

// Using switch statement


switch (today) {
case MONDAY:
System.out.println("It's Monday!");
break;
case FRIDAY:
System.out.println("It's Friday!");
break;
default:
System.out.println("It's another day!");
}
}
}

Enum Class
The enum class in Java can have fields, constructors, and methods.

enum Day {
SUNDAY("Weekend"), MONDAY("Weekday"), TUESDAY("Weekday"),
WEDNESDAY("Weekday"), THURSDAY("Weekday"), FRIDAY("Weekday"),
SATURDAY("Weekend");

private String description;

Day(String description) {
this.description = description;
}

public String getDescription() {


return description;
}
}

Java Notes 25
public class Main {
public static void main(String[] args) {
for (Day day : Day.values()) {
System.out.println(day + ": " + day.getDescription());
}
}
}

What is Annotation
Annotations provide metadata about the program and are used to give information to the compiler,
to be used by the JVM, or for other tools. They do not directly affect the execution of the code.
Example:

public class Example {


@Override
public String toString() {
return "Example class";
}
}

Functional Interface
A functional interface is an interface with exactly one abstract method. They can contain multiple
default or static methods. Functional interfaces are used with lambda expressions.

Example:

@FunctionalInterface
interface MyFunctionalInterface {
void execute();
}

Lambda Expression
Lambda expressions provide a clear and concise way to implement a functional interface using an
expression.

Syntax:

(parameters) -> expression

Example:

Java Notes 26
MyFunctionalInterface myFunc = () -> System.out.println("Hello, Lambda!");
myFunc.execute();

Lambda Expression with Return


Lambda expressions can also return values.
Example:

@FunctionalInterface
interface Addable {
int add(int a, int b);
}

public class Main {


public static void main(String[] args) {
Addable adder = (a, b) -> a + b;
System.out.println(adder.add(10, 20)); // Output: 30
}
}

Types of Interface
Marker Interface: No methods, used to mark a class (e.g., Serializable ).

Functional Interface: One abstract method (e.g., Runnable , Callable ).

Normal Interface: Multiple abstract methods.

What is Exception
An exception is an event that disrupts the normal flow of the program. It is an object which is
thrown at runtime.

Exception Handling using try catch


Exception handling is used to handle runtime errors so that the normal flow of the application can
be maintained.
Example:

public class Example {


public static void main(String[] args) {
try {
int data = 100 / 0;
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero.");

Java Notes 27
}
}
}

try with Multiple catch


You can have multiple catch blocks to handle different types of exceptions.
Example:

public class Example {


public static void main(String[] args) {
try {
int data = 100 / 0;
} catch (ArithmeticException e) {
System.out.println("Arithmetic Exception: Cannot divide by zer
o.");
} catch (Exception e) {
System.out.println("General Exception");
}
}
}

Exception Hierarchy
Java exceptions are hierarchical and are divided into two categories:

Checked Exceptions: Exceptions that are checked at compile time.

Unchecked Exceptions: Exceptions that are not checked at compile time (Runtime exceptions).

Hierarchy:

luaCopy code
Throwable
|-- Exception
| |-- IOException
| |-- SQLException
| `-- RuntimeException
| |-- ArithmeticException
| `-- NullPointerException
`-- Error

Exception throw Keyword


The throw keyword is used to explicitly throw an exception.

Example:

Java Notes 28
public class Example {
static void checkAge(int age) {
if (age < 18) {
throw new ArithmeticException("Not eligible for voting.");
} else {
System.out.println("Eligible for voting.");
}
}

public static void main(String[] args) {


checkAge(15);
}
}

Custom Exception
You can create your own exceptions by extending the Exception class.

Example:

class MyException extends Exception {


public MyException(String message) {
super(message);
}
}

public class Main {


public static void main(String[] args) {
try {
throw new MyException("Custom exception occurred");
} catch (MyException e) {
System.out.println(e.getMessage());
}
}
}

Ducking Exception using throws


The throws keyword is used to declare an exception in the method signature, indicating that the
method might throw that exception.
Example:

public class Example {

Java Notes 29
static void checkAge(int age) throws MyException {
if (age < 18) {
throw new MyException("Not eligible for voting.");
} else {
System.out.println("Eligible for voting.");
}
}

public static void main(String[] args) {


try {
checkAge(15);
} catch (MyException e) {
System.out.println(e.getMessage());
}
}
}

User Input using BufferedReader and Scanner


BufferedReader:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Example {


public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(Sy
stem.in));
System.out.print("Enter your name: ");
String name = reader.readLine();
System.out.println("Hello, " + name);
}
}

Scanner:

import java.util.Scanner;

public class Example {


public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();

Java Notes 30
System.out.println("Hello, " + name);
scanner.close();
}
}

try with Resources


The try -with-resources statement is used to automatically close resources when they are no
longer needed. This ensures that the resources are closed properly.
Example:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Example {


public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("fil
e.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Threads
A thread is a lightweight sub-process, the smallest unit of processing. It is a separate path of
execution and can run concurrently with other threads. In Java, you can create a thread by
extending the Thread class or implementing the Runnable interface.

Example (Extending Thread):

public class MyThread extends Thread {


public void run() {
System.out.println("Thread is running");
}

public static void main(String[] args) {


MyThread t1 = new MyThread();
t1.start();

Java Notes 31
}
}

Example (Implementing Runnable):

public class MyRunnable implements Runnable {


public void run() {
System.out.println("Thread is running");
}

public static void main(String[] args) {


Thread t1 = new Thread(new MyRunnable());
t1.start();
}
}

Multiple Threads
You can create and run multiple threads in Java to perform multiple tasks concurrently.

Example:

public class MultiThread extends Thread {


public void run() {
System.out.println(Thread.currentThread().getName() + " is runnin
g");
}

public static void main(String[] args) {


MultiThread t1 = new MultiThread();
MultiThread t2 = new MultiThread();
t1.start();
t2.start();
}
}

Thread Priority and Sleep


Thread Priority: Determines the relative priority of threads. A higher priority thread gets more
CPU time.

Thread Sleep: Puts the thread to sleep for a specified period.

Example:

Java Notes 32
public class ThreadPrioritySleep extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(Thread.currentThread().getName() + " - " +
i);
}
}

public static void main(String[] args) {


ThreadPrioritySleep t1 = new ThreadPrioritySleep();
ThreadPrioritySleep t2 = new ThreadPrioritySleep();
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}

Runnable vs Thread
Runnable: Implements Runnable interface. Preferred way as it allows multiple inheritance.

Thread: Extends Thread class. Suitable when you want to override other Thread methods.

Race Condition
A race condition occurs when two or more threads can access shared data and try to change it at
the same time. This leads to inconsistent results.
Example:

class Counter {
private int count = 0;

public void increment() {


count++;
}

public int getCount() {


return count;
}
}

Java Notes 33
public class RaceCondition {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Runnable task = () -> {
for (int i = 0; i < 1000; i++) {
counter.increment();
}
};

Thread t1 = new Thread(task);


Thread t2 = new Thread(task);

t1.start();
t2.start();

t1.join();
t2.join();

System.out.println("Final count: " + counter.getCount());


}
}

Thread States
A thread can be in one of the following states:

NEW: The thread is created but not yet started.

RUNNABLE: The thread is ready to run and is waiting for CPU time.

BLOCKED: The thread is blocked waiting for a monitor lock.

WAITING: The thread is waiting indefinitely for another thread to perform a particular action.

TIMED_WAITING: The thread is waiting for another thread to perform a specific action for up to
a specified waiting time.

TERMINATED: The thread has completed execution.

Collection API
The Collection API is a framework that provides architecture to store and manipulate a group of
objects. It includes interfaces and classes like List , Set , Map , ArrayList , HashSet , and HashMap .

ArrayList
ArrayListis a resizable array implementation of the List interface. It allows duplicate elements and
maintains insertion order.

Example:

Java Notes 34
import java.util.ArrayList;

public class ArrayListExample {


public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");

for (String fruit : list) {


System.out.println(fruit);
}
}
}

Set
Set is an unordered collection that does not allow duplicate elements. HashSet is a commonly used
implementation.
Example:

import java.util.HashSet;
import java.util.Set;

public class SetExample {


public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
set.add("Apple"); // Duplicate

for (String fruit : set) {


System.out.println(fruit);
}
}
}

Map
Map is an object that maps keys to values. A Map cannot contain duplicate keys.

Example:

Java Notes 35
import java.util.HashMap;
import java.util.Map;

public class MapExample {


public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);

for (Map.Entry<String, Integer> entry : map.entrySet()) {


System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}

Comparator vs Comparable
Comparable: Used to define the natural order of objects (single sorting sequence).

Comparator: Used to define multiple sorting sequences.

Comparable Example:

import java.util.*;

class Student implements Comparable<Student> {


String name;
int age;

Student(String name, int age) {


this.name = name;
this.age = age;
}

public int compareTo(Student s) {


return this.age - s.age;
}
}

public class ComparableExample {


public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 22));
students.add(new Student("Bob", 20));
students.add(new Student("Charlie", 21));

Java Notes 36
Collections.sort(students);

for (Student s : students) {


System.out.println(s.name + " - " + s.age);
}
}
}

Comparator Example:

import java.util.*;

class Student {
String name;
int age;

Student(String name, int age) {


this.name = name;
this.age = age;
}
}

class NameComparator implements Comparator<Student> {


public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
}

public class ComparatorExample {


public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 22));
students.add(new Student("Bob", 20));
students.add(new Student("Charlie", 21));

Collections.sort(students, new NameComparator());

for (Student s : students) {


System.out.println(s.name + " - " + s.age);
}
}
}

Need of Stream API

Java Notes 37
The Stream API was introduced in Java 8 to process collections of objects in a functional
programming style. It provides methods for filtering, mapping, and reducing, allowing for more
concise and readable code.

forEach Method
The forEach method is used to iterate over elements of a collection.

Example:

import java.util.Arrays;
import java.util.List;

public class ForEachExample {


public static void main(String[] args) {
List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
list.forEach(fruit -> System.out.println(fruit));
}
}

Stream API
The Stream API is used to process collections of objects. A stream is a sequence of elements
supporting sequential and parallel aggregate operations.
Example:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {


public static void main(String[] args) {
List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
List<String> result = list.stream()
.filter(fruit -> fruit.startsWith("A"))
.collect(Collectors.toList());
result.forEach(System.out::println); // Output: Apple
}
}

Map Filter Reduce Sorted


Map: Transforms each element of the stream.

Java Notes 38
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class MapExample {


public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squaredNumbers = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList
());
squaredNumbers.forEach(System.out::println); // Output: 1, 4, 9, 1
6, 25
}
}

Filter: Selects elements based on a condition.

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FilterExample {


public static void main(String[] args) {
List<String> list = Arrays.asList("Apple", "Banana", "Cherry");
List<String> result = list.stream()
.filter(fruit -> fruit.startsWith("A"))
.collect(Collectors.toList());
result.forEach(System.out::println); // Output: Apple
}
}

Reduce: Aggregates stream elements to a single value.

import java.util.Arrays;
import java.util.List;

public class ReduceExample {


public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, (a, b) -> a + b);

Java Notes 39
System.out.println(sum); // Output: 15
}
}

Sorted: Returns a stream with elements sorted.

import java.util.Arrays;
import java.util.List;

public class SortedExample {


public static void main(String[] args) {
List<String> list = Arrays.asList("Banana", "Apple", "Cherry");
list.stream()
.sorted()
.forEach(System.out::println); // Output: Apple, Banana, Cherry
}
}

These notes provide an overview of threads, collections, and the Stream API in Java. Let me know
if you need more details or additional examples!

Java Notes 40

You might also like