From d9568bafae72d673a8e01bb9fc47828185139340 Mon Sep 17 00:00:00 2001 From: Jerry Lee Date: Sat, 20 Apr 2024 19:10:35 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20use=20normal=20array=20list=20inste?= =?UTF-8?q?ad=20of=20immutable(`Collections#emptyList`)=20or=20fixed-size(?= =?UTF-8?q?`Arrays#asList`)=20list=20=E2=9B=91=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Safer for application codes which may reuse the returned list as normal collection. --- .../java/io/foldright/cffu/CffuFactory.java | 13 ++--- .../cffu/CompletableFutureUtils.java | 48 +++++++++++-------- .../foldright/cffu/kotlin/CffuExtensions.kt | 24 ++++------ .../kotlin/CompletableFutureExtensions.kt | 12 ++--- 4 files changed, 43 insertions(+), 54 deletions(-) diff --git a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java index 94f7792d..51f71ec5 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CffuFactory.java @@ -12,7 +12,6 @@ import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.concurrent.ThreadSafe; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; @@ -591,8 +590,7 @@ public Executor delayedExecutor(long delay, TimeUnit unit, Executor executor) { * Returns a new Cffu that is completed when all the given Cffus complete. * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. - * If no Cffus are provided, returns a Cffu completed - * with the value {@link java.util.Collections#emptyList() emptyList}. + * If no Cffus are provided, returns a Cffu completed with the value empty list. *

* Same to {@link #allOf(Cffu[])}, but the returned Cffu * contains the results of input Cffus. @@ -613,8 +611,7 @@ public final Cffu> cffuAllOf(Cffu... cfs) { * the new Cffu is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value {@link java.util.Collections#emptyList() emptyList}. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. *

* Same as {@link #cffuAllOf(Cffu[])} with overloaded argument type {@link CompletableFuture}. * @@ -647,8 +644,7 @@ public Cffu> cffuAllOf() { * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given Cffus, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value {@link Collections#emptyList() emptyList}. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. * * @param cfs the CompletableFutures * @return a new CompletableFuture that is successful when all the given CompletableFutures success @@ -668,8 +664,7 @@ public final Cffu> cffuAllOfFastFail(Cffu... cfs) { * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given CompletableFutures, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value {@link Collections#emptyList() emptyList}. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. *

* Same as {@link #cffuAllOfFastFail(Cffu[])} with overloaded argument type {@link CompletableFuture}. * diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index f0087d3b..bf97ba37 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -10,8 +10,8 @@ import org.jetbrains.annotations.Contract; import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.concurrent.*; import java.util.function.Function; @@ -37,8 +37,7 @@ public final class CompletableFutureUtils { * CompletableFutures, the new CompletableFuture is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so, with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a CompletableFuture completed - * with the value {@link Collections#emptyList() emptyList}. + * If no CompletableFutures are provided, returns a CompletableFuture completed with the value empty list. *

* Same to {@link CompletableFuture#allOf(CompletableFuture[])}, * but the returned CompletableFuture contains the results of the given CompletableFutures. @@ -54,8 +53,8 @@ public final class CompletableFutureUtils { public static CompletableFuture> allOfWithResult(CompletableFuture... cfs) { requireCfsAndEleNonNull(cfs); final int size = cfs.length; - if (size == 0) return CompletableFuture.completedFuture(Collections.emptyList()); - if (size == 1) return cfs[0].thenApply(Arrays::asList); + if (size == 0) return CompletableFuture.completedFuture(arrayList()); + if (size == 1) return cfs[0].thenApply(CompletableFutureUtils::arrayList); final Object[] result = new Object[size]; @@ -66,7 +65,7 @@ public static CompletableFuture> allOfWithResult(CompletableFuture (List) Arrays.asList(result)); + .thenApply(unused -> (List) arrayList(result)); } /** @@ -109,8 +108,7 @@ public static CompletableFuture allOfFastFail(CompletableFuture... cfs) * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so *without* waiting other incomplete given CompletableFutures, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a CompletableFuture completed - * with the value {@link Collections#emptyList() emptyList}. + * If no CompletableFutures are provided, returns a CompletableFuture completed with the value empty list. *

* Same to {@link #allOfFastFail(CompletableFuture[])}, * but the returned CompletableFuture contains the results of the given CompletableFutures. @@ -126,8 +124,8 @@ public static CompletableFuture allOfFastFail(CompletableFuture... cfs) public static CompletableFuture> allOfFastFailWithResult(CompletableFuture... cfs) { requireCfsAndEleNonNull(cfs); final int size = cfs.length; - if (size == 0) return CompletableFuture.completedFuture(Collections.emptyList()); - if (size == 1) return cfs[0].thenApply(Arrays::asList); + if (size == 0) return CompletableFuture.completedFuture(arrayList()); + if (size == 1) return cfs[0].thenApply(CompletableFutureUtils::arrayList); final CompletableFuture[] successOrBeIncomplete = new CompletableFuture[size]; // NOTE: fill ONE MORE element of failedOrBeIncomplete LATER @@ -148,6 +146,17 @@ private static void requireCfsAndEleNonNull(CompletableFuture... cfs) { } } + /** + * Returns normal array list instead of unmodifiable or fixed-size list. + * Safer for application code which may reuse the returned list as normal collection. + */ + @SuppressWarnings("unchecked") + private static List arrayList(T... elements) { + List ret = new ArrayList<>(elements.length); + ret.addAll(Arrays.asList(elements)); + return ret; + } + @SuppressWarnings({"unchecked", "rawtypes"}) private static void fill(CompletableFuture[] cfs, CompletableFuture[] successOrBeIncomplete, @@ -609,7 +618,7 @@ public static CompletableFuture exceptionallyAsync( public static CompletableFuture exceptionallyAsync( CompletableFuture cf, Function fn, Executor executor) { if (IS_JAVA12_PLUS) { - return (cf.exceptionallyAsync(fn, executor)); + return cf.exceptionallyAsync(fn, executor); } // below code is copied from CompletionStage#exceptionallyAsync @@ -631,8 +640,7 @@ public static CompletableFuture exceptionallyAsync( */ public static CompletableFuture orTimeout(CompletableFuture cf, long timeout, TimeUnit unit) { if (IS_JAVA9_PLUS) { - cf.orTimeout(timeout, unit); - return cf; + return cf.orTimeout(timeout, unit); } // below code is copied from CompletableFuture#orTimeout with small adoption @@ -656,8 +664,7 @@ public static CompletableFuture orTimeout(CompletableFuture cf, long t public static CompletableFuture completeOnTimeout( CompletableFuture cf, @Nullable T value, long timeout, TimeUnit unit) { if (IS_JAVA9_PLUS) { - cf.completeOnTimeout(value, timeout, unit); - return cf; + return cf.completeOnTimeout(value, timeout, unit); } // below code is copied from CompletableFuture#completeOnTimeout with small adoption @@ -683,7 +690,7 @@ public static CompletableFuture completeOnTimeout( public static CompletableFuture exceptionallyCompose( CompletableFuture cf, Function> fn) { if (IS_JAVA12_PLUS) { - return (cf.exceptionallyCompose(fn)); + return cf.exceptionallyCompose(fn); } // below code is copied from CompletionStage.exceptionallyCompose @@ -911,8 +918,7 @@ public static CompletableFuture completeAsync(CompletableFuture cf, Su public static CompletableFuture completeAsync( CompletableFuture cf, Supplier supplier, Executor executor) { if (IS_JAVA9_PLUS) { - cf.completeAsync(supplier, executor); - return cf; + return cf.completeAsync(supplier, executor); } // below code is copied from CompletableFuture#completeAsync with small adoption @@ -971,9 +977,9 @@ public static CompletableFuture copy(CompletableFuture cf) { @Contract(pure = true) public static CompletableFuture newIncompleteFuture(CompletableFuture cf) { if (IS_JAVA9_PLUS) { - return (cf.newIncompleteFuture()); + return cf.newIncompleteFuture(); } - return (new CompletableFuture<>()); + return new CompletableFuture<>(); } //# Getter methods @@ -1006,7 +1012,7 @@ static Executor screenExecutor(Executor e) { return requireNonNull(e, "defaultExecutor is null"); } - private static final boolean USE_COMMON_POOL = (ForkJoinPool.getCommonPoolParallelism() > 1); + private static final boolean USE_COMMON_POOL = ForkJoinPool.getCommonPoolParallelism() > 1; /** * Fallback if ForkJoinPool.commonPool() cannot support parallelism diff --git a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt index db91cb65..fddebfe0 100644 --- a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt +++ b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CffuExtensions.kt @@ -68,8 +68,7 @@ private const val ERROR_MSG_FOR_ARRAY = "no cffuFactory argument provided when t * the new Cffu is completed when all the given Cffus complete. * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. - * If no Cffus are provided, returns a Cffu completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no Cffus are provided, returns a Cffu completed with the value empty list. * * Same as [allOfCffuVoid], but the returned Cffu contains the results of input Cffus. * Same as [CffuFactory.cffuAllOf], providing this method is convenient for method chaining. @@ -91,8 +90,7 @@ fun Collection>.allOfCffu(cffuFactory: CffuFactory = ABSENT): Cffu Array>.allOfCffu(cffuFactory: CffuFactory = ABSENT): Cffu Collection>.allOfCffu(cffuFactory: CffuFactory): Cf * the new Cffu is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so, with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. * * Same as [allOfCffuVoid], but the returned Cffu contains the results of input CompletableFutures. * Same as [CffuFactory.cffuAllOf], providing this method is convenient for method chaining. @@ -228,8 +224,7 @@ fun Array>.allOfCffuVoid(cffuFactory: CffuFactory): Cff * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given Cffus, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. * * Same as [allOfFastFailCffuVoid], but the returned Cffu contains the results of input Cffus. * Same as [CffuFactory.cffuAllOfFastFail], providing this method is convenient for method chaining. @@ -252,8 +247,7 @@ fun Collection>.allOfFastFailCffu(cffuFactory: CffuFactory = ABSENT) * If any of the given Cffus complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given Cffus, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. * * Same as [allOfFastFailCffuVoid], but the returned Cffu contains the results of input Cffus. * Same as [CffuFactory.cffuAllOfFastFail], providing this method is convenient for method chaining. @@ -276,8 +270,7 @@ fun Array>.allOfFastFailCffu(cffuFactory: CffuFactory = ABSENT): Cff * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given CompletableFutures, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. * * Same as [allOfFastFailCffuVoid], but the returned Cffu contains the results of input Cffus. * Same as [CffuFactory.cffuAllOfFastFail], providing this method is convenient for method chaining. @@ -295,8 +288,7 @@ fun Collection>.allOfFastFailCffu(cffuFactory: CffuFact * If any of the given CompletableFutures complete exceptionally, then the returned Cffu * also does so *without* waiting other incomplete given CompletableFutures, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a Cffu completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a Cffu completed with the value empty list. * * Same as [allOfFastFailCffuVoid], but the returned Cffu contains the results of input Cffus. * Same as [CffuFactory.cffuAllOfFastFail], providing this method is convenient for method chaining. diff --git a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt index abadbc9b..0c606add 100644 --- a/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt +++ b/cffu-kotlin/src/main/java/io/foldright/cffu/kotlin/CompletableFutureExtensions.kt @@ -31,8 +31,7 @@ import java.util.concurrent.TimeUnit * CompletableFutures, the returned new CompletableFuture is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so, with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a CompletableFuture completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a CompletableFuture completed with the value empty list. * * Same as [allOfCompletableFutureVoid], * but the returned CompletableFuture contains the results of input CompletableFutures. @@ -49,8 +48,7 @@ fun Collection>.allOfCompletableFuture(): CompletableFu * CompletableFutures, the returned new CompletableFuture is completed when all the given CompletableFutures complete. * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so, with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a CompletableFuture completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a CompletableFuture completed with the value empty list. * * Same as [allOfCompletableFutureVoid], * but the returned CompletableFuture contains the results of input CompletableFutures. @@ -112,8 +110,7 @@ fun Array>.allOfCompletableFutureVoid(): CompletableFut * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so *without* waiting other incomplete given CompletableFutures, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a CompletableFuture completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a CompletableFuture completed with the value empty list. * * Same as [allOfFastFailCompletableFutureVoid], * but the returned CompletableFuture contains the results of input CompletableFutures. @@ -131,8 +128,7 @@ fun Collection>.allOfFastFailCompletableFuture(): Compl * If any of the given CompletableFutures complete exceptionally, then the returned CompletableFuture * also does so *without* waiting other incomplete given CompletableFutures, * with a CompletionException holding this exception as its cause. - * If no CompletableFutures are provided, returns a CompletableFuture completed - * with the value [emptyList][java.util.Collections.emptyList]. + * If no CompletableFutures are provided, returns a CompletableFuture completed with the value empty list. * * Same as [allOfFastFailCompletableFutureVoid], * but the returned CompletableFuture contains the results of input CompletableFutures.