From 88368b1ee65a2645e26697d78fbe41eaa0cf17d6 Mon Sep 17 00:00:00 2001 From: Marco Yeung Date: Sun, 17 Sep 2023 15:32:05 -0400 Subject: [PATCH 1/2] learning --- .../java/lambdasinaction/chap11/LSep17.java | 97 +++++++++++++++++++ .../java/lambdasinaction/chap11/README.md | 0 .../chap11/v1/BestPriceFinderMain.java | 1 + 3 files changed, 98 insertions(+) create mode 100644 src/main/java/lambdasinaction/chap11/LSep17.java create mode 100644 src/main/java/lambdasinaction/chap11/README.md diff --git a/src/main/java/lambdasinaction/chap11/LSep17.java b/src/main/java/lambdasinaction/chap11/LSep17.java new file mode 100644 index 00000000..4cec31a4 --- /dev/null +++ b/src/main/java/lambdasinaction/chap11/LSep17.java @@ -0,0 +1,97 @@ +package lambdasinaction.chap11; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * https://www.youtube.com/watch?v=0hQvWIdwnw4&ab_channel=Devoxx + */ +public class LSep17 { + + static void future() { + + create().thenAccept(d -> System.out.println(d)) + .thenRun(() -> System.out.println("this never dies")) + .thenRun(() -> System.out.println("really, this never dies")) + .thenRun(() -> System.out.println("r...really, this never dies")); + } + + + void randomTest() { + ExecutorService executorService = + new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); + + Runnable r = () -> { + try { + TimeUnit.MILLISECONDS.sleep(300); + + } catch (InterruptedException ie) { + ie.printStackTrace(); + } + }; + + Callable tasks = () -> { + TimeUnit.MILLISECONDS.sleep(300); + return "Task's execution"; + }; + } + + + static CompletableFuture create() { + return CompletableFuture.supplyAsync(() -> 2); + } + + public static void main(String[] args) throws IOException { + LSep17 ls = new LSep17(); + + String dd = LocalDateTime.now().format(DateTimeFormatter.ofPattern("MMddHHmm")); + System.out.println(dd); + +// List lst = new ArrayList<>(Arrays.asList("")); +// lst = IntStream.range(1, 10).mapToObj(i -> String.format("data %s", i)).collect(Collectors.toList()); +// ls.writeListString(lst); + System.out.println("done"); + + } + void method() { + String fileName = "this_is_large_file.txt"; + IntStream.range(0, 5).map(x -> { + try { + whenWriteStringUsingBufferedWritter_thenCorrect(fileName); + } catch (IOException e) { + throw new RuntimeException(e); // TODO + } + return x; + }).forEach(System.out::println); + + } + + public void writeListString(List fileListing) throws IOException { + } + + public void whenWriteStringUsingBufferedWritter_thenCorrect(String fileName) + throws IOException { + String str = LocalDateTime.now() + " Hello\n"; + BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true)); + writer.write(str); + + writer.close(); + } +} diff --git a/src/main/java/lambdasinaction/chap11/README.md b/src/main/java/lambdasinaction/chap11/README.md new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java index 5a74161a..c1c66626 100644 --- a/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java +++ b/src/main/java/lambdasinaction/chap11/v1/BestPriceFinderMain.java @@ -8,6 +8,7 @@ public class BestPriceFinderMain { private static BestPriceFinder bestPriceFinder = new BestPriceFinder(); public static void main(String[] args) { + //turns the return res as Supplier execute("sequential", () -> bestPriceFinder.findPricesSequential("myPhone27S")); execute("parallel", () -> bestPriceFinder.findPricesParallel("myPhone27S")); execute("composed CompletableFuture", () -> bestPriceFinder.findPricesFuture("myPhone27S")); From 124aafa706a68117858c05a5ab0fe6e9bb0a9e69 Mon Sep 17 00:00:00 2001 From: Marco Yeung Date: Mon, 9 Oct 2023 23:07:47 -0400 Subject: [PATCH 2/2] CompletableFuture learning --- dependency-reduced-pom.xml | 1 + pom.xml | 21 ++++++ src/main/java/learning/AnyOfFutures.java | 42 +++++++++++ .../learning/CompletablefutureTutorial.java | 69 +++++++++++++++++++ .../java/learning/ExceptionInFutures.java | 29 ++++++++ src/main/java/learning/FilterExample.java | 38 ++++++++++ .../java/learning/GuideCompletableFuture.java | 24 +++++++ src/main/java/learning/OptionalTest.java | 39 +++++++++++ src/main/java/learning/README.md | 4 ++ .../java/learning/ThenCombineFutures.java | 44 ++++++++++++ .../java/learning/ThenComposeFutures.java | 49 +++++++++++++ src/main/java/learning/User.java | 13 ++++ src/main/java/log4j2.xml | 29 ++++++++ 13 files changed, 402 insertions(+) create mode 100644 dependency-reduced-pom.xml create mode 100644 src/main/java/learning/AnyOfFutures.java create mode 100644 src/main/java/learning/CompletablefutureTutorial.java create mode 100644 src/main/java/learning/ExceptionInFutures.java create mode 100644 src/main/java/learning/FilterExample.java create mode 100644 src/main/java/learning/GuideCompletableFuture.java create mode 100644 src/main/java/learning/OptionalTest.java create mode 100644 src/main/java/learning/README.md create mode 100644 src/main/java/learning/ThenCombineFutures.java create mode 100644 src/main/java/learning/ThenComposeFutures.java create mode 100644 src/main/java/learning/User.java create mode 100644 src/main/java/log4j2.xml diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml new file mode 100644 index 00000000..ec167c15 --- /dev/null +++ b/dependency-reduced-pom.xml @@ -0,0 +1 @@ + 4.0.0 manning lambdasinaction 1.0 maven-compiler-plugin 3.1 1.9 1.9 maven-shade-plugin package shade benchmarks org.openjdk.jmh.Main UTF-8 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 10e5035e..8145f29b 100644 --- a/pom.xml +++ b/pom.xml @@ -28,6 +28,27 @@ junit 4.11 + + org.projectlombok + lombok-utils + 1.18.6 + + + org.projectlombok + lombok + 1.18.22 + compile + + + org.apache.logging.log4j + log4j-api + 2.17.1 + + + org.apache.logging.log4j + log4j-core + 2.17.1 + diff --git a/src/main/java/learning/AnyOfFutures.java b/src/main/java/learning/AnyOfFutures.java new file mode 100644 index 00000000..50885b13 --- /dev/null +++ b/src/main/java/learning/AnyOfFutures.java @@ -0,0 +1,42 @@ +package learning; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public class AnyOfFutures { + + void anyOfTest() throws ExecutionException, InterruptedException { + CompletableFuture future1 = CompletableFuture.supplyAsync(() -> { + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return "Result of Future 1"; + }); + + CompletableFuture future2 = CompletableFuture.supplyAsync(() -> { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return "Result of Future 2"; + }); + + CompletableFuture future3 = CompletableFuture.supplyAsync(() -> { + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return "Result of Future 3"; + }); + + CompletableFuture anyOfFuture = CompletableFuture.anyOf(future1, future2, future3); + + System.out.println(anyOfFuture.get()); // Result of Future 2 + } + +} diff --git a/src/main/java/learning/CompletablefutureTutorial.java b/src/main/java/learning/CompletablefutureTutorial.java new file mode 100644 index 00000000..28bfa705 --- /dev/null +++ b/src/main/java/learning/CompletablefutureTutorial.java @@ -0,0 +1,69 @@ +package learning; + +import lombok.extern.log4j.Log4j2; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * https://www.callicoder.com/java-8-completablefuture-tutorial/ + */ +@Log4j2 +public class CompletablefutureTutorial { + + public static void main(String[] args) throws ExecutionException, InterruptedException { + List data = Arrays.asList("one", "two"); + + CompletablefutureTutorial ct = new CompletablefutureTutorial(); + ct.thenApplyTest(data); + } + + void thenApplyTest(List data) throws ExecutionException, InterruptedException { + CompletableFuture future = getStringCompletableFuture(); + CompletableFuture nfuture = + future.thenApply(n -> {return "enriched " + n;}) + .thenApply(g -> " 1 more " + g); + + System.out.println("new data:" + nfuture.get()); + } + + String supplyAsyncTest(List data) { + CompletableFuture future = getStringCompletableFuture(); + + String res = future.join(); + log.info("supplyAsync finished:" + res); + return res; + } + + private static CompletableFuture getStringCompletableFuture() { + CompletableFuture future = CompletableFuture.supplyAsync(new Supplier() { + + @Override + public String get() { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return "Get and return "; + } + }); + return future; + } + + void runAsyncTest(List data) { + + log.info("beginning"); + List> jobList = + data.stream().map(r -> CompletableFuture.runAsync(() -> { + log.info("running {}", r); + })).collect(Collectors.toList()); + jobList.stream().map(CompletableFuture::join).collect(Collectors.toList()); + } + +} diff --git a/src/main/java/learning/ExceptionInFutures.java b/src/main/java/learning/ExceptionInFutures.java new file mode 100644 index 00000000..2de35569 --- /dev/null +++ b/src/main/java/learning/ExceptionInFutures.java @@ -0,0 +1,29 @@ +package learning; + +import java.util.concurrent.CompletableFuture; + +public class ExceptionInFutures { + + public static void main(String[] args) { + + } + + void exceptionTest() { + CompletableFuture.supplyAsync(() -> { + // Code which might throw an exception + return "Some result"; + }).exceptionally(ex -> { + ex.printStackTrace(); + return ""; + }).thenApply(result -> { + return "processed result"; + }).exceptionally(eex -> { + return "xx"; + }).thenApply(result -> { + return "result after further processing"; + }).thenAccept(result -> { + // do something with the final result + }); + } + +} diff --git a/src/main/java/learning/FilterExample.java b/src/main/java/learning/FilterExample.java new file mode 100644 index 00000000..f0b180c8 --- /dev/null +++ b/src/main/java/learning/FilterExample.java @@ -0,0 +1,38 @@ +package learning; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; + +public class FilterExample { + + /** + * https://stackoverflow.com/questions/40720461/completablefutures-and-filtering-based-on-values-that-are-inside + */ + private CompletableFuture> convertToFutureOfStream(List> toConvert) { + return CompletableFuture.allOf(toConvert.stream().toArray(CompletableFuture[]::new)) + .thenApply( + v -> toConvert.stream().map(CompletableFuture::join) + ); + } + + + void method() { + +/* + CompletableFuture> toReturn = asyncCall() + .thenCompose(listOfStuff -> convertToFutureOfStream( + listOfStuff.stream() + .map(this::asyncCall2) + .collect(Collectors.toList()) + ) + .thenApply(stream -> + stream.filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()) + ) + ); +*/ + + } +} diff --git a/src/main/java/learning/GuideCompletableFuture.java b/src/main/java/learning/GuideCompletableFuture.java new file mode 100644 index 00000000..ef994ca1 --- /dev/null +++ b/src/main/java/learning/GuideCompletableFuture.java @@ -0,0 +1,24 @@ +package learning; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * https://www.baeldung.com/java-completablefuture + */ +public class GuideCompletableFuture { + + public static void main(String[] args) throws ExecutionException, InterruptedException { + new GuideCompletableFuture().guideFuture(); + } + + void guideFuture() throws ExecutionException, InterruptedException { + Future completableFuture = + CompletableFuture.completedFuture("Hello"); + + String res = completableFuture.get(); + System.out.println(res); + } + +} diff --git a/src/main/java/learning/OptionalTest.java b/src/main/java/learning/OptionalTest.java new file mode 100644 index 00000000..c670614f --- /dev/null +++ b/src/main/java/learning/OptionalTest.java @@ -0,0 +1,39 @@ +package learning; + +import java.util.Optional; + +/** + * https://www.callicoder.com/java-8-optional-tutorial/ + */ + +public class OptionalTest { + + public static void main(String[] args) { + new OptionalTest().optionalTest(); + + } + void optionalTest() { + Optional o = findUserId(""); + + o.ifPresentOrElse(f -> System.out.println(f), () -> {System.out.println("run in thread." + Thread.currentThread().getName());}); + + + User user1 = null; + + Optional optUser = Optional.ofNullable(user1); + + User finalUser = (user1 == null ? new User() : user1); + + finalUser = optUser.orElse(new User()); + Optional optUserName = optUser.map(User::getName); + Optional optUserPolo = optUserName.filter(a -> a.contains("Polo")); + + Optional val = Optional.ofNullable(null); + + } + + + Optional findUserId(String userid) { + return Optional.empty(); + } +} diff --git a/src/main/java/learning/README.md b/src/main/java/learning/README.md new file mode 100644 index 00000000..8b03268d --- /dev/null +++ b/src/main/java/learning/README.md @@ -0,0 +1,4 @@ +https://www.callicoder.com/java-8-completablefuture-tutorial/ + + +https://www.baeldung.com/java-completablefuture diff --git a/src/main/java/learning/ThenCombineFutures.java b/src/main/java/learning/ThenCombineFutures.java new file mode 100644 index 00000000..12e048ad --- /dev/null +++ b/src/main/java/learning/ThenCombineFutures.java @@ -0,0 +1,44 @@ +package learning; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public class ThenCombineFutures { + + public static void main(String[] args) throws ExecutionException, InterruptedException { + new ThenCombineFutures().thenCombineTest(); + } + + void thenCombineTest() throws ExecutionException, InterruptedException { + System.out.println("Retrieving weight."); + CompletableFuture weightInKgFuture = CompletableFuture.supplyAsync(() -> { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return 65.0; + }); + + System.out.println("Retrieving height."); + CompletableFuture heightInCmFuture = CompletableFuture.supplyAsync(() -> { + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } + return 177.8; + }); + + System.out.println("Calculating BMI."); + CompletableFuture combinedFuture = weightInKgFuture.thenCombine( + heightInCmFuture, + (weightInKg, heightInCm) -> { + Double heightInMeter = heightInCm / 100; + return weightInKg / (heightInMeter * heightInMeter); + }); + + System.out.println("Your BMI is - " + combinedFuture.get()); + } +} diff --git a/src/main/java/learning/ThenComposeFutures.java b/src/main/java/learning/ThenComposeFutures.java new file mode 100644 index 00000000..59403a45 --- /dev/null +++ b/src/main/java/learning/ThenComposeFutures.java @@ -0,0 +1,49 @@ +package learning; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +public class ThenComposeFutures { + + public static void main(String[] args) throws ExecutionException, InterruptedException { + new ThenComposeFutures().thenComposeTest(); + } + + void thenComposeTest() throws ExecutionException, InterruptedException { + String userId = "name"; + + CompletableFuture> result = + getUsersDetail(userId).thenApply(user -> getCreditRating(user)); + + CompletableFuture result2 = + getUsersDetail(userId).thenCompose(user -> getCreditRating(user)); + + System.out.println(result.get()); + } + + CompletableFuture getUsersDetail(String userId) { + return CompletableFuture.supplyAsync(() -> { + return UserService.getUserDetails(userId); + }); + } + + CompletableFuture getCreditRating(User user) { + return CompletableFuture.supplyAsync(() -> { + return CreditRatingService.getCreditRating(user); + }); + } + + private static class UserService { + + public static User getUserDetails(String userId) { + return new User(); + } + } + + private static class CreditRatingService { + + public static Double getCreditRating(User user) { + return 10.40; + } + } +} diff --git a/src/main/java/learning/User.java b/src/main/java/learning/User.java new file mode 100644 index 00000000..d9a645a7 --- /dev/null +++ b/src/main/java/learning/User.java @@ -0,0 +1,13 @@ +package learning; + +public class User { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/log4j2.xml b/src/main/java/log4j2.xml new file mode 100644 index 00000000..cc7f655b --- /dev/null +++ b/src/main/java/log4j2.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +