虽然我试图将Optional功能与方法引用一起使用,但确实使我困惑如何使用可重用的代码对其进行优化。我认为在尝试同时使用所有这些新功能(对我来说)时遇到了困难,我决定摆脱Java-6样式,现在我觉得我想不出来简单,我觉得它过于复杂了。如何创建
List<BooleanExpression> expressionMapping = new ArrayList<>();
if (request != null) { // request is input parameter, a DTO
Optional.ofNullable(request.getPlantId())
.map(campaign.plant.id::contains) // campaign is static created by Querydsl
.ifPresent(expressionMapping::add);
Optional.ofNullable(request.getTitle())
.map(campaign.title::containsIgnoreCase)
.ifPresent(expressionMapping::add);
Optional.ofNullable(request.getCampaignNumber())
.map(this::getLikeWrapped)
.map(campaign.campaignNumber::like)
.ifPresent(expressionMapping::add);
... 20 more Optional bunch of code like this
}
也难以像以前的代码那样使用Optional编写此代码:
if (request.getLockVehicle() != null) {
if (request.getLockVehicle()) {
expressionMapping.add(campaign.lockVehicle.isNotNull());
} else {
expressionMapping.add(campaign.lockVehicle.isNull());
}
}
答案 0 :(得分:2)
使用enum
声明Request
中的所有字段并将其用作代码的公共部分该怎么办?我没有检查它,这只是为了展示我的方法:
public enum RequestField {
PLANT_ID(Request::getPlantId, (val, campaign) -> campaign.plant.id::contains),
TITLE(Request::getTitle, (val, campaign) -> campaign.title::containsIgnoreCase),
CAMPAIGN_NUMBER(Request::getCampaignNumber, (val, campaign) -> campaign.campaignNumber::like),
// ... more fields here ...
;
private final Function<Request, Optional<Object>> get;
private final BiFunction<Object, Campaign, BooleanExpression> map;
RequestField(Function<Request, Object> get, BiFunction<Object, Campaign, BooleanExpression> map) {
this.get = get.andThen(Optional::ofNullable);
this.map = map;
}
public static List<BooleanExpression> getBooleanExpressions(Request request, Campaign campaign) {
if (request == null)
return Collections.emptyList();
List<BooleanExpression> res = new LinkedList<>();
for (RequestField field : values())
field.get.apply(request)
.map(r -> field.map.apply(r, campaign))
.ifPresent(res::add);
return res.isEmpty() ? Collections.emptyList() : Collections.unmodifiableList(res);
}
}
您的客户代码将如下所示:
List<BooleanExpression> booleanExpressions = RequestField.getBooleanExpressions(request, campaign);
PS 您的最后一个代码如下:
if (request.getLockVehicle() != null)
expressionMapping.add(request.getLockVehicle() ? campaign.lockVehicle.isNotNull() : campaign.lockVehicle.isNull());
答案 1 :(得分:0)
使用Optional
的目的是告知谁正在调用该方法/参数,使其可能为null
。
在代码的第一部分中,您没有从中获得任何好处,您只是在重写一些将代码Optional
包裹起来的代码,但正如您所说的那样,没有任何“可重用”的目的。
一种有用的方法是将其用作方法的返回值:例如,如果您知道title
可以为null,则可以像这样重构getter。
public Optional<String> getTitle(){
return Optional.ofNullable(this.title); //I'm guessing the 'title' variable here
}
这将为您提供帮助:每次调用getTitle()
时,您都会知道它可能为空,因为您获得的是Optional<String>
而不是String
。
这将带您进入:
request.getTitle().ifPresent(title-> title.doSomething())
// you can also add something like .orElse("anotherStringValue")
第二个示例可以改写为第一个示例,使getLockVehicle()
返回为Optional<Boolean>
,即使我建议在此处将类中的默认值设置为{{1 }} ... false
真是愚蠢
希望这有助于清理思路