CompletionStage: почему allOf или anyOf определено в CompletableFuture

У меня есть фреймворк, использующий интерфейс CompletionStage и мне любопытно, почему вспомогательные методы anyOf или allOf находятся в CompletableFuture определены там.

Похоже, они должны работать на интерфейсах, а не на реализации?

Я пока очень недоволен интерфейсом CompletionStage. Существуют ли другие библиотеки Java, совместимые с CompletionStage, но кто-то может порекомендовать другой интерфейс расширенного набора?

Или, может быть, какая-то библиотека, написанная с дополнительными вспомогательными методами для работы с CompletionStage?


person Setheron    schedule 22.02.2016    source источник
comment
Ответ кворы quora.com / упоминает, что allOf и anyOf являются статическими и не могут быть переопределены подклассами, и поэтому получают специальную (более безопасную) обработку   -  person tkruse    schedule 20.04.2018


Ответы (2)


Если все, что вам нужно, это метод, предоставляющий те же функции anyOf и allOf для объектов типа CompletionStage, вы можете просто прибегнуть к 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));
}
person Holger    schedule 22.02.2016
comment
Мой вопрос больше о том, почему этих функций нет даже в интерфейсе. Похоже на ошибку разработчиков JDK. - person Setheron; 22.02.2016
comment
Поскольку это необязательный метод, он неуместен для фреймворка. - person Ben Manes; 23.02.2016
comment
@BenManes Что необязательно? Они добавили, что в реализации CompletableFuture это просто кажется неправильным. - person Setheron; 23.02.2016
comment
Реализация CompletionStage, которая не хочет взаимодействовать с другими, может вызвать исключение {@code UnsupportedOperationException}. Например, до недавнего времени адаптеры Scala Future не поддерживали этот метод. Безопасно только тогда, когда вы создали будущее. - person Ben Manes; 23.02.2016
comment
@BenManes: Но некоторые методы CompletableFuture все равно вызывают toCompletableFuture, например, applyToEither...(), acceptEither...(), thenCombine...(), thenAccept...() и так далее. Они вызывают его в аргументе CompletionStage, реализация которого неизвестна. Почему allOf() и anyOf() являются особыми случаями? - person tkruse; 20.04.2018
comment
@tkruse правда, я думаю, что это было необязательно, и на самом деле его больше нет в JDK10. Раньше он заявлял that does not choose to interoperate with others, чтобы обеспечить свободу действий при серьезных несовместимостях. - person Ben Manes; 20.04.2018

Вот что я придумал

/**
 * 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;
    }

}
person Setheron    schedule 22.02.2016