2017-02-23 3 views
4

リポジトリからデータを返すN個のリストがあります。私はこれらの3つのリストの最初の空でないものを返したい(それぞれが別のSQLを実行してデータを取得する)。最初の空ではないリストをJava 8で遅延的に返します。

私はこれをゆっくりやりたいので、受け入れ可能な結果が見つかった場合はデータベース上でSQLを実行する必要はありません。私のコードは(変更された)

@Override 
public List<Something> dataService(Data data) { 

return firstNonEmptyList(repository.getDataWayOne(data.getParameter()), 
         repository.getDataWayTwo(data.getParameter()), 
         repository.getDataWayThree(data.getParameter().getAcessoryParameter()) 
         Collections.singletonList(repository.getDefaultData(data.getParameter())); 

} 

@SafeVarargs 
private final List<Something> firstNonEmptyList(List<Something>... lists) { 
for (List<Something> list : lists) { 
    if (!list.isEmpty()) { 
    return list; 
    } 
} 

return null; 

} 

これは動作しますが、怠惰ではありません。何か案は?

+0

私が間違っている場合は私を修正しますが、lambdaの中でリストの呼び出しをラップすると怠け者になると思います。 'firstNonEmptyList'では、あなたが望むもの(すなわち、空でないリストを返すもの)を見つけるまで、各ラムダを評価します。ラムダと呼ばれていないものは決してクエリを実行しません。とにかく、shmoselによって提供されるソリューションは、私が記述したやり方はよりエレガントです。 – Gabriel

答えて

9

あなたはサプライヤーの流れを作り、あなたは結果を見つけるまで、出会いのためにそれらを評価することができます

return Stream.<Supplier<List<Something>>>of(
      () -> repository.getDataWayOne(data.getParameter()), 
      () -> repository.getDataWayTwo(data.getParameter()), 
      () -> repository.getDataWayThree(data.getParameter().getAcessoryParameter()), 
      () -> Collections.singletonList(repository.getDefaultData(data.getParameter())) 
     ) 
     .map(Supplier::get) 
     .filter(l -> !l.isEmpty()) 
     .findFirst() 
     .orElse(null); 

各サプライヤーがmap()が実行されるまで、実際にそれをしようとせずに、結果セットにアクセスする方法を定義します。 filter()map()statelessの操作であるため、各サプライヤが呼び出され、その結果が検証されてから次の試行が試行されます。空でない結果が見つかると、findFirst()short-circuitingなので、ストリームはすぐに終了します。

+1

これはいくつかの人々がめまいを起こさせるJava 8の答えの1つです。あなたはそれを一歩一歩説明することができ、それはなぜ怠惰な読み込みですか? –

+0

これは優れた答えです。最もJava8-icの方法です。私のフランス語を赦してください! – khachik

+0

@GrzegorzGórkiewicz私は試しました。うまくいけば、今は少しはっきりしています。 – shmosel

3

ストリームがお茶のお茶でない場合でも、元のコードにわずかな変更を加えるだけで、ラムダを使用して目的を達成できます。

+0

偶然、私の最後のコメントはまさにあなたがここでやったことです。それはうまくいきますが、問題はそれが怠惰についての意図を隠していることです。この場合、より機能的なスタイルが歓迎されます。 – Gabriel

+0

私は実際には正反対だと思っています。「firstNonEmptyList」の短絡動作はかなり見やすいものです。ストリームでは、誰もがストリームAPIに精通している場合にのみ明らかです。このメソッドのJavadocを使用すると、それをさらに明確にすることができます。 –

+0

これはまた、レイジーローディングを含む私のすべてのテストに合格し、合格しました。私はそれを感謝します。私はそれが補助的な方法を排除するので、shmoselのものを使うつもりです。 –

関連する問題