2017-02-03 6 views
0

私は基本的に同じような何かをしたいと思います:これは一例です破棄しないフィルタのようなラムダ演算はありますか?

assertEquals(Arrays.asList(1,2,3).stream() 
            .noDiscardingFilter(x -> x!=1) 
            .map(x -> x*10) 
            .collect(Collectors.toList()), 
       Arrays.asList(1,20,30) 
      ) 

、私はその特定の問題を解決する方法についての答えを得る必要はありません、それは空想何を示すためにちょうど例です私は後に来ているもの。

+3

map()中間演算でそれをやってみませんか? –

+0

そのような操作やトリックがあれば質問してください。 – Whimusical

+3

*問題を解決する方法についての回答を得る必要はありません。私が知っていることが嬉しいものを見せてくれるだけの実用的な方法です。あなたは*ファンシー*が意味するものを定義/定量化できますか? – CKing

答えて

8

すべての中間ステップは、ストリームパイプライン全体に影響します。 noDiscardingFilterのステップは、collectの操作ではなく、後でチェーン化されたものに影響します。あなたが条件付きの機能を持つようにしたい場合は、そのように実装するより明確になります:

public static <T> Function<T,T> conditional(
           Predicate<? super T> p, Function<T, ? extends T> f) { 
    return obj -> p.test(obj)? f.apply(obj): obj; 
} 

これは

assertEquals(Stream.of(1, 2, 3) 
     .map(conditional(x -> x!=1, x -> x*10)) 
     .collect(Collectors.toList()), 
    Arrays.asList(1, 20, 30) 
); 

または

Stream.of(1, 5, null, 3, null, 4) 
     .map(conditional(Objects::isNull, x -> 0)) // replacing null with default value 
     .forEach(System.out::println); 

または

として使用することができます
Stream.of(1, 5, null, 3, null, 4) 
     .map(conditional(Objects::nonNull, x -> x*10)) // null-safe calculation 
     .forEach(System.out::println); 

これらの使用例ではどのように注意してくださいconditionalに渡された述語および関数が、連鎖ストリーム操作とは異なる同じスコープに属していることがすぐに分かります。

3

フィルタに一致するエントリのみを変更し、残りは保持する場合は、

assertEquals(Arrays.asList(-1, 1, 20, 30), 
      Stream.of(-1, 1, 2, 3) 
        .map(i -> i <= 1 ? i /* retain */ : 10 * i /* transform */) 
        .collect(Collectors.toList())); 
+1

の後のラムダ操作の種類を示す単純化です。それがアイデアです。それは私の元来の命題でしたが、ロジックがかなり複雑なので、私はそのようなフィルタリングのための操作があるかどうかをよく聞きました – Whimusical

関連する問題