简体   繁体   中英

Streams - Filter all not throwing exception

Let's say I have a stream of Reports and I have a method that checks if the user has rights to read each report. This method will throw an exception if the user doesn't have the rights

checkReadAuthorization(Report report) throw AccessViolationException;

Is there a way to filter out all Reports for which this method throws an exception? Something like:

reports.stream()
.filterThrowingException(this::checkReadAuthorization);

Now I have a function which returns true or false if the exception is thrown but I am wondering if there is a better way to achieve this

private boolean checkAuthorization(Report report) {
    try {
        checkReadAuthorization(report);
        return true;
    } catch(AccessViolationException ex) {
        return false;
    }
}

and then I used it in a filter like this

return dossiers.stream()
    .filter(this::checkAuthorization)
    .collect(Collectors.toList());

There is nothing like " filterThrowingException " in the current Stream-API. You can do only to make a decision to keep or filter out the Report using try-catch inside the Stream::filter :

List<Report> filtered = list.stream().filter(report -> {
    try {
        this.checkAuthorization(report);
    } catch (AccessViolationException ex) {
        return false;
    }
    return true;
}).collect(Collectors.toList());

Personally, I recommend changing the interface of the method checkReadAuthorization to return boolean indicating whether the input is valid or not.

private boolean checkReadAuthorization(Report report) { /* ... */ }

this result can be used as a predicate in the filter.

List<Report> filtered = list.stream()
                            .filter(this::checkReadAuthorization)
                            .collect(Collectors.toList());

Summary: Better change the design of the validation classes and methods instead of trying Stream-API to adapt what is not optimal.

I would swap checkReadAuthorization and checkAuthorization :

private boolean checkAuthorization(Report report) 
{
    // put here the logic that checks for authorization, but without throwing exception
}

void checkReadAuthorization(Report report) throw AccessViolationException
{
    if (!checkAuthorization(report)) {
        throw new AccessViolationException ();
    }
}

This way you don't use an exception as a condition.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM