Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert looping into lambda and throw exception

How can i write below code using lambda expression in java8. I am new to Java 8.

for (GlobalPricingRequest globalPricingRequest : globalPricingRequests) {
    BigDecimal feePerTrans = globalPricingRequest.getFeePerTransact();
    if (feePerTrans != null && feePerTrans.intValue() < 0) {
        throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
    }
    List<EventTypePricingMapping> eventTypePricingMappings = globalPricingRequest.getEventTypePricingList();
    for (EventTypePricingMapping eventTypePricingMapping : eventTypePricingMappings) {
        BigDecimal feePerRevenue = eventTypePricingMapping.getFeePerRevenue();
        if (feePerRevenue != null && feePerRevenue.intValue() < 0) {
            throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
        }
        if (eventTypePricingMapping.getFeePerRevenue().intValue() < 0) {
            throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
        }
    }
}

I have tried the below code as yet as per the suggestion . Is there any other thing which we can improve in this code to write it using lambdas more.

globalPricingRequests.forEach((globalPricingRequest) -> {
    if (checkIfValueLessThanZero(globalPricingRequest.getFeePerTransact())) {
        throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
    }
    List<EventTypePricingMapping> eventTypePricingMappings = globalPricingRequest.getEventTypePricingList();
    eventTypePricingMappings.forEach((eventTypePricingMapping) -> {
        if (checkIfValueLessThanZero(eventTypePricingMapping.getFeePerRevenue())) {
            throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
        }
        if (checkIfValueLessThanZero(eventTypePricingMapping.getFeePerReg())) {
            throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
        }
    });
});


private boolean checkIfValueLessThanZero(Object object) {
    if (object instanceof BigDecimal) {
       if (object != null && ((BigDecimal) object).intValue() < 0) {
           return true;
       }
    }
    return false;
}
like image 814
Ishant Gaurav Avatar asked Jan 05 '19 11:01

Ishant Gaurav


People also ask

Can we throw exceptions in lambda expression?

A lambda expression body can't throw any exceptions that haven't specified in a functional interface. If the lambda expression can throw an exception then the "throws" clause of a functional interface must declare the same exception or one of its subtype.

How do you handle exception thrown by lambda expression?

Because IOException is a checked exception, we must handle it explicitly. We have two options. First, we may simply throw the exception outside of our method and take care of it somewhere else. Alternatively, we can handle it inside the method that uses a lambda expression.

Which exception is not supported by Lambda?

A lambda expression for this functional interface can't throw CheckedExceptions.


1 Answers

Problem

Your problem is not with lambdas, but with code organisation. You have a data, i.e. List<GlobalPricingRequest> and a set of validation rules. All you need to do it to apply these valdation rules to the given data.

This approach give you flexibility to add or remove validation rules easily. And test or check each rule separately.

Solution

Optimal solution is to split each validation into separate class.

First, create a manager and interface for validation rule:

public final class GlobalPricingRequestValidationManager {

    private final List<ValidationRule> validationRules =
            Arrays.asList(
                new TransactionFeeEqualOrGreaterThanZeroValidationRule(),
                new RevenueFeeEqualOrGreaterThanZeroValidationRule());

    public void validate(List<GlobalPricingRequest> globalPricingRequests) {
        validationRules.forEach(validationRule -> validationRule.validate(globalPricingRequests));
    }

    public interface ValidationRule {

        void validate(List<GlobalPricingRequest> globalPricingRequests);
    }

}

Second, implement each validation rule in the separate class (was added to the manager):

public final class TransactionFeeEqualOrGreaterThanZeroValidationRule implements GlobalPricingRequestValidationManager.ValidationRule {

    @Override
    public void validate(List<GlobalPricingRequest> globalPricingRequests) {
        if (globalPricingRequests.stream()
                                 .map(GlobalPricingRequest::getFeePerTransact)
                                 .filter(Objects::nonNull)
                                 .anyMatch(val -> val.signum() == -1)))
            throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
    }
}

public final class RevenueFeeEqualOrGreaterThanZeroValidationRule implements GlobalPricingRequestValidationManager.ValidationRule {

    @Override
    public void validate(List<GlobalPricingRequest> globalPricingRequests) {
        if (globalPricingRequests.stream()
                                 .map(GlobalPricingRequest::getEventTypePricingList)
                                 .flatMap(List::stream)
                                 .map(EventTypePricingMapping::getFeePerRevenue)
                                 .filter(Objects::nonNull)
                                 .anyMatch(val -> val.signum() == -1)))
            throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");

    }
}

Clinet code:

GlobalPricingRequestValidationManager validationManager = new GlobalPricingRequestValidationManager();
List<GlobalPricingRequest> globalPricingRequests = Collections.emptyList();
validationManager.validate(globalPricingRequests);
like image 142
oleg.cherednik Avatar answered Oct 13 '22 00:10

oleg.cherednik