2016-07-19 17 views
3

私はStream<@Nullable Object>を持っている場合、私はそのようなヌル要素をフィルタリングすることができます。フィルターストリームからNULL値可能な値と更新NULL可能プロパティ

Stream<@Nullable Object> s = str.filter(Objects::nonNull); 

これは、しかし、NULL可能なオブジェクトのストリームを返します。 NonNull要素のストリームを返すエレガントな方法はありますか?この場所では、要素がnullになることはできません。

芋、これは私が作ってみたものですが、それはあまりにも長いです:

Stream<@NonNull Object> s = str.map(Optional::ofNullable).filter(Optional::isPresent).map(Optional::get) 

(これはオプションは::常にNULL以外の値を返します得ることを意味する)

+1

'str.filter(Objects :: nonNull).map(Objects :: requireNonNull)' ... – Holger

答えて

2

まあ、すべてのOptionalまたはObjectsに基づくソリューションは、明示的な注釈を持たないため、チェッカーがメソッドのセマンティクスを認識していると想定しています。

filterはタイプを決して変更しないので、フィルタ機能のセマンティクスを理解していても、これをStream<@Nullable X>Stream<@NonNull X>のトランジションとしてモデル化するチェッカーからの深いサポートが必要です。

簡単な方法は、それが要素の型変更することができますようmapを使用することです。ここでは

Stream<@NonNull Object> s = str.filter(Objects::nonNull).map(Objects::requireNonNull); 

を、フィルタ操作にはnull要素が存在しないことを保証しますが、正式な要素の型を変更しません。対照的に、map操作では正式タイプの変更が可能であり、関数Objects::requireNonNullは、これらのJRE提供メソッドに注釈がないと監査ツールが認識していると仮定して、null入力を非NULL出力に変換します。

requireNonNullnull値の例外をスローするので、filtermapの組み合わせのみがnull値を除去し、正式な要素タイプを変更する目的の動作を可能にします。任意の合理的で正しいとして認識されるべき

監査ツールは、JREのメソッドの意味を理解していない場合は、注釈で、その後、同等の方法を自分で作成する必要があります、

class MyObjUtil { 
    public static <T> @NonNull T requireNonNull(@Nullable T obj) { 
     if(obj==null) throw new NullPointerException(); 
     return obj; 
    } 
} 

チェッカー、および

Stream<@NonNull Object> s = str.filter(Objects::nonNull).map(MyObjUtil::requireNonNull); 

としてそれを使用するあなたのOptionalベースのアプローチは、Java 9に簡素化することができます。

Stream<@NonNull Object> s = str.flatMap(o -> Optional.ofNullable(o).stream()); 

さらに簡略化することができた。

Stream<@NonNull Object> s = str.flatMap(o -> Stream.ofNullable(o)); 

もちろん、これは再び、これらの方法を理解するツールが必要です。それとも再実装ロジック:

class MyStreamUtil { 
    public static <T> Stream<@NonNull T> ofNullable(@Nullable T obj) { 
     return obj==null? Stream.empty(): Stream.of(obj); 
    } 
} 
Stream<@NonNull Object> s = str.flatMap(o -> MyStreamUtil.ofNullable(o)); 

その後、同様のJava 8の下で動作します。

+0

私はそこに良い答えがあるとは思わないので、私はあなたの答えを受け入れるでしょう。ありがとうございました! – looper

関連する問題