Java

Introduction to Java 

Setting Up Java Development Environment:


Writing Your First Java Program:

Create a simple "Hello, World!" program to verify your setup:

public class HelloWorld {

public static void main(String[] args) {

    System.out.println("Hello, World!");

}

}

Compile and run the program using the following commands in your terminal or command prompt:

javac HelloWorld.java

java HelloWorld

You should see the output: Hello, World!

Java Basics:

Variables and Data Types:


int age = 25;

double price = 19.99;

String name = "John";

boolean isStudent = true;

Operators:

Java provides arithmetic, assignment, comparison, logical, and bitwise operators for performing different kinds of operations on variables and values.


int x = 10 + 5;

int y = 10 - 5;

int z = 10 * 5;

int quotient = 10 / 5;

int remainder = 10 % 3;

Control Flow Statements:

Control flow statements, such as if, else, for, while, do-while, control the flow of execution in a program based on specified conditions.

int num = 10;

if (num > 0) {

System.out.println("Positive");

} else if (num < 0) {

System.out.println("Negative");

} else {

System.out.println("Zero");

}

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

System.out.println(i);

}

while (num > 0) {

System.out.println(num);

num--;

}

Arrays:

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

String[] names = new String[3];

names[0] = "John";

names[1] = "Alice";

names[2] = "Bob";

Object-Oriented Programming (OOP) Concepts:

Classes and Objects:

public class Car {

String brand;

String model;

int year;

public void drive() {

   System.out.println("Driving...");

}

}

public class Main {

public static void main(String[] args) {

   Car myCar = new Car();

   myCar.brand = "Toyota";

   myCar.model = "Camry";

   myCar.year = 2020;

   myCar.drive();

}

}

Encapsulation

Encapsulate fields within a class using access modifiers (private, protected, public) and provide public getter and setter methods to access and modify the fields.

Inheritance:

public class Animal {

public void sound() {

  System.out.println("Animal makes a sound");

}

}

public class Dog extends Animal {

@Override

public void sound() {

  System.out.println("Dog barks");

}

}

Polymorphism:

Animal myDog = new Dog();

myDog.sound(); // Output: Dog barks

Abstraction in Java:

Abstract classes and interfaces allow you to define common behavior without specifying implementation details. Abstract classes may contain abstract methods (without implementation), while interfaces declare method signatures without implementations.

// Abstract class

public abstract class Animal {


  // Abstract method (no implementation)

public abstract void sound();


// concrete method

public void sleep() {

  System.out.println("The animal is sleeping ZZZZZ....");

}

}


// Concrete subclass

public class Dog extends Animal {


  // Implementing abstract method

@Override

public void sound() {

  System.out.println("Dog barks");

}

}


public class Main {

public static void main(String[] args) {

  // create an instance of Dog

  Dog dog = new Dog();


  // call methods

  dog.sound()

  dog.sleep() 

}

}

Interface 

// Abstract class

public interface Animal {


  // Abstract method (no implementation)

public void sound();


// concrete method

public default void sleep() {

  System.out.println("ZZZZZ....");

}

}


// Concrete subclass

public class Dog extends Animal {


  // Implementing abstract method

@Override

public void sound() {

  System.out.println("Dog barks");

}

}


public class Main {

public static void main(String[] args) {

  // create an instance of Dog

  Dog dog = new Dog();


  // call methods

  dog.sound()

  dog.sleep() 

}

}

In general:


Advanced to Java

Chapter 1: Advanced Object-Oriented Programming (OOP)


class Vehicle {

void start() {

  System.out.println("Vehicle started");

}

}


class Car extends Vehicle {

void start() {

  System.out.println("Car started");

}

}


class Bicycle extends Vehicle {

// No need to override start() method

}


public class InheritanceExample {

public static void main(String[] args) {

  Vehicle vehicle = new Car();

  vehicle.start(); // Output: Car started

}

}


Chapter 2: Generics

Introduction to Generic

class Box<T> {

private T item;

public void setItem(T item) {

  this.item = item;

}


public T getItem() {

  return item;

}

}


