Advance Java tutorials with code examples in details

 Here is an Advanced Java tutorial with detailed code examples. This tutorial covers advanced topics like Multithreading, File I/O, Networking, Java Collections, Lambda Expressions, Streams, Reflection, and more.


1. Multithreading in Java

Multithreading allows multiple threads to run concurrently, which is essential for performance, especially in multi-core processors.

1.1 Creating a Thread in Java

There are two ways to create a thread in Java:

  • By extending the Thread class
  • By implementing the Runnable interface

Example 1: Extending Thread Class

class MyThread extends Thread { public void run() { System.out.println("Thread is running using extend Thread"); } } public class Main { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); // start the thread } }

Example 2: Implementing Runnable Interface

class MyRunnable implements Runnable { public void run() { System.out.println("Thread is running using Runnable Interface"); } } public class Main { public static void main(String[] args) { MyRunnable r = new MyRunnable(); Thread t = new Thread(r); t.start(); // start the thread } }

1.2 Thread Synchronization

When multiple threads access shared resources, synchronization is important to prevent data corruption. This can be done using the synchronized keyword.

Example 3: Synchronizing a Method

class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } } public class Main { public static void main(String[] args) { 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(); try { t1.join(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Final count: " + counter.getCount()); } }

In this example, the increment method is synchronized to ensure only one thread can access it at a time.


2. File I/O in Java

Java provides a rich set of classes in the java.io and java.nio packages to handle file input/output.

2.1 Reading a File

Using FileReader and BufferedReader

import java.io.*; public class FileReadExample { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } } }

This code reads each line of a text file and prints it to the console.

2.2 Writing to a File

Using FileWriter and BufferedWriter

import java.io.*; public class FileWriteExample { public static void main(String[] args) { try (BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt"))) { bw.write("Hello, world!\n"); bw.write("Java I/O Example\n"); } catch (IOException e) { e.printStackTrace(); } } }

This code writes two lines to the "output.txt" file.


3. Java Networking

Java provides a java.net package that supports network communication.

3.1 Socket Programming

You can create client-server communication using Sockets in Java. The client sends a message to the server, and the server responds.

Server Program

import java.io.*; import java.net.*; public class Server { public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(8080)) { System.out.println("Server is waiting for client..."); Socket socket = serverSocket.accept(); System.out.println("Client connected"); BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter output = new PrintWriter(socket.getOutputStream(), true); String message = input.readLine(); System.out.println("Message from client: " + message); output.println("Hello from server!"); } catch (IOException e) { e.printStackTrace(); } } }

Client Program

import java.io.*; import java.net.*; public class Client { public static void main(String[] args) { try (Socket socket = new Socket("localhost", 8080)) { BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter output = new PrintWriter(socket.getOutputStream(), true); output.println("Hello from client!"); System.out.println("Server says: " + input.readLine()); } catch (IOException e) { e.printStackTrace(); } } }

4. Java Collections Framework

The Java Collections Framework provides a set of classes and interfaces to store and manipulate data.

4.1 ArrayList Example

ArrayList is a resizable array implementation of the List interface.

import java.util.*; public class ArrayListExample { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Mango"); // Iterating through the list for (String fruit : list) { System.out.println(fruit); } } }

4.2 HashMap Example

HashMap is a key-value pair implementation of the Map interface.

import java.util.*; public class HashMapExample { public static void main(String[] args) { HashMap<Integer, String> map = new HashMap<>(); map.put(1, "One"); map.put(2, "Two"); map.put(3, "Three"); // Iterating through the map for (Map.Entry<Integer, String> entry : map.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } } }

5. Lambda Expressions and Streams in Java

Java 8 introduced Lambda Expressions and Streams for functional-style programming.

5.1 Lambda Expressions

Lambda expressions provide a clear and concise way to represent one method interface (functional interface) using an expression.

interface MathOperation { int operate(int a, int b); } public class LambdaExample { public static void main(String[] args) { MathOperation add = (a, b) -> a + b; MathOperation multiply = (a, b) -> a * b; System.out.println("Addition: " + add.operate(5, 3)); System.out.println("Multiplication: " + multiply.operate(5, 3)); } }

5.2 Streams API

The Stream API is used to process sequences of elements in a functional style. It allows operations like filtering, mapping, and collecting.

import java.util.*; import java.util.stream.*; public class StreamExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // Using Stream to filter even numbers and print them numbers.stream() .filter(n -> n % 2 == 0) .forEach(System.out::println); } }

6. Reflection in Java

Reflection is a powerful feature in Java that allows you to inspect and manipulate classes, methods, fields, and constructors during runtime.

6.1 Using Reflection to Inspect Class

import java.lang.reflect.*; class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void displayInfo() { System.out.println("Name: " + name + ", Age: " + age); } } public class ReflectionExample { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("Person"); System.out.println("Class Name: " + clazz.getName()); Constructor<?> constructor = clazz.getConstructor(String.class, int.class); Object personObj = constructor.newInstance("John", 25); Method method = clazz.getMethod("displayInfo"); method.invoke(personObj); } }

7. Java Design Patterns

Design Patterns are reusable solutions to common software design problems. Some common patterns in Java include:

  • Singleton
  • Factory
  • Observer
  • Decorator
  • Strategy

Conclusion

This Advanced Java tutorial covered several advanced topics in Java such as Multithreading, File I/O, Networking, Java Collections, Lambda Expressions, Streams, and Reflection. These concepts help you write efficient, scalable, and maintainable code. To truly master Java, it's important to keep practicing and exploring advanced concepts like Java Memory Management, Concurrency, JVM Internals, and Distributed Systems.

Comments

Popular posts from this blog

PrimeNG tutorial with examples using frequently used classes

Docker and Kubernetes Tutorials and QnA

Building strong foundational knowledge in frontend development topics