Skip to content
Advertisement

Trying to update a CompletableFuture variable but get error : local variables referenced from a lambda expression must be final or effectively final

public CompletableFuture<String> description() {
    CompletableFuture<String> result = CompletableFuture
            .supplyAsync(() -> "Search for: " + this.stop + " <-> " + name + ":n")
            .thenApply(x -> x += "From " +  this.stop + "n");

    CompletableFuture<Void> temp = services.thenAccept(x -> {
      for (BusService service : x.keySet()) {
        CompletableFuture<Set<BusStop>> stops = x.get(service);
        result = result.thenApply(y -> y += describeService(service, stops));
      }
    });
    return result;
  }

  
  public CompletableFuture<String> describeService(BusService service,
                                                   CompletableFuture<Set<BusStop>> stops) {

    return stops.thenApply(x -> {
      if (x.isEmpty()) {
        return "";
      }
      return x.stream()
              .filter(stop -> stop != this.stop)
              .reduce("- Can take " + service + " to:n",
                      (str, stop) -> str += "  - " + stop + "n",
                      (str1, str2) -> str1 + str2);
    });

  }

I was trying to update the result in the forloop in description(), since result.thenApply() results in a new CompletableFuture instance, I need to reassign it to a new variable in order to update result, but i am not very sure how

Advertisement

Answer

You don’t need to reassign it to a new variable, and you shouldn’t. Combine the futures instead.

return services.thenCombine(result, (x, y) -> {
  for (BusService service : x.keySet()) {
    CompletableFuture<Set<BusStop>> stops = x.get(service);
    y += describeService(service, stops);
  }
  return y;
});
Advertisement