是否可以在Java8流中重写此类代码?

时间:2017-08-09 16:04:54

标签: java-8 java-stream

我试图让它适应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;
}

但我遇到了检查流中的集合是否为空的问题。 &#34; streammest&#34;我得到的东西看起来像这样:

@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;
}

但我仍然不喜欢它。

2 个答案:

答案 0 :(得分: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 :(得分:0)

无论@Joe C的评论如何,我不确定将此OP移至Code Review是否更好。但是我从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. 忘记流API,它看起来很酷,但不是那么酷。使用/不使用Stream API编写简洁的代码真的很酷。
  2. 虽然我喜欢Lambdas和Stream API。但是,比较for-loop / if / while,如何使用Stream API编写简洁代码对我来说更具挑战性。最好一次又一次地浏览Stream API,并在开始在实际产品中使用流API之前做更多的练习。
  3. 始终更喜欢StreamEx。有时用原生Stream API编写代码真的很无聊。 StreamEx为完成任务提供了许多简便的方法。
  4. 忘记流