I have the following list
List<CompletableFuture<Name>> myList;
The Name class contains the following properties.
String name;
boolean available;
How can I count the total number of name objects which have the available property set to true?
I have the following list
List<CompletableFuture<Name>> myList;
The Name class contains the following properties.
String name;
boolean available;
How can I count the total number of name objects which have the available property set to true?
You first need to wait for the completion of the Futures, then you could can filter() the ones with available set to true and last but not least count() the amount of list items left. For all of that I am using the Java Stream API.
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
public class Main {
record Name(String name, boolean available){};
public static void main(String[] args) {
var input = new ArrayList<CompletableFuture<Name>>();
input.add(CompletableFuture.completedFuture(new Name("Thomas", true)));
input.add(CompletableFuture.completedFuture(new Name("John", true)));
input.add(CompletableFuture.completedFuture(new Name("Pat", false)));
var total = input.stream()
.map(CompletableFuture::join)
.filter(name -> name.available)
.count();
System.out.println(total);
}
}
Expected output:
2
In terms of waiting for the Futures to complete have a look at this StackOverflow thread which discusses some of the available options and their behavior in more detail.
Getting the result synchronously is easy.
static int countNames(List<CompletableFuture<Name>> names) {
int count = 0;
for (CompletableFuture<Name> futureName: names) {
if (futureName.join().available) { // this is where you'd get exceptions
count++;
}
}
return count;
}
The only problem is that you'll get exceptions propagated to you, and you'll have to wait for every future to complete in order.
This method gives you a result that is also a Future, allowing you to continue a promise-like flow.
static Future<Integer> countNames(List<CompletableFuture<Name>> names) {
CompletableFuture<Integer> tally = CompletableFuture.completedFuture(0);
for (CompletableFuture<Name> futureName: names) {
tally = futureName.thenCombine(tally, (name, count) -> name.available ? count + 1 : count);
}
return tally;
}