public class GenericsExample {

public static void main(String[] args) {

   Box<Integer> integerBox = new Box<>();

   integerBox.setItem(10);

   System.out.println("Item: " + integerBox.getItem()); // Output: Item: 10

}

}


Generic Classes and Methods


public class Utils {

public static <T> T max(T[] array) {

  T max = array[0];

  for (T item : array) {

  if (item.compareTo(max) > 0) {

  max = item;

}

}

  return max;

}

}


public class GenericMethodsExample {

public static void main(String[] args) {

  Integer[] numbers = {1, 5, 3, 7, 2};

    String[] names = {"John", "Alice", "Bob"};

  System.out.println("Max number: " + Utils.max(numbers)); // Output: Max number: 7

  System.out.println("Max name: " + Utils.max(names)); // Output: Max name: John

}

}


Type Erasure and Bounded Type Parameters


class BoundedList<T extends Comparable<T>> {

private List<T> list = new ArrayList<>();

public void add(T item) {

  list.add(item);

}

public T max() {

  return Collections.max(list);

}

}

public class BoundedTypeParametersExample {

public static void main(String[] args) {

  BoundedList<Integer> numbers = new BoundedList<>();

  numbers.add(10);

  numbers.add(5);

  System.out.println("Max number: " + numbers.max()); // Output: Max number: 10

}

}


Chapter 3: Collections Framework

Lists, Sets, Maps


import java.util.*;

public class CollectionsExample {

public static void main(String[] args) {

// List example

  List<String> list = new ArrayList<>();

  list.add("Java");

  list.add("Python");

  list.add("C++");

// Set example

  Set<Integer> set = new HashSet<>();

  set.add(10);

  set.add(20);

  set.add(30);

// Map example

  Map<String, Integer> map = new HashMap<>();

  map.put("One", 1);

  map.put("Two", 2);

  map.put("Three", 3);

  System.out.println("List: " + list);

  System.out.println("Set: " + set);

  System.out.println("Map: " + map);

}

}

Sorting and Searching

import java.util.*;

public class SortingSearchingExample {

public static void main(String[] args) {

   // Sorting example

  List<Integer> numbers = Arrays.asList(3, 1, 5, 2, 4);

  Collections.sort(numbers);

  System.out.println("Sorted numbers: " + numbers); // Output: Sorted numbers: [1, 2, 3, 4, 5]

  // Searching example

  int index = Collections.binarySearch(numbers, 3);

  System.out.println("Index of 3: " + index); // Output: Index of 3: 2

}

}

Collection Utilities

import java.util.*;

public class CollectionUtilitiesExample {

public static void main(String[] args) {

  // Sorting example

  List<Integer> numbers = Arrays.asList(3, 1, 5, 2, 4);

  Collections.sort(numbers);

  System.out.println("Sorted numbers: " + numbers); // Output: Sorted numbers: [1, 2, 3, 4, 5]

  // Shuffling example

  Collections.shuffle(numbers);

  System.out.println("Shuffled numbers: " + numbers);

  // Converting array to list

  Integer[] array = {1, 2, 3};

  List<Integer> list = Arrays.asList(array);

  System.out.println("List from array: " + list);

}

}

Chapter 4: Concurrency (Multithreading) 

Creating Thread

class MyThread extends Thread {

   public void run() {

       System.out.println("Thread running");

   }

}


public class ConcurrencyExample {

   public static void main(String[] args) {

       MyThread thread = new MyThread();

       thread.start();

   }

}


Synchronization

class Counter {

   private int count;


   public synchronized void increment() {

       count++;

   }


   public synchronized int getCount() {

       return count;

   }

}


public class SynchronizationExample {

   public static void main(String[] args) {

       Counter counter = new Counter();


       Thread t1 = new Thread(() -> {

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

               counter.increment();

           }

       });


       Thread t2 = new Thread(() -> {

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

               counter.increment();

           }

       });


       t1.start();

       t2.start();


       try {

           t1.join();

           t2.join();

       } catch (InterruptedException e) {

           e.printStackTrace();

       }


       System.out.println("Count: " + counter.getCount()); // Output: Count: 2000

   }

}


Thread Pools

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;


public class ThreadPoolExample {

