'Filtering a stream of CompletableFuture<SomeObject> on some attribute of SomeObject

I have a Stream of CompletableFuture of SomeObject and I'm trying to filter this on some attribute of SomeObject and I can't seem to find a satisfying way to filter this.

public class SomeObject {
    private String someAttribute;

    public String getSomeAttribute() {
        return someAttribute;
    } 
}

I tried this, but I'm wondering if there is a non-blocking way ?

  public List<CompletableFuture<SomeObject>> filterStream(Stream<CompletableFuture<SomeObject>> stream) {
        return stream.filter(futureSomeObject -> {
            try {
                return futureSomeObject.get().getSomeAttribute().equals("SOMETHING");
            } catch (InterruptedException | ExecutionException e) {
                return false;
            }
        }).toList();
  }

I also thought of something like this, but I'll need to change the return signature :

stream.map(CompletableFuture::join).filter(object -> object.getSomeAttribute().equals("SOMETHING")).toList();


Solution 1:[1]

If you absolutely must keep the return type you can map back from List<SomeObject> to List<CompletableFuture<SomeObject>> in your second approach:

stream
    .map(CompletableFuture::join)
    .filter(object -> object.getSomeAttribute().equals("SOMETHING"))
    .map(CompletableFuture::completedFuture)
    .toList();

Note that this approach is still blocking though. A simple way to obtain a unblocking solution is wrapping your second approach itself into a CompletableFuture. However this would also impact the return type and turn it into CompletableFuture<List<SomeObject>>.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1