Вопрос

I need to create list of Callable with each have int parameter from range [1..99) with execute one method. My initial idea was:

List<Callable<Double>> list = new ArrayList<>(100);
IntStream.range(1, 99).forEach(i -> list.add(() -> calculateResult(i)));

Next idea was to collect items to list:

List<Callable<Double>> list = IntStream.range(1, 99).mapToObj(value -> (() -> calculateResult(value))).collect(Collectors.toList());

It looks good, but in mapToObj function doesn't recognize inner lambda as Callable<Double>. If I use typical inner class like this it works:

   List<Callable<Double>> list = IntStream.range(1, 99).mapToObj(new IntFunction<Callable<Double>>() {
        @Override
        public Callable<Double> apply(int value) {
            return () -> calculateResult(value);
        }
    }).collect(Collectors.toList());

Is there any way to pass return type to lambda expression?

Это было полезно?

Решение

Are you in search of something like this?

public static void main(String[] args) {
    List<Callable<Double>> list = IntStream.range(1, 99)
            .<Callable<Double>>mapToObj(value -> callableFactory(value))
            .collect(Collectors.toList());
}

public static Callable<Double> callableFactory(int value) {
    return new Callable<Double>() {
        @Override public Double call() { return calculateResult(value); }
    };
}

public static Double calculateResult(int value) {
    return Math.random();
}

Другие советы

Insert a cast and your solution compiles:

List<Callable<Double>> list = IntStream.range(1, 99)
    .mapToObj(value -> (Callable<Double>) (() -> calculateResult(value)))
    .collect(Collectors.toList());

You can do it the following way:

public double calculateResult(int value) {
    return 0.0d;
}

List<Callable<Double>> list = IntStream.range(1, 99)
        .<Callable<Double>>mapToObj(value -> (() -> calculateResult(value)))
        .collect(Collectors.toList());

The change I have applied here is that I explicitely type the mapToObj call, as you want to have the stream mapped to a Stream<Callable<Double>>, you will need to give explicit types, this is how you do it.

I am still trying to figure out why the explicit types are needed at all.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top