这段代码能否使用Java8流重写?

3

我试图将其适应于Java 8流:

public boolean isProcessionRestricted(CommonMessage message) {
    if (message.getClass() == BonusMessage.class) {
        log.debug("Staring validating BonusMessage: '{}'", message);
        BonusMessage bonusMessage = (BonusMessage) message;
        Optional<BonusTriggerConfig> config = bonusTriggerConfigRepository.getCached();
        if (config.isPresent()) {
            BonusTriggerConfig bonusTriggerConfig = config.get();
            List<BonusRewardConfig> rewardConfigs = bonusTriggerConfig.getRewardConfigs();
            if (!rewardConfigs.isEmpty()) {
                return rewardConfigs.stream()
                        .map(BonusRewardConfig::getBonusTypeId)
                        .noneMatch(bonusTypeId -> bonusTypeId == bonusMessage.getBonusTypeId());
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    return false;
}

但是我在使用流时遇到了检查集合是否为空的问题。我得到的“streammest”看起来像这样:

@Override
public boolean isProcessionRestricted(CommonMessage message) {
    if (message.getClass() == BonusMessage.class) {
        log.debug("Staring validating BonusMessage: '{}'", message);
        BonusMessage bonusMessage = (BonusMessage) message;
        return bonusTriggerConfigRepository.getCached()
                .map(bonusTriggerConfig -> {
                    List<BonusRewardConfig> rewardConfigs = bonusTriggerConfig.getRewardConfigs();
                    return !rewardConfigs.isEmpty() && rewardConfigs.stream()
                            .map(BonusRewardConfig::getBonusTypeId)
                            .noneMatch(bonusTypeId -> bonusTypeId == bonusMessage.getBonusTypeId());
                }).orElse(false);
    }
    return false;
}

但我仍然不喜欢它。

4
我不完全确定你在问什么。如果你在问是否可能,那么你已经清楚地表明了答案是肯定的。如果你想知道如何改进它,最好去Code Review - Joe C
1
是“noneMatch”还是“anyMatch”?!rewardConfigs.isEmpty()&& rewardConfigs.stream()... noneMatch(...)对我来说没有意义。 - 123-xyz
1
@123-xyz :),我也尝试过noneMatchanyMatch的行为是不同的。你可以看到我的编辑答案,我在写下anyMatch解决方案后立即将其删除。如果集合为空,OP只想简单地返回false - holi-java
2个回答

4
您可以使用Optional#filter来过滤空集合,例如:
return bonusTriggerConfigRepository.getCached()
        .map(bonusTriggerConfig -> bonusTriggerConfig.getRewardConfigs())
        // v--- filter the empty configs out
        .filter(rewardConfigs-> !rewardConfigs.isEmpty())
        .map(rewardConfigs -> rewardConfigs.stream()
            .map(BonusRewardConfig::getBonusTypeId)
            .noneMatch(bonusTypeId -> bonusTypeId == bonusMessage.getBonusTypeId())
        )
        .orElse(false);

1
这个答案表明,如果你知道如何编写代码,即使不使用第三方库,也可以完成它。 - Abhijit Sarkar

0

不管@Joe C的评论,我不确定将此OP移动到代码审查是否更好。但是我从OP中学到了如何使用Java 8 Stream API编写简洁代码的东西。首先,这是我第一次尝试使用StreamEx(我没有尝试使用本机流API,因为对我来说太无聊了...)

public boolean isProcessionRestricted(CommonMessage message) {
    return StreamEx.of(message)
        .select(BonusMessage.class)
        .peek(m -> log.debug("Staring validating BonusMessage: '{}'", m))
        .anyMatch(m -> bonusTriggerConfigRepository.getCached()
                .map(btc -> StreamEx.of(btc.getRewardConfigs())
                        .noneMatch(brc -> brc.getBonusTypeId() == m.getBonusTypeId())).orElse(false));
}

(如果有编译错误,请帮忙更新我的答案)。 但是逻辑对我来说看起来太复杂了。以下是我作为程序员可能会编写的代码:
public boolean isProcessionRestricted(CommonMessage message) {
    if (!(message insanceof BonusMessage && bonusTriggerConfigRepository.getCached().isPresent())) {
        return false;
    }

    log.debug("Staring validating BonusMessage: '{}'", message);     
    int restrictedBonusTypeId = ((BonusMessage) message).getBonusTypeId();
    List<BonusRewardConfig> rewardConfigs = bonusTriggerConfigRepository.getCached().get().getRewardConfigs();
    return rewardConfigs.size() > 0 && rewardConfigs.stream()
            .noneMatch(brc -> brc.getBonusTypeId() == restrictedBonusTypeId);
}

我的建议和学习心得:

  1. 忘记Stream API吧,它看起来很酷,但并不是那么酷。使用/不使用Stream API编写简洁的代码才是真正酷炫的。
  2. 虽然我喜欢Lambda和Stream API,但是如何使用Stream API编写简洁的代码对我来说更具挑战性,相比于for循环/if/while语句。在实际产品中使用Stream API之前,最好反复学习Stream API并进行更多的练习。
  3. 始终优先选择StreamEx。有时使用原生的Stream API编写代码真的很无聊。StreamEx提供了许多更短、更方便的方法来完成您的任务。

忘记Stream吧。


听起来不错。会尝试实现。 - SoulCub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接