CompletionStage: Why is allOf or anyOf defined in

2019-05-04 21:06发布

问题:

I have a framework that uses the interface CompletionStage and I'm curious why the helper methods anyOf or allOf found in CompletableFuture are defined there.

Seems like they should be operating on the interfaces rather than the implementation ?

I'm quite dissatisfied with the CompletionStage interface thus far. Are there other Java libraries that are CompletionStage compliant but a different superset interface someone can recommend?

Or perhaps some library written with additional helper methods for working with CompletionStage ?

回答1:

If all you want, is a method providing the same anyOf and allOf functionality for objects of the type CompletionStage, you can simply resort to toCompletableFuture:

public static CompletionStage<Object> anyOf(CompletionStage<?>... css) {
    return CompletableFuture.anyOf(Arrays.stream(css)
        .map(CompletionStage::toCompletableFuture).toArray(CompletableFuture[]::new));
}
public static CompletionStage<Void> allOf(CompletionStage<?>... css) {
    return CompletableFuture.allOf(Arrays.stream(css)
        .map(CompletionStage::toCompletableFuture).toArray(CompletableFuture[]::new));
}


回答2:

Here is what I've come up with

/**
 * A class with several helper methods for working with {@link CompletionStage}
 */
public class CompletionStages {


    public static CompletionStage<Object> anyOf(CompletionStage... completionStages) {
        if (completionStages == null) {
            throw new IllegalArgumentException("You must pass a non-null argument for completionStages");
        }
        if (completionStages.length == 0) {
            throw new IllegalArgumentException("You must pass a non-empty argument for completionStages");
        }

        CompletableFuture result = new CompletableFuture();
        for(CompletionStage completionStage : completionStages) {
            completionStage.thenAccept( r -> result.complete(r));
        }
        return result;
    }


    public static CompletionStage<Void> allOf(CompletionStage... completionStages) {
        if (completionStages == null) {
            throw new IllegalArgumentException("You must pass a non-null argument for completionStages");
        }
        if (completionStages.length == 0) {
            throw new IllegalArgumentException("You must pass a non-empty argument for completionStages");
        }

        CompletionStage result = CompletableFuture.completedFuture(null);
        for(int i = 0; i < completionStages.length; i++) {
            CompletionStage curr = completionStages[i];
            result = result.thenAcceptBoth(curr, (o, o2) -> {});
        }
        return result;
    }

}