   public static void main(String[] args) {

       ExecutorService executor = Executors.newFixedThreadPool(5);

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

           Runnable worker = new WorkerThread("Task-" + i);

           executor.execute(worker);

       }

       executor.shutdown();

       while (!executor.isTerminated()) {

       }

       System.out.println("All tasks completed");

   }

}


class WorkerThread implements Runnable {

   private String taskName;


   public WorkerThread(String taskName) {

       this.taskName = taskName;

   }


   @Override

   public void run() {

       System.out.println(Thread.currentThread().getName() + " (Start) taskName = " + taskName);

       processTask();

       System.out.println(Thread.currentThread().getName() + " (End)");

   }


   private void processTask() {

       try {

           Thread.sleep(2000);

       } catch (InterruptedException e) {

           e.printStackTrace();

       }

   }

}

Chapter 5: I/O Streams

Reading and Writing Files

import java.io.*;


public class FileHandlingExample {

   public static void main(String[] args) {

       try {

           // Writing to a file

           FileWriter writer = new FileWriter("output.txt");

           writer.write("Hello, World!");

           writer.close();


           // Reading from a file

           FileReader reader = new FileReader("output.txt");

           int data;

           while ((data = reader.read()) != -1) {

               System.out.print((char) data);

           }

           reader.close();

       } catch (IOException e) {

           System.out.println("Error: " + e.getMessage());

       }

   }

}

File Operations

import java.io.*;


public class FileOperationsExample {

   public static void main(String[] args) {

       File file = new File("data.txt");


       // Check if file exists

       if (file.exists()) {

           System.out.println("File exists");


           // Delete file

           if (file.delete()) {

               System.out.println("File deleted successfully");

           } else {

               System.out.println("Failed to delete file");

           }

       } else {

           System.out.println("File does not exist");

       }

   }

}

Chapter 6: Exceptions and Error Handling

Handling Exceptions

public class ExceptionHandlingExample {

   public static void main(String[] args) {

       try {

           int result = divide(10, 0);

           System.out.println("Result: " + result);

       } catch (ArithmeticException e) {

           System.out.println("Error: " + e.getMessage());

       }

   }


   public static int divide(int num1, int num2) {

       return num1 / num2;

   }

}

Custom Exceptions

class InvalidAgeException extends Exception {

   public InvalidAgeException(String message) {

       super(message);

   }

}


public class CustomExceptionExample {

   public static void main(String[] args) {

       try {

           validateAge(15);

       } catch (InvalidAgeException e) {

           System.out.println("Error: " + e.getMessage());

       }

   }


   public static void validateAge(int age) throws InvalidAgeException {

       if (age < 18) {

           throw new InvalidAgeException("Age must be 18 or above");

       }

   }

}

Chapter 7: Advanced Language Features

These advanced language features enhance the expressiveness, safety, and productivity of Java programming by providing powerful tools for functional programming, data manipulation, error handling, and metadata management. They enable developers to write cleaner, more concise, and more maintainable code.

// Enum definition for days of the week

public enum DayOfWeek {

   SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

}


// Using the enum

public class EnumExample {

   public static void main(String[] args) {

       // Iterating over enum values

       for (DayOfWeek day : DayOfWeek.values()) {

           System.out.println(day);

       }


       // Accessing individual enum constants

       DayOfWeek firstDay = DayOfWeek.MONDAY;

       System.out.println("First day of the week: " + firstDay);

   }

}


import java.lang.reflect.Field;

import java.lang.reflect.Method;


// Sample class for reflection

class MyClass {

   private String name;

   public int value;


   public MyClass(String name, int value) {

       this.name = name;

       this.value = value;

   }


   public void printInfo() {

       System.out.println("Name: " + name + ", Value: " + value);

   }

}


// Using reflection to inspect class members

public class ReflectionExample {

   public static void main(String[] args) throws Exception {

       // Getting class information

       Class<?> cls = MyClass.class;


       // Inspecting fields

       System.out.println("Fields:");

       for (Field field : cls.getDeclaredFields()) {

           System.out.println(field.getName() + " (" + field.getType() + ")");

       }


       // Inspecting methods

       System.out.println("\nMethods:");

       for (Method method : cls.getDeclaredMethods()) {

           System.out.println(method.getName() + " (" + method.getParameterCount() + " parameters)");

       }


       // Creating an instance dynamically

       MyClass obj = (MyClass) cls.getConstructor(String.class, int.class).newInstance("Example", 123);

       obj.printInfo();

   }

}



