I have a method in Java which should return a CompletableFuture<Boolean<> and I have some issues with the case when it is supposed to be true. My Method is below:
@Override
public CompletableFuture<Boolean> process(String name, Object data, Object message) {
switch (name) {
case ("first"):
Map<String, Long> finalAmount = (Map<String, Long>) data;
finalAmount.forEach((id, amount) -> {
event.retrieveEvent(id)
.thenCompose(config -> {
update(id, amount, config);
return CompletableFuture.completedFuture(true);
});
});
}
return CompletableFuture.completedFuture(false);
}
The problem is that I have a map and I have to iterate over it and do something for each value. Even though it always enters the part with "CompletableFuture.completedFuture(true)" - in the end, it always goes to the final "return CompletableFuture.completedFuture(false)" and it returns false instead of true.
What can I do and how should I rewrite my method in order to return true after the map elements finish and for each one, everything worked and it returned true?
The code never stops to wait for the result of the case case("first")
, so it will schedule a CompletableFuture
to compute it and continue to the return CompletableFuture.completedFuture(false);
.
This is one possible solution:
@Override
public CompletableFuture<Boolean> process(String name, Object data, Object message) {
switch (name) {
case ("first"):
CompletableFuture<Void> result = CompletableFuture.completedFuture( null );
Map<String, Long> finalAmount = (Map<String, Long>) data;
finalAmount.forEach((id, amount) -> {
result = result
.thenCompose(v -> event.retrieveEvent(id))
.thenAccept(config -> update(id, amount, config));
});
return result.thenApply(v -> Boolean.TRUE);
}
return CompletableFuture.completedFuture(Boolean.FALSE);
}
If you want to run all the tasks in parallel, an alternative solutions is:
@Override
public CompletableFuture<Boolean> process(String name, Object data, Object message) {
switch (name) {
case ("first"):
Map<String, Long> finalAmount = (Map<String, Long>) data;
CompletableFuture<Void>[] futures = new CompletableFuture<>[finalAmount.size()];
AtomicInteger index = new AtomicInteger();
finalAmount.forEach((id, amount) -> {
futures[index.getAndIncrement()] = event
.retrieveEvent(id)
.thenAccept(config -> update(id, amount, config));
});
return CompletableFuture
.allOf(futures)
.thenApply(v -> Boolean.TRUE);
}
return CompletableFuture.completedFuture(Boolean.FALSE);
}
Assuming that everything is thread-safe.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.