首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用方法引用创建可重用的可选映射?

如何使用方法引用创建可重用的可选映射?
EN

Stack Overflow用户
提问于 2018-09-06 12:09:45
回答 2查看 483关注 0票数 4

当我试图在方法引用中使用可选特性时,我真的很困惑如何用可重用的代码来优化它。我认为我在尝试使用所有这些新特性(对我来说)的同时,我决定摆脱java-6风格,现在我认为我不能简单地思考,我觉得它变得太复杂了。我怎么能创造

代码语言:javascript
复制
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
}

与前面的代码一样,在使用可选代码编写此代码时也有问题:

代码语言:javascript
复制
if (request.getLockVehicle() != null) {
            if (request.getLockVehicle()) {
                expressionMapping.add(campaign.lockVehicle.isNotNull());
            } else {
                expressionMapping.add(campaign.lockVehicle.isNull());
            }
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-06 12:44:02

如何使用enum声明来自Request的所有字段,并将其作为代码的公共部分使用。我没有检查它,这只是为了显示我的方法:

代码语言:javascript
复制
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);
    }
}

您的客户端代码如下所示:

代码语言:javascript
复制
List<BooleanExpression> booleanExpressions = RequestField.getBooleanExpressions(request, campaign);

P.S.您的最后一段代码可能如下所示:

代码语言:javascript
复制
if (request.getLockVehicle() != null)
    expressionMapping.add(request.getLockVehicle() ? campaign.lockVehicle.isNotNull() : campaign.lockVehicle.isNull());
票数 2
EN

Stack Overflow用户

发布于 2018-09-06 12:29:55

使用Optional的目的是通知调用该方法/参数的人可能是null

在代码的第一部分中,您没有从中获得任何好处,您只是在重写一些围绕Optional逻辑封装它的代码,但是,正如您所说,没有任何“可重用”的目的。

一种有用的方法是将其用作方法的返回值:例如,如果您知道您的title可能为null,则可以重构您的getter如下

代码语言:javascript
复制
public Optional<String> getTitle(){
    return Optional.ofNullable(this.title); //I'm guessing the 'title' variable here
}

这将对您有所帮助:每次调用getTitle()时,您都会知道这可能是null,因为您正在获取一个Optional<String>而不是一个String

这样你就可以:

代码语言:javascript
复制
request.getTitle().ifPresent(title-> title.doSomething())
// you can also add something like .orElse("anotherStringValue")

第二个示例可以重新处理为第一个示例,将getLockVehicle()返回为Optional<Boolean>,即使我建议在这里使用类中的默认值设置它,可能是false. Optional<Boolean>非常没有意义

希望这能让你头脑清醒

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52203808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档