2015-12-22 5 views
7

私はJava8が初めてです。リストとフィルタを実装しました。私は自分のコードでヌルチェックをしました。同じコードスニペットでリストが空でないかどうかを確認する方法については、私は助けていただきたいと思います。リストが空でない場合、コードはアサーションを続行する必要があります。Java 8でリストが空であるかどうかを調べる

list.stream().filter(listElement -> listElement != null). 
    forEach((listElement) -> Assert.assertEquals(
     ValueType.CANDY, 
     listElement.getCandyType())); 

答えて

12

あなたは古くなった質問をしています。ストリームはソースのすべての要素を処理するため、要素がない場合は何も行われません。したがって、リストが空であるかどうかを確認する必要はありません。

list.stream().filter(Objects::nonNull) 
    .map(listElement -> listElement.getCandyType()) 
    .forEach(candyType -> Assert.assertEquals(ValueType.CANDY, candyType)); 

または

Assert.assertTrue(list.stream().filter(Objects::nonNull) 
         .map(listElement -> listElement.getCandyType()) 
         .allMatch(Predicate.isEqual(ValueType.CANDY)); 

allMatch

は、このチェックのために必要な規則に従います。

それでも、あなたはあなたのコードを簡素化することができます。要素がない場合、矛盾する要素はないので、はすべてと一致します。 listElement -> listElement.getCandyType()は、ClassName::getCandyTypeという形式のメソッド参照で置き換えることもできます。私は正しいクラス名を知らないのでここではそれをしなかった。

両方のバリエーションの間にパフォーマンスの違いはありません。 allMatchは最初の不一致要素に遭遇した直後に戻り、assertEqualsは最初に一致しない要素を投げます。後者の場合、スタックトレースはストリームAPI実装の成果物を表示しません。

ユニットテストではなく、プロダクションコードのチェックを行い、Java言語assertのように、これらのチェックをオフにすることができます。このフォームとして

assert list.stream().filter(Objects::nonNull) 
      .map(listElement -> listElement.getCandyType()) 
      .allMatch(Predicate.isEqual(ValueType.CANDY)); 

forEach作用をassertステートメントを有するアサーションは、第一の変形一方、オフされるオーバーヘッドがないことの保証は依然としてすべての要素を反復処理の中間ステップを実行せてもよいですパイプライン。

+0

あなたのアプローチの欠点は、失敗した場合、元のコードは、 "CANDYは期待されましたが:SHMANDY"のような実際の一致していない値を表示し、コードはアサーションが失敗したと言うだけです。 –

+0

@ Tagir Valeev:私の最初の変種はまだそれを行います。その情報が本当に役立つかどうかは議論の余地がありますが。たぶん索引が役立つかもしれません、多分*他の*一致しない項目、いくつかがある場合...通常、誤った状態につながった歴史はあなたが必要とするものですが、それは何か、どちらの変種も実現できません。 – Holger

+0

ありがとうございます。私はあなたの答えを選択しました。これは非常に明確で、私のコードも改善されました。 –

4

isEmpty方法

if (list.isEmpty()) { ... } 

はここドキュメントですチェックアウト:リストが空であることをアサートhttps://docs.oracle.com/javase/7/docs/api/java/util/List.html#isEmpty()

+0

ありがとうございましたが、私はそれがJava8の流れの中でチェックすることができる方法の構文を知りたいと思いました –

+4

リストが空の場合、ループする要素がないため、アサートは発生しません – Buddy

1

は、リストの任意の特定の要素は、いくつかのフォームを持っていることを主張するとは別のものです(すなわちgetCandyType() == ValueType.CANDY)。 2つのアイデアを結びつけようとすることは、正しい方法ではありません。あなたがする必要がどのような

assertThat(list.isEmpty(), not(equalTo(Boolean.FALSE))) 

...または同様の何かをしている、forEachの前または後に、第二のアサーションを追加することです。

空リストの主な点の1つは、要素を含むリストと同じ方法で処理できることです。このため、Optional classNull patternのようなものが存在します。あなたが実際にリストが空であることに本当に気を付けるなら、あなたは本当にでなければなりません。は別個のアサーションにしてください。

+0

これらのユーティリティメソッドが名前の示す通りに動作する場合、 'not(equalTo(Boolean.FALSE)) '本当のことを言ってかなり難解な方法です... – Holger

+0

@Holger、私は彼らもエラーメッセージを自動的にフォーマットすることができると思います("それはF ALSE ")。このような冗長はここでは絶対に不要です。 –

+1

@Holgerあなたが正しいとすれば、最も良いアサーションはおそらくhamcrestの 'IsEmptyCollection.empty()' matcher - 'assertThat(list、not(empty()))'を使うでしょう。 – sisyphus

6

選ばれた答えは、newly introduced to Java8 Optional classOptional.ofNullableでヌルケースを処理するためだけの小さな提案素晴らしいです:

Optional.ofNullable(list) 
      .orElseGet(Collections::emptyList) 
      .stream().filter(Objects::nonNull) 
      .map(listElement -> listElement.getCandyType()) 
      .forEach(candyType -> Assert.assertEquals(ValueType.CANDY, candyType));); 
関連する問題