Я хочу пройтись по пространству поиска асинхронной функции. Я закодировал логику следующим образом:
/**
* Assuming that a function maps a range of inputs to the same output value, minimizes the input value while
* maintaining the output value.
*
* @param previousInput the last input known to return {@code target}
* @param currentInput the new input value to evaluate
* @param function maps an input to an output value
* @param target the expected output value
* @return the minimum input value that results in the {@code target} output value
* <br>{@code @throws NullPointerException} if any argument is null
* <br>{@code @throws IllegalArgumentException} if {@code stepSize} is zero}
*/
private static CompletionStage<BigDecimal> optimizeInput(BigDecimal previousInput,
BigDecimal currentInput,
BigDecimal stepSize,
Function<BigDecimal, CompletionStage<BigDecimal>> function,
BigDecimal target)
{
return function.apply(currentInput).thenCompose(output ->
{
assertThat("stepSize", stepSize).isNotZero();
int outputMinusTarget = output.compareTo(target);
if (outputMinusTarget != 0)
return CompletableFuture.completedFuture(previousInput);
BigDecimal nextInput = currentInput.add(stepSize);
if (nextInput.compareTo(BigDecimal.ZERO) < 0)
return CompletableFuture.completedFuture(previousInput);
return optimizeInput(currentInput, nextInput, stepSize, function, target);
});
}
К сожалению, если функция имеет большое пространство поиска, это вызовет StackoverflowError после некоторых итераций. Можно ли итеративно пройтись по пространству поиска со стеком фиксированного размера?
function
на самом деле асинхронный? В противном случае это делаетoptimizeInput()
простым рекурсивным методом. Кроме того, кажется, что вы ничего не распараллеливаете в этом коде, поэтому не проще ли было бы реализовать это без использованияCompletableFuture
(может быть, просто оберните первоначальный вызов вsupplyAsync()
). Было бы неплохо предоставить образецfunction
и соответствующую трассировку стека. - person Didier L   schedule 26.04.2018function
может быть синхронным или асинхронным. Разные вызывающие абоненты передают функции разного типа. Код не знает заранее, но он должен обрабатывать оба случая безStackoverflowError
. - person Gili   schedule 27.04.2018