import java.util.ArrayList;

import java.util.List;


public class LambdaExample {

   public static void main(String[] args) {

       List<String> names = new ArrayList<>();

       names.add("Alice");

       names.add("Bob");

       names.add("Charlie");


       // Using lambda expression to iterate through the list

       names.forEach(name -> System.out.println(name));

   }

}


import java.util.Arrays;

import java.util.List;


public class StreamsExample {

   public static void main(String[] args) {

       List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);


       // Using streams to filter and sum even numbers

       int sum = numbers.stream()

                       .filter(num -> num % 2 == 0)

                       .mapToInt(num -> num * 2)

                       .sum();


       System.out.println("Sum of even numbers doubled: " + sum);

   }

}


import java.util.Optional;


public class OptionalExample {

   public static void main(String[] args) {

       String str = "Hello";


       // Creating an optional from a nullable value

       Optional<String> optionalStr = Optional.ofNullable(str);


       // Checking if the value is present and printing it

       optionalStr.ifPresent(value -> System.out.println("Value: " + value));


       // Getting the value or a default if it's not present

       String result = optionalStr.orElse("Default Value");

       System.out.println("Result: " + result);

   }

}


import java.lang.annotation.*;


@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface MethodInfo {

   String author() default "Unknown";

   String date();

   int revision() default 1;

   String comments();

}


public class AnnotationsExample {

   @MethodInfo(author = "John", date = "2024-02-20", comments = "This is a sample method")

   public static void myMethod() {

       // Method implementation

   }


   public static void main(String[] args) {

       // Retrieving annotation information

       MethodInfo methodInfo = AnnotationsExample.class.getMethod("myMethod").getAnnotation(MethodInfo.class);

       System.out.println("Author: " + methodInfo.author());

       System.out.println("Date: " + methodInfo.date());

       System.out.println("Comments: " + methodInfo.comments());

   }

}


// Functional interface with a single abstract method

@FunctionalInterface

interface MathOperation {

   int operate(int a, int b);

}


public class FunctionalInterfaceExample {

   public static void main(String[] args) {

       // Using a lambda expression to implement the functional interface

       MathOperation addOperation = (a, b) -> a + b;

       System.out.println("Addition result: " + addOperation.operate(5, 3));


       // Using a method reference to implement the functional interface

       MathOperation subtractOperation = FunctionalInterfaceExample::subtract;

       System.out.println("Subtraction result: " + subtractOperation.operate(5, 3));

   }


   // Method to be used with method reference

   public static int subtract(int a, int b) {

       return a - b;

   }

}


Chapter 8: Java Networking

import java.net.*;


public class NetworkingExample {

   public static void main(String[] args) {

       try {

           URL url = new URL("https://www.example.com");

           HttpURLConnection connection = (HttpURLConnection) url.openConnection();

           connection.setRequestMethod("GET");


           int responseCode = connection.getResponseCode();

           System.out.println("Response Code: " + responseCode);

       } catch (Exception e) {

           e.printStackTrace();

       }

   }

}

Chapter 9: Java Database Connectivity (JDBC)

Bach updates

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.SQLException;


public class BatchUpdateExample {

   public static void main(String[] args) {

       // Database connection parameters

       String url = "jdbc:mysql://localhost:3306/mydatabase";

       String username = "username";

       String password = "password";


       // SQL statements for batch update

       String[] sqlStatements = {

           "INSERT INTO users (username, email) VALUES (?, ?)",

           "UPDATE users SET email = ? WHERE username = ?",

           "DELETE FROM users WHERE username = ?"

       };


       try (

           // Establish database connection

           Connection connection = DriverManager.getConnection(url, username, password);

           // Prepare batch update statement

           PreparedStatement preparedStatement = connection.prepareStatement(sqlStatements[0]);

       ) {

           // Insert data into batch

           preparedStatement.setString(1, "user1");

           preparedStatement.setString(2, "user1@example.com");

           preparedStatement.addBatch();


           // Update data in batch

           preparedStatement.setString(1, "updated@example.com");

           preparedStatement.setString(2, "user1");

           preparedStatement.addBatch();


           // Delete data in batch

           preparedStatement.setString(1, "user2");

           preparedStatement.addBatch();


           // Execute batch update

           int[] results = preparedStatement.executeBatch();


           // Process batch update results

           for (int result : results) {

               System.out.println("Update count: " + result);

           }

       } catch (SQLException e) {

           e.printStackTrace();

       }

   }

}

