Please set up the timer and start doing the following tasks !!!
Solution is available in
completedbranch
Warmup [15 min]: Find non-unique elements in a list
- Clone a project https://github.com/TheJKGL/codeus-practice/tree/develop
- Switch to
developbranch and navigate tosrc/main/java/com/practice/warmup/FindNonUniqueElementsInList.java - Validate your solution using Unit Tests in
src/test/java/com/practice/warmup/FindNonUniqueElementsTest.java
Optionally:
- Solve the task using Java Stream API
- Solve the task using any other programming language
Assignment [40 min]: Practice with CompletableFuture API and HttpClient API
- Read the short presentation below to dive into the context of the task
- Stay in
developbranch and navigate tosrc/main/java/com/practice/assignmentpackage and implement all methods inCompletableFutureTasksclass - Validate your solution using Unit Tests in
src/test/java/com/practice/assignment/CompletableFutureTests.java
- Objective: Understand key methods of
CompletableFutureandHttpClientfor asynchronous programming in Java. - Use Cases: Making non-blocking HTTP requests, processing results asynchronously.
- What is CompletableFuture?
- A class that represents a future result of an asynchronous computation.
- Provides a way to execute tasks asynchronously and handle results and exceptions.
-
supplyAsync(Supplier supplier)
- Executes a task asynchronously using a
Supplier. - Returns a
CompletableFuturecontaining the result.
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 42);
- Executes a task asynchronously using a
-
thenApply(Function<? super T, ? extends U> fn)
- Transforms the result of a
CompletableFutureusing a provided function. - Returns a new
CompletableFuturewith the transformed result.
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> future = completableFuture .thenApply(s -> s + " World"); assertEquals("Hello World", future.get());
- Transforms the result of a
-
thenAccept(Consumer<? super T> action)
- Consumes the result of the
CompletableFuturewithout returning a new result. - Useful for side effects.
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<Void> future = completableFuture .thenAccept(s -> System.out.println("Computation returned: " + s)); future.get();//void
- Consumes the result of the
-
exceptionally(Function<Throwable, ? extends T> fn)
- Handles exceptions that occur during the asynchronous computation.
- Returns a new
CompletableFuturewith a fallback result.
future.exceptionally(ex -> { System.out.println("Error: " + ex.getMessage()); return null; });
-
allOf(CompletableFuture<?>... cfs)
- Combines multiple
CompletableFutureinstances into one. - Completes when all futures complete.
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
- Combines multiple
- What is HttpClient?
- A modern API for making HTTP requests in Java. (since Java 11)
- Supports synchronous and asynchronous operations.
-
newBuilder()
- Creates a new
HttpClientbuilder for customizing client settings (timeouts, redirects).
HttpClient client = HttpClient.newBuilder().build();
- Creates a new
-
sendAsync(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler)
- Sends an asynchronous HTTP request and returns a
CompletableFuture<HttpResponse<T>>.
CompletableFuture<HttpResponse<String>> responseFuture = client.sendAsync(request, BodyHandlers.ofString());
- Sends an asynchronous HTTP request and returns a
-
send(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler)
- Sends a synchronous HTTP request and returns the response.
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
-
HttpRequest.newBuilder()
- Creates a builder for constructing HTTP requests with various settings (method, headers).
HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.example.com")) .GET() .build();
-
HttpResponse.BodyHandlers
- Provides built-in body handlers for various types of responses (e.g., string, byte array).
- Asynchronous HTTP Requests:
- Utilize
HttpClientwithCompletableFutureto send non-blocking requests. - Process responses asynchronously using
thenApply,thenAccept, and handle exceptions withexceptionally.
- Utilize
CompletableFuture<User> userFuture = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(...)
.thenApply(...)
.exceptionally(...);- Benefits:
- Efficiently handle multiple asynchronous operations.
- Build scalable applications without blocking threads.
- Key Takeaway: Understanding these methods allows for robust and efficient HTTP interactions in Java applications.
https://www.baeldung.com/java-9-http-client