2017-08-09 10 views
3

は、私は、Java 8のストリームに適合するようにしようとしていた。Java8ストリームでこのようなコードを書き直すことはできますか?

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

が、私はコレクションはストリーム内の空であるかどうかをチェックして、問題に直面しました。私が得意な "ストリームメスト"は、次のようになります。

@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](https://codereview.stackexchange.com/)に行く方が良いでしょう。 –

+1

は 'noneMatch'または 'anyMatch'ですか? !rewardConfigs.isEmpty()&& rewardConfigs.stream()... noneMatch(...)はシーンを私に作っていません –

+1

@ 123-xyz :) 'noneMatch'と' anyMatch'の動作は違っていますまた試みた。あなたは私の編集された答えを見ることができます、私はそれを書いた直後に 'anyMatch'ソリューションを削除しました。 OPはコレクションが空の場合にだけ 'false'を返すだけです。 –

答えて

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を移動する方が良いでしょうかはわかりません。しかし、私は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. 私はLambdaとStream APIが好きですが。しかし、Stream APIを使用して簡潔なコードを書く方法は、for-loop/if/whileを比較するとはるかに難しい課題です。実際の製品でストリームAPIを使用する前に、Stream APIを何度も繰り返し、より多くの方法を実行することをお勧めします。
  3. 常に好ましいのはStreamExです。時には、ネイティブストリームAPIを使ってコードを書くのは本当に退屈です。 StreamExは、あなたのタスクを達成するための多くの短くて便利な方法を提供します。

私はあなたが求めているものを全くわからないんだけどストリーム

+0

音は悪くありません。実装しようとします。 – SoulCub

関連する問題