Which of the following best describes a 'functional interface' in the context of Java Lambda Expressions?
Anonymous Quiz
21%
An interface that contains only static methods.
71%
An interface with exactly one abstract method, which can be implemented by a lambda expression.
7%
An interface that can only be implemented by anonymous inner classes.
0%
An interface that has no methods at all.
Restart from Day 1?
Anonymous Poll
79%
πYes, let's start from the basics.
21%
βοΈ No, continue from where we left off.
Here's your Telegram post for Day 25 of the Java learning series!
---
π Day 25: Unit Testing (JUnit) π
It's time to build robust Java applications! Today, we dive into the world of Unit Testing with **JUnit**. π§ͺ Writing tests ensures your code behaves exactly as expected, catches bugs early, and makes refactoring a breeze. We'll learn how to create simple test cases to verify individual components (units) of your code. Let's make our code reliable! πͺ
```java
// Calculator.java - The class we want to test
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
// A simple method to demonstrate an edge case for testing
public int divide(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Cannot divide by zero");
}
return a / b;
}
}
```
```java
// CalculatorTest.java - Our JUnit test class
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; // Import static assertions
public class CalculatorTest {
// Test method for the add operation
@Test
void testAdd() {
Calculator calculator = new Calculator();
// assertEquals(expected, actual, message)
assertEquals(5, calculator.add(2, 3), "2 + 3 should be 5");
assertEquals(0, calculator.add(-1, 1), "-1 + 1 should be 0");
assertEquals(-5, calculator.add(-2, -3), "-2 + -3 should be -5");
}
// Test method for the subtract operation
@Test
void testSubtract() {
Calculator calculator = new Calculator();
assertEquals(1, calculator.subtract(3, 2), "3 - 2 should be 1");
assertEquals(-5, calculator.subtract(0, 5), "0 - 5 should be -5");
assertEquals(0, calculator.subtract(7, 7), "7 - 7 should be 0");
}
// Test method for the multiply operation
@Test
void testMultiply() {
Calculator calculator = new Calculator();
assertEquals(6, calculator.multiply(2, 3), "2 * 3 should be 6");
assertEquals(0, calculator.multiply(5, 0), "5 * 0 should be 0");
assertEquals(-10, calculator.multiply(-2, 5), "-2 * 5 should be -10");
}
// Test method to verify division by zero throws an exception
@Test
void testDivideByZeroThrowsException() {
Calculator calculator = new Calculator();
// assertThrows(expectedType, executable, message)
assertThrows(IllegalArgumentException.class, () -> calculator.divide(10, 0),
"Dividing by zero should throw IllegalArgumentException");
}
// Example of a failing test (if you change expected to 4 for 2+3)
// @Test
// void testAddFailingExample() {
// Calculator calculator = new Calculator();
// assertEquals(4, calculator.add(2, 3), "2 + 3 should be 5 (this will fail)");
// }
}
```
Output example:
```
[INFO] Running CalculatorTest
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
**Challenge for you!** π‘
Add a new method `power(int base, int exponent)` to the `Calculator` class that calculates `base` raised to the power of `exponent`. Then, write a JUnit test method (`testPower()`) to verify its correctness. Don't forget edge cases like `exponent = 0` and `exponent = 1`!
---
---
π Day 25: Unit Testing (JUnit) π
It's time to build robust Java applications! Today, we dive into the world of Unit Testing with **JUnit**. π§ͺ Writing tests ensures your code behaves exactly as expected, catches bugs early, and makes refactoring a breeze. We'll learn how to create simple test cases to verify individual components (units) of your code. Let's make our code reliable! πͺ
```java
// Calculator.java - The class we want to test
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
public int multiply(int a, int b) {
return a * b;
}
// A simple method to demonstrate an edge case for testing
public int divide(int a, int b) {
if (b == 0) {
throw new IllegalArgumentException("Cannot divide by zero");
}
return a / b;
}
}
```
```java
// CalculatorTest.java - Our JUnit test class
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; // Import static assertions
public class CalculatorTest {
// Test method for the add operation
@Test
void testAdd() {
Calculator calculator = new Calculator();
// assertEquals(expected, actual, message)
assertEquals(5, calculator.add(2, 3), "2 + 3 should be 5");
assertEquals(0, calculator.add(-1, 1), "-1 + 1 should be 0");
assertEquals(-5, calculator.add(-2, -3), "-2 + -3 should be -5");
}
// Test method for the subtract operation
@Test
void testSubtract() {
Calculator calculator = new Calculator();
assertEquals(1, calculator.subtract(3, 2), "3 - 2 should be 1");
assertEquals(-5, calculator.subtract(0, 5), "0 - 5 should be -5");
assertEquals(0, calculator.subtract(7, 7), "7 - 7 should be 0");
}
// Test method for the multiply operation
@Test
void testMultiply() {
Calculator calculator = new Calculator();
assertEquals(6, calculator.multiply(2, 3), "2 * 3 should be 6");
assertEquals(0, calculator.multiply(5, 0), "5 * 0 should be 0");
assertEquals(-10, calculator.multiply(-2, 5), "-2 * 5 should be -10");
}
// Test method to verify division by zero throws an exception
@Test
void testDivideByZeroThrowsException() {
Calculator calculator = new Calculator();
// assertThrows(expectedType, executable, message)
assertThrows(IllegalArgumentException.class, () -> calculator.divide(10, 0),
"Dividing by zero should throw IllegalArgumentException");
}
// Example of a failing test (if you change expected to 4 for 2+3)
// @Test
// void testAddFailingExample() {
// Calculator calculator = new Calculator();
// assertEquals(4, calculator.add(2, 3), "2 + 3 should be 5 (this will fail)");
// }
}
```
Output example:
```
[INFO] Running CalculatorTest
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
```
**Challenge for you!** π‘
Add a new method `power(int base, int exponent)` to the `Calculator` class that calculates `base` raised to the power of `exponent`. Then, write a JUnit test method (`testPower()`) to verify its correctness. Don't forget edge cases like `exponent = 0` and `exponent = 1`!
---
Which JUnit 5 annotation is used to mark a method as a test method?
Anonymous Quiz
0%
A) @BeforeEach
63%
B) @Test
13%
C) @TestSuite
25%
D) @RunTest
π Day 26: Diving into Basic Web Scraping with Jsoup! πΈοΈ Ever wished you could automatically pull information from websites? Today, we're exploring the fascinating world of web scraping using Jsoup, a robust Java library. Jsoup simplifies parsing HTML, navigating the DOM, and extracting specific data with familiar CSS selectors. It's an essential skill for data collection, monitoring, and automation. Let's write some code! π§βπ»
Here's how to get started with Jsoup to extract a page title and a paragraph:
```java
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class SimpleWebScraper {
public static void main(String[] args) {
String url = "http://example.com/"; // A simple, static page for demonstration
try {
// 1. Connect to the URL and get the HTML document
// Jsoup.connect(url) creates a Connection object
// .get() fetches the URL and parses the HTML into a Document object
Document document = Jsoup.connect(url).get();
// 2. Extract the page title
String title = document.title();
System.out.println("Page Title: " + title);
// 3. Extract the text from the first paragraph (<p> tag)
// .select("p") finds all <p> tags
Elements paragraphs = document.select("p");
if (!paragraphs.isEmpty()) {
// .first() gets the first Element in the collection
// .text() extracts the plain text content of the element
System.out.println("First Paragraph Text: " + paragraphs.first().text());
}
// 4. Extract the text from the <h1> tag
// .selectFirst("h1") finds only the first <h1> tag
Element h1Tag = document.selectFirst("h1");
if (h1Tag != null) {
System.out.println("H1 Tag Text: " + h1Tag.text());
}
} catch (IOException e) {
System.err.println("Error connecting to " + url + ": " + e.getMessage());
e.printStackTrace(); // For more detailed error info
}
}
}
```
Output example:
```
Page Title: Example Domain
First Paragraph Text: This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.
H1 Tag Text: Example Domain
```
π‘ **Challenge:** Can you modify the code to find *all* `<a>` (anchor) tags on `http://example.com/` and print their `href` attributes? (Hint: Loop through the `Elements` collection and use `element.attr("href")`!) Happy scraping! π΅οΈββοΈ
---
Here's how to get started with Jsoup to extract a page title and a paragraph:
```java
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class SimpleWebScraper {
public static void main(String[] args) {
String url = "http://example.com/"; // A simple, static page for demonstration
try {
// 1. Connect to the URL and get the HTML document
// Jsoup.connect(url) creates a Connection object
// .get() fetches the URL and parses the HTML into a Document object
Document document = Jsoup.connect(url).get();
// 2. Extract the page title
String title = document.title();
System.out.println("Page Title: " + title);
// 3. Extract the text from the first paragraph (<p> tag)
// .select("p") finds all <p> tags
Elements paragraphs = document.select("p");
if (!paragraphs.isEmpty()) {
// .first() gets the first Element in the collection
// .text() extracts the plain text content of the element
System.out.println("First Paragraph Text: " + paragraphs.first().text());
}
// 4. Extract the text from the <h1> tag
// .selectFirst("h1") finds only the first <h1> tag
Element h1Tag = document.selectFirst("h1");
if (h1Tag != null) {
System.out.println("H1 Tag Text: " + h1Tag.text());
}
} catch (IOException e) {
System.err.println("Error connecting to " + url + ": " + e.getMessage());
e.printStackTrace(); // For more detailed error info
}
}
}
```
Output example:
```
Page Title: Example Domain
First Paragraph Text: This domain is for use in illustrative examples in documents. You may use this domain in literature without prior coordination or asking for permission.
H1 Tag Text: Example Domain
```
π‘ **Challenge:** Can you modify the code to find *all* `<a>` (anchor) tags on `http://example.com/` and print their `href` attributes? (Hint: Loop through the `Elements` collection and use `element.attr("href")`!) Happy scraping! π΅οΈββοΈ
---
Which Java library is commonly used for parsing HTML, navigating the DOM, and extracting data from web pages using CSS selectors?
Anonymous Quiz
33%
A) Apache HttpClient
42%
B) Jsoup
8%
C) Selenium WebDriver
17%
D) Spring WebFlux
Here's your Telegram post and quiz for Day 27!
---
**π Day 27: Introduction to Spring Boot π**
Ready for something game-changing? Today, we're diving into Spring Boot β the powerhouse framework that makes building robust, production-ready Java applications a breeze! π Say goodbye to complex configurations and hello to convention over configuration, embedded servers, and rapid development. We'll build our very first 'Hello World' REST API, showcasing just how easy it is to get started. Let's make some magic! β¨
```java
// SpringBootDemoApplication.java
// This is your main application entry point.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication // Marks this as a Spring Boot application
public class SpringBootDemoApplication {
public static void main(String[] args) {
// This line launches the Spring Boot application
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
// HelloController.java
// This would typically be in a separate file (e.g., com.example.demo.controller)
// It handles incoming web requests.
@RestController // Marks this class as a REST controller
class HelloController {
// Maps HTTP GET requests to the "/hello" path
@GetMapping("/hello")
public String sayHello() {
return "Hello from Spring Boot! π"; // The response sent to the client
}
}
```
**How to run (conceptual):**
1. Set up a Spring Boot project (e.g., using Spring Initializr).
2. Place `SpringBootDemoApplication.java` and `HelloController.java` in appropriate packages (e.g., `com.example.demo`).
3. Run the `main` method in `SpringBootDemoApplication`.
4. Open your browser and navigate to `http://localhost:8080/hello`.
**Output example:**
When you open `http://localhost:8080/hello` in your browser:
```
Hello from Spring Boot! π
```
**Small Challenge:**
Can you add another endpoint to our `HelloController`? Create a new method mapped to `/greet` that returns the string "Greetings, Java Learner! Happy coding! πͺ".
---
---
**π Day 27: Introduction to Spring Boot π**
Ready for something game-changing? Today, we're diving into Spring Boot β the powerhouse framework that makes building robust, production-ready Java applications a breeze! π Say goodbye to complex configurations and hello to convention over configuration, embedded servers, and rapid development. We'll build our very first 'Hello World' REST API, showcasing just how easy it is to get started. Let's make some magic! β¨
```java
// SpringBootDemoApplication.java
// This is your main application entry point.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication // Marks this as a Spring Boot application
public class SpringBootDemoApplication {
public static void main(String[] args) {
// This line launches the Spring Boot application
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
// HelloController.java
// This would typically be in a separate file (e.g., com.example.demo.controller)
// It handles incoming web requests.
@RestController // Marks this class as a REST controller
class HelloController {
// Maps HTTP GET requests to the "/hello" path
@GetMapping("/hello")
public String sayHello() {
return "Hello from Spring Boot! π"; // The response sent to the client
}
}
```
**How to run (conceptual):**
1. Set up a Spring Boot project (e.g., using Spring Initializr).
2. Place `SpringBootDemoApplication.java` and `HelloController.java` in appropriate packages (e.g., `com.example.demo`).
3. Run the `main` method in `SpringBootDemoApplication`.
4. Open your browser and navigate to `http://localhost:8080/hello`.
**Output example:**
When you open `http://localhost:8080/hello` in your browser:
```
Hello from Spring Boot! π
```
**Small Challenge:**
Can you add another endpoint to our `HelloController`? Create a new method mapped to `/greet` that returns the string "Greetings, Java Learner! Happy coding! πͺ".
---
What is a primary benefit of using Spring Boot for Java development?
Anonymous Quiz
0%
It eliminates the need for the Java Virtual Machine.
100%
It simplifies the development of standalone, production-ready Spring applications.
0%
It replaces SQL databases entirely with in-memory storage.
0%
It converts Java code directly into machine code without compilation.
π Day 28: Dive into the fascinating world of **Multithreading and Concurrency** in Java! π€― Ever wanted your program to do multiple things *simultaneously*? That's what multithreading empowers you to do! We'll explore how to create and manage independent threads of execution using `Runnable` and `Thread`. Get ready to unlock parallel processing power, but also learn about the cool challenges it brings! πͺ
Here's a simple example demonstrating concurrent execution and a common pitfall:
```java
// Counter.java
class Counter {
int count = 0; // This shared resource is not thread-safe
public void increment() {
// Simulate some work being done
try {
Thread.sleep(1); // Small delay to increase chance of race condition
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
count++;
}
public int getCount() {
return count;
}
}
// Task.java
class Task implements Runnable {
private Counter sharedCounter;
private String name;
private int incrementsPerThread;
public Task(Counter counter, String name, int increments) {
this.sharedCounter = counter;
this.name = name;
this.incrementsPerThread = increments;
}
@Override
public void run() {
System.out.println(name + " starting...");
for (int i = 0; i < incrementsPerThread; i++) {
sharedCounter.increment();
}
System.out.println(name + " finished.");
}
}
// MultithreadingExample.java
public class MultithreadingExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
int numIncrementsPerThread = 1000;
int numThreads = 2;
// Create two threads, each incrementing the same counter
Thread t1 = new Thread(new Task(counter, "Worker-1", numIncrementsPerThread));
Thread t2 = new Thread(new Task(counter, "Worker-2", numIncrementsPerThread));
// Start both threads
t1.start();
t2.start();
// Wait for both threads to complete their execution
t1.join(); // main thread waits for t1 to finish
t2.join(); // main thread waits for t2 to finish
System.out.println("nExpected Final Counter Value: " + (numIncrementsPerThread * numThreads));
System.out.println("Actual Final Counter Value: " + counter.getCount());
}
}
```
Output example:
```
Worker-1 starting...
Worker-2 starting...
Worker-1 finished.
Worker-2 finished.
Expected Final Counter Value: 2000
Actual Final Counter Value: 1978 (This value will vary due to race condition, always less than expected)
```
π‘ Challenge Time! Why is the `Actual Final Counter Value` often less than the `Expected` one? π€ This is a classic **race condition**! Your mission: Modify the `increment()` method in the `Counter` class using the `synchronized` keyword to ensure thread-safe increments and always get the correct final value! Share your solution in the comments! π
---
Here's a simple example demonstrating concurrent execution and a common pitfall:
```java
// Counter.java
class Counter {
int count = 0; // This shared resource is not thread-safe
public void increment() {
// Simulate some work being done
try {
Thread.sleep(1); // Small delay to increase chance of race condition
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
count++;
}
public int getCount() {
return count;
}
}
// Task.java
class Task implements Runnable {
private Counter sharedCounter;
private String name;
private int incrementsPerThread;
public Task(Counter counter, String name, int increments) {
this.sharedCounter = counter;
this.name = name;
this.incrementsPerThread = increments;
}
@Override
public void run() {
System.out.println(name + " starting...");
for (int i = 0; i < incrementsPerThread; i++) {
sharedCounter.increment();
}
System.out.println(name + " finished.");
}
}
// MultithreadingExample.java
public class MultithreadingExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
int numIncrementsPerThread = 1000;
int numThreads = 2;
// Create two threads, each incrementing the same counter
Thread t1 = new Thread(new Task(counter, "Worker-1", numIncrementsPerThread));
Thread t2 = new Thread(new Task(counter, "Worker-2", numIncrementsPerThread));
// Start both threads
t1.start();
t2.start();
// Wait for both threads to complete their execution
t1.join(); // main thread waits for t1 to finish
t2.join(); // main thread waits for t2 to finish
System.out.println("nExpected Final Counter Value: " + (numIncrementsPerThread * numThreads));
System.out.println("Actual Final Counter Value: " + counter.getCount());
}
}
```
Output example:
```
Worker-1 starting...
Worker-2 starting...
Worker-1 finished.
Worker-2 finished.
Expected Final Counter Value: 2000
Actual Final Counter Value: 1978 (This value will vary due to race condition, always less than expected)
```
π‘ Challenge Time! Why is the `Actual Final Counter Value` often less than the `Expected` one? π€ This is a classic **race condition**! Your mission: Modify the `increment()` method in the `Counter` class using the `synchronized` keyword to ensure thread-safe increments and always get the correct final value! Share your solution in the comments! π
---
π **Day 29: Basic Database Interaction (JDBC)!** π
Ever wondered how Java applications store and retrieve data from databases? Today's the day we demystify it with **JDBC (Java Database Connectivity)**! π€―
JDBC is the standard API for Java to interact with relational databases. We'll cover the fundamental steps: establishing a `Connection`, creating `Statement`s to execute SQL queries, and processing the `ResultSet`. Get ready to make your Java apps data-driven! Let's connect! π
```java
import java.sql.*;
public class SimpleJdbcApp {
// H2 In-Memory Database URL - simple, no separate server needed!
private static final String DB_URL = "jdbc:h2:mem:testdb";
private static final String USER = "sa"; // Default H2 user
private static final String PASS = ""; // Default H2 password (empty for H2 in-memory)
public static void main(String[] args) {
System.out.println("π Day 29: Basic JDBC Interaction! π");
System.out.println("Connecting to H2 In-Memory database...");
// Using try-with-resources ensures Connection and Statement are closed automatically
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement()) {
System.out.println("β Database connected successfully!");
// 1. Create a table
String createTableSQL = "CREATE TABLE STUDENTS " +
"(id INT PRIMARY KEY AUTO_INCREMENT, " +
"name VARCHAR(255) NOT NULL, " +
"age INT)";
stmt.executeUpdate(createTableSQL); // executeUpdate for DDL (CREATE, ALTER, DROP) and DML (INSERT, UPDATE, DELETE)
System.out.println("β¨ Table 'STUDENTS' created.");
// 2. Insert some data
String insertSQL1 = "INSERT INTO STUDENTS (name, age) VALUES ('Alice', 20)";
stmt.executeUpdate(insertSQL1);
String insertSQL2 = "INSERT INTO STUDENTS (name, age) VALUES ('Bob', 22)";
stmt.executeUpdate(insertSQL2);
System.out.println("β Data inserted into STUDENTS table.");
// 3. Select and retrieve data
String selectSQL = "SELECT id, name, age FROM STUDENTS";
System.out.println("n--- Retrieving Student List ---");
// Using try-with-resources for ResultSet too, ensures it's closed
try (ResultSet rs = stmt.executeQuery(selectSQL)) { // executeQuery for SELECT statements
while (rs.next()) {
// Retrieve by column name
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
// Display values
System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age);
}
} // ResultSet 'rs' is closed here automatically
} catch (SQLException e) {
System.err.println("β An SQL error occurred: " + e.getMessage());
// In a real application, you'd log this more robustly
e.printStackTrace();
} finally {
System.out.println("nπ‘ Database interaction complete. H2 In-Memory database is ephemeral (data is lost when app closes).");
}
}
}
```
Output example:
```
π Day 29: Basic JDBC Interaction! π
Connecting to H2 In-Memory database...
β Database connected successfully!
β¨ Table 'STUDENTS' created.
β Data inserted into STUDENTS table.
--- Retrieving Student List ---
ID: 1, Name: Alice, Age: 20
ID: 2, Name: Bob, Age: 22
π‘ Database interaction complete. H2 In-Memory database is ephemeral (data is lost when app closes).
```
**Small Challenge:** πͺ Can you add a new student and then write a `SELECT` query to retrieve *only* students older than 21? (Hint: Use `executeUpdate()` for the new student and add a `WHERE` clause to your `SELECT` query! For example: `SELECT ... FROM STUDENTS WHERE age > 21`).
---
Ever wondered how Java applications store and retrieve data from databases? Today's the day we demystify it with **JDBC (Java Database Connectivity)**! π€―
JDBC is the standard API for Java to interact with relational databases. We'll cover the fundamental steps: establishing a `Connection`, creating `Statement`s to execute SQL queries, and processing the `ResultSet`. Get ready to make your Java apps data-driven! Let's connect! π
```java
import java.sql.*;
public class SimpleJdbcApp {
// H2 In-Memory Database URL - simple, no separate server needed!
private static final String DB_URL = "jdbc:h2:mem:testdb";
private static final String USER = "sa"; // Default H2 user
private static final String PASS = ""; // Default H2 password (empty for H2 in-memory)
public static void main(String[] args) {
System.out.println("π Day 29: Basic JDBC Interaction! π");
System.out.println("Connecting to H2 In-Memory database...");
// Using try-with-resources ensures Connection and Statement are closed automatically
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
Statement stmt = conn.createStatement()) {
System.out.println("β Database connected successfully!");
// 1. Create a table
String createTableSQL = "CREATE TABLE STUDENTS " +
"(id INT PRIMARY KEY AUTO_INCREMENT, " +
"name VARCHAR(255) NOT NULL, " +
"age INT)";
stmt.executeUpdate(createTableSQL); // executeUpdate for DDL (CREATE, ALTER, DROP) and DML (INSERT, UPDATE, DELETE)
System.out.println("β¨ Table 'STUDENTS' created.");
// 2. Insert some data
String insertSQL1 = "INSERT INTO STUDENTS (name, age) VALUES ('Alice', 20)";
stmt.executeUpdate(insertSQL1);
String insertSQL2 = "INSERT INTO STUDENTS (name, age) VALUES ('Bob', 22)";
stmt.executeUpdate(insertSQL2);
System.out.println("β Data inserted into STUDENTS table.");
// 3. Select and retrieve data
String selectSQL = "SELECT id, name, age FROM STUDENTS";
System.out.println("n--- Retrieving Student List ---");
// Using try-with-resources for ResultSet too, ensures it's closed
try (ResultSet rs = stmt.executeQuery(selectSQL)) { // executeQuery for SELECT statements
while (rs.next()) {
// Retrieve by column name
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
// Display values
System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age);
}
} // ResultSet 'rs' is closed here automatically
} catch (SQLException e) {
System.err.println("β An SQL error occurred: " + e.getMessage());
// In a real application, you'd log this more robustly
e.printStackTrace();
} finally {
System.out.println("nπ‘ Database interaction complete. H2 In-Memory database is ephemeral (data is lost when app closes).");
}
}
}
```
Output example:
```
π Day 29: Basic JDBC Interaction! π
Connecting to H2 In-Memory database...
β Database connected successfully!
β¨ Table 'STUDENTS' created.
β Data inserted into STUDENTS table.
--- Retrieving Student List ---
ID: 1, Name: Alice, Age: 20
ID: 2, Name: Bob, Age: 22
π‘ Database interaction complete. H2 In-Memory database is ephemeral (data is lost when app closes).
```
**Small Challenge:** πͺ Can you add a new student and then write a `SELECT` query to retrieve *only* students older than 21? (Hint: Use `executeUpdate()` for the new student and add a `WHERE` clause to your `SELECT` query! For example: `SELECT ... FROM STUDENTS WHERE age > 21`).
---
Which JDBC object is primarily used to retrieve and process the results returned by executing a SQL SELECT query?
Anonymous Quiz
25%
A) java.sql.Connection
13%
B) java.sql.Statement
63%
C) java.sql.ResultSet
0%
D) java.sql.DriverManager
Which of the following is typically the *first* crucial step when starting a new software development project?
Anonymous Quiz
0%
A. Writing all the code for the main features
0%
B. Deploying the application to a production server
88%
C. Defining requirements, planning, and designing the project structure
13%
D. Creating marketing materials for the finished product
Day 32! π We're diving deep into the future of Java concurrency: **Structured Concurrency with Project Loom**. Forget the old "thread-per-request" headaches and complex `CompletableFuture` chains for error handling. With Virtual Threads and `StructuredTaskScope`, you can orchestrate multiple concurrent operations as a single unit, ensuring cleaner code, automatic error propagation, and efficient resource management. This paradigm shift will revolutionize how we build scalable, resilient services. Get ready to rethink your concurrency strategies! β¨
```java
import java.time.Duration;
import java.util.concurrent.Future;
import java.util.concurrent.StructuredTaskScope;
import java.util.random.RandomGenerator;
public class StructuredConcurrencyExample {
record UserData(String name, int id) {}
record Order(String itemId, int userId) {}
public static void main(String[] args) throws InterruptedException {
System.out.println("π Day 32: Starting Structured Concurrency with Virtual Threads!");
long startTime = System.currentTimeMillis();
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<UserData> userFuture = scope.fork(() -> {
System.out.println(" [User Service] Fetching user data on: " + Thread.currentThread());
Thread.sleep(Duration.ofMillis(RandomGenerator.getDefault().nextInt(200, 500)));
return new UserData("Alice", 123);
});
Future<Order> orderFuture = scope.fork(() -> {
System.out.println(" [Order Service] Fetching order data on: " + Thread.currentThread());
Thread.sleep(Duration.ofMillis(RandomGenerator.getDefault().nextInt(300, 800)));
// Simulate a potential failure for demonstration
// if (RandomGenerator.getDefault().nextBoolean()) {
// throw new RuntimeException("Failed to fetch orders!");
// }
return new Order("BOOK-456", 123);
});
// Wait for all subtasks to complete or for one to fail
scope.join();
// If any subtask failed, this will re-throw the exception
scope.throwIfFailed();
UserData user = userFuture.resultNow();
Order order = orderFuture.resultNow();
System.out.println("β All tasks completed successfully!");
System.out.println("User: " + user);
System.out.println("Order: " + order);
} catch (Exception e) {
System.err.println("β One or more tasks failed: " + e.getMessage());
}
long endTime = System.currentTimeMillis();
System.out.println("Total execution time: " + (endTime - startTime) + "ms");
System.out.println("Main thread: " + Thread.currentThread());
}
}
```
Output example:
```
π Day 32: Starting Structured Concurrency with Virtual Threads!
[User Service] Fetching user data on: VirtualThread[...]/run-scope-1
[Order Service] Fetching order data on: VirtualThread[...]/run-scope-2
β All tasks completed successfully!
User: UserData[name=Alice, id=123]
Order: Order[itemId=BOOK-456, userId=123]
Total execution time: 785ms
Main thread: main
```
*(Note: Execution time will vary due to random delays. The thread names will show `VirtualThread[...]`.)*
**Small Challenge:**
Uncomment the `// if (RandomGenerator.getDefault().nextBoolean()) { throw new RuntimeException("Failed to fetch orders!"); }` line in the `orderFuture` task. Run the code multiple times and observe how `StructuredTaskScope.ShutdownOnFailure` automatically handles the error, potentially cancelling the other tasks and propagating the exception. How does this compare to traditional `CompletableFuture` error handling? π€
---
```java
import java.time.Duration;
import java.util.concurrent.Future;
import java.util.concurrent.StructuredTaskScope;
import java.util.random.RandomGenerator;
public class StructuredConcurrencyExample {
record UserData(String name, int id) {}
record Order(String itemId, int userId) {}
public static void main(String[] args) throws InterruptedException {
System.out.println("π Day 32: Starting Structured Concurrency with Virtual Threads!");
long startTime = System.currentTimeMillis();
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<UserData> userFuture = scope.fork(() -> {
System.out.println(" [User Service] Fetching user data on: " + Thread.currentThread());
Thread.sleep(Duration.ofMillis(RandomGenerator.getDefault().nextInt(200, 500)));
return new UserData("Alice", 123);
});
Future<Order> orderFuture = scope.fork(() -> {
System.out.println(" [Order Service] Fetching order data on: " + Thread.currentThread());
Thread.sleep(Duration.ofMillis(RandomGenerator.getDefault().nextInt(300, 800)));
// Simulate a potential failure for demonstration
// if (RandomGenerator.getDefault().nextBoolean()) {
// throw new RuntimeException("Failed to fetch orders!");
// }
return new Order("BOOK-456", 123);
});
// Wait for all subtasks to complete or for one to fail
scope.join();
// If any subtask failed, this will re-throw the exception
scope.throwIfFailed();
UserData user = userFuture.resultNow();
Order order = orderFuture.resultNow();
System.out.println("β All tasks completed successfully!");
System.out.println("User: " + user);
System.out.println("Order: " + order);
} catch (Exception e) {
System.err.println("β One or more tasks failed: " + e.getMessage());
}
long endTime = System.currentTimeMillis();
System.out.println("Total execution time: " + (endTime - startTime) + "ms");
System.out.println("Main thread: " + Thread.currentThread());
}
}
```
Output example:
```
π Day 32: Starting Structured Concurrency with Virtual Threads!
[User Service] Fetching user data on: VirtualThread[...]/run-scope-1
[Order Service] Fetching order data on: VirtualThread[...]/run-scope-2
β All tasks completed successfully!
User: UserData[name=Alice, id=123]
Order: Order[itemId=BOOK-456, userId=123]
Total execution time: 785ms
Main thread: main
```
*(Note: Execution time will vary due to random delays. The thread names will show `VirtualThread[...]`.)*
**Small Challenge:**
Uncomment the `// if (RandomGenerator.getDefault().nextBoolean()) { throw new RuntimeException("Failed to fetch orders!"); }` line in the `orderFuture` task. Run the code multiple times and observe how `StructuredTaskScope.ShutdownOnFailure` automatically handles the error, potentially cancelling the other tasks and propagating the exception. How does this compare to traditional `CompletableFuture` error handling? π€
---
Hey everyone! We're starting again from Day 1 so everyone can build a strong foundation by learning everything from the basics this time.
β€1
Share this with your friends so they also get benefits.
https://t.me/java_for_beginner
https://t.me/java_for_beginner
Telegram
Java for beginners
Learn Java daily with bite-sized lessons, practical code examples, output previews, and fun quizzes.