2017-01-25 6 views
2

私はこの質問をフレームに正確にどのように確認されませんでしたので、私と一緒にクマ...Javaストリーム> "orElseGet"を親ストリームにインライン化することは可能ですか?

1)は、オプションの要素のStreamをインスタンス化するためのより良い(別名より「正しい」)の方法は、他の、ありますnullを追加し、続いてnull '

Stream.of(... , 
     person.likesRed() ? Color.RED : null) 
     .filter(Objects::nonNull) 
... 

2)第二に、親Stream/mapに "インライン" への道以下orElseGet機能はありますか?クリーナー式が

Stream.concat(Stream.of(Color.BLUE, Color.GREEN), 
       person.likesRed()? Stream.of(Color.RED): Stream.empty()) 

これはあなたの元の式よりも簡単ではありませんが、それは作成されないだろう

import static java.util.Optional.ofNullable; 

public Response getFavouriteColours(final String personId) { 
    Person person = personService.findById(personId); 

    Supplier<List<String>> fallbackToDefaultFavouriteColours =() -> 
      Stream.of(
        Color.BLUE, 
        Color.GREEN, 
        person.likesRed() ? Color.RED : null) 
        .filter(Objects::nonNull) 
        .map(Color::getName) 
        .collect(Collectors.toList()); 

    return ofNullable(person) 
      .map(p -> ofNullable(p.getFavouriteColours()).orElseGet(fallbackToDefaultFavouriteColours)) 
      .map(Response::createSuccess) 
      .orElse(Response::createNotFound); 

} 
+4

ナー、これはそれが得られるほど良く見えます。 –

+0

私はそれをもう一度。私はあなたの現在のコードの改善の範囲を見ることができません。これは実際どのようにできるかです。しかし、私は 'null'の代わりにDEFAULT/NONEという色のenum定数を使うかもしれませんが、それは意見の問題だと言いました。 –

+1

'。orElseGet(Response :: createNotFound)'を意味しましたか? – Holger

答えて

1

.map(p -> ofNullable(p.getFavouriteColours()).orElseGet(fallbackToDefaultFavouriteColours)) 

フル(不自然)の例それを後でフィルタリングするために何かを挿入するという悪い気持ち、または後で再構成されなければならない既に知られている情報を破棄するという、より抽象的なものです。

技術的な違いがあります。上記の式は、aが特定の操作を最適化するために使用できる既知のサイズを持つStreamを作成します。対照的に、filterを使用するバリアントは、フィルタリングする前の要素の数になりますが、既知の正確なサイズではない推定サイズしかありません。

周囲のコードが大幅にOptionalを使いすぎないことによって単純化することができます:それはそうだけれども

public Response getFavouriteColours(final String personId) { 
    Person person = personService.findById(personId); 
    if(person==null) return Response.createNotFound(); 

    List<String> favouriteColours = person.getFavouriteColours(); 
    if(favouriteColours==null) { 
     favouriteColours=new ArrayList<>(); 
     Collections.addAll(favouriteColours, Color.BLUE.getName(), Color.GREEN.getName()); 
     if(person.likesRed()) favouriteColours.add(Color.RED.getName()); 
    } 
    return Response.createSuccess(favouriteColours); 
} 

public Response getFavouriteColours(final String personId) { 
    Person person = personService.findById(personId); 
    if(person == null) return Response.createNotFound(); 

    List<String> favouriteColours = person.getFavouriteColours(); 
    if(favouriteColours == null) 
     favouriteColours = Stream.concat(
       Stream.of(Color.BLUE, Color.GREEN), 
       person.likesRed()? Stream.of(Color.RED): Stream.empty()) 
      .map(Color::getName) 
      .collect(Collectors.toList()); 

    return Response.createSuccess(favouriteColours); 
} 

でもストリーム動作自体は、ここで、従来不可欠コードよりも簡単ではありませんより複雑な例ではStream APIの使用による利益が得られますが、Optionalの使用は複雑な操作ではうまくいかない可能性があります。チェーン内のすべての不在値またはフィルターの不一致がチェーンの最後で同じ方法で処理されると想定される場合、オプションのチェーンを使用すると、コードを単純化できます。しかし、あなたの例(そしてほとんどの実際のシナリオ)のように、すべての不在価値が別の扱いを受けるべきか、個別に報告されなければならない場合、Optionalals、特に入れ子になったOptionalsを使用してコードを改善することはありません。

関連する問題