如何在Java8中使用Lambda表达式编写以下代码。我是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");
}
}
}
我已经按照建议尝试了以下代码。我们还有什么可以改进的代码,可以使用lambdas编写更多代码。
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;
}
答案 0 :(得分:4)
您的问题不是lambda,而是代码组织。您有一个数据,即List<GlobalPricingRequest>
和一组验证规则。您需要执行所有操作以将这些评估规则应用于给定数据。
这种方法使您可以灵活地轻松添加或删除验证规则。然后分别测试或检查每个规则。
最佳解决方案是将每个验证分成单独的类。
首先,创建验证规则的管理器和界面:
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);
}
}
第二,在单独的类中实现每个验证规则(已添加到管理器中):
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代码:
GlobalPricingRequestValidationManager validationManager = new GlobalPricingRequestValidationManager();
List<GlobalPricingRequest> globalPricingRequests = Collections.emptyList();
validationManager.validate(globalPricingRequests);
答案 1 :(得分:2)
您可以使用 stream两次,并提高代码的可读性:
Try
答案 2 :(得分:2)
通过命令式方法,您正在执行的这种类型的验证会更好,但是我们可以在适当的地方使用lambda。
首先,我将使用signum
将重复条件隔离到本地谓词,正如@ThomasKläger在帖子中所建议的那样,因为在这种特定情况下比intValue
更合适。 / p>
Predicate<BigDecimal> criteria = b -> b != null && b.signum() < 0;
然后您的命令式方法将如下所示:
for (GlobalPricingRequest globalPricingRequest : globalPricingRequests) {
isValidOrElseThrowBadRequestException(globalPricingRequest.getFeePerTransact(), criteria);
for (EventTypePricingMapping eventTypePricingMapping : globalPricingRequest.getEventTypePricingList()) {
isValidOrElseThrowBadRequestException(eventTypePricingMapping.getFeePerRevenue(), criteria);
}
}
isValidOrElseThrow
的定义为:
public static void isValidOrElseThrowBadRequestException(BigDecimal data, Predicate<BigDecimal> criteria) throws Exception { // change the exception to the specific one you're using
if(criteria.test(data)) throw ExceptionHelper.badRequest("Fee Per Transaction can't be less than zero");
}
只需在此处进行一些隔离,就可以使代码更具可读性。
答案 3 :(得分:0)
@results = Item.search(
'Query',
where: {consumer_type: 'User', consumer_id: current_user.id},
load: false
)