Chapter 10: JavaFX GUI Programming

Example 1: Hello World

This example demonstrates a simple JavaFX application that displays a "Hello, World!" message in a window.

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;


public class HelloWorld extends Application {

   @Override

   public void start(Stage primaryStage) {

       // Create a label

       Label label = new Label("Hello, World!");


       // Create a layout pane and add the label

       StackPane root = new StackPane();

       root.getChildren().add(label);


       // Create a scene and set it on the stage

       Scene scene = new Scene(root, 300, 200);

       primaryStage.setScene(scene);


       // Set the stage title and show it

       primaryStage.setTitle("Hello World Example");

       primaryStage.show();

   }


   public static void main(String[] args) {

       launch(args);

   }

}

Example 2: Button Click

This example demonstrates how to create a button and handle its click event.

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;


public class ButtonClickExample extends Application {

   @Override

   public void start(Stage primaryStage) {

       // Create a button

       Button button = new Button("Click Me");

       // Handle button click event

       button.setOnAction(e -> System.out.println("Button clicked!"));


       // Create a layout pane and add the button

       StackPane root = new StackPane();

       root.getChildren().add(button);


       // Create a scene and set it on the stage

       Scene scene = new Scene(root, 300, 200);

       primaryStage.setScene(scene);


       // Set the stage title and show it

       primaryStage.setTitle("Button Click Example");

       primaryStage.show();

   }


   public static void main(String[] args) {

       launch(args);

   }

}

Chapter 11: Advanced Topics

Java Virtual Machine (JVM) internals involve understanding how the JVM executes Java bytecode and manages memory, threads, and resources. It includes topics such as:

Example: Exploring JVM internals using tools like jconsole, jvisualvm, analyzing memory usage, garbage collection behavior.

The Java Memory Model (JMM) defines the rules and guarantees for the behavior of shared memory in Java multithreaded programs. It specifies how changes made by one thread to shared variables are visible to other threads. Key concepts include:

Example: Understanding memory visibility issues, race conditions, and synchronization guarantees provided by the Java Memory Model.

Performance optimization in Java involves identifying and addressing bottlenecks to improve the speed, efficiency, and scalability of Java applications. Techniques include:

Example: Profiling Java applications, identifying performance bottlenecks, tuning JVM parameters, and optimizing code for better performance.

Example: Garbage Collection Tuning

// JVM options for garbage collection tuning

-Xms512m // Initial heap size

-Xmx2048m // Maximum heap size

-XX:NewSize=128m // Initial size of the young generation

-XX:MaxNewSize=256m // Maximum size of the young generation

-XX:SurvivorRatio=8 // Ratio of eden/survivor space size

-XX:MaxTenuringThreshold=15 // Maximum tenuring threshold for objects in the young generation

-XX:+UseConcMarkSweepGC // Use Concurrent Mark Sweep (CMS) garbage collector

-XX:+UseParNewGC // Use parallel young generation collector

-XX:+CMSParallelRemarkEnabled // Enable parallel remark phase in CMS


Example: Synchronization and Volatile Variables

public class Counter {

   private volatile int count;


   public synchronized void increment() {

       count++;

   }


   public int getCount() {

       return count;

   }

}


Example: Concurrent Data Structures

import java.util.concurrent.ConcurrentHashMap;


public class ConcurrentMapExample {

   public static void main(String[] args) {

       ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

       map.put("A", 1);

       map.put("B", 2);

       map.put("C", 3);


       System.out.println(map.get("B")); // Output: 2

   }

}

Chapter 12: Best Practices and Design Patterns

Chapter 13: Advanced Java Tools and Libraries