任何类似过滤器的lambda操作都不会丢弃?

Whi*_*cal 0 java lambda java-8 java-stream

我基本上想做的事情如下:

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

这是一个例子,我不需要得到如何解决这个特定问题的答案,这只是一个例子来展示我正在追求的奇特东西.

Hol*_*ger 8

任何中间步骤都会影响整个流管道.你的愿望背后没有可识别的规则,即noDiscardingFilter步骤会影响后续链接的map内容,而不会影响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;
}
Run Code Online (Sandbox Code Playgroud)

这可以用作

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

要么

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

要么

Stream.of(1, 5, null, 3, null, 4)
      .map(conditional(Objects::nonNull, x -> x*10)) // null-safe calculation
      .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

请注意,在这些用例中,可以立即识别传递的谓词和函数conditional属于同一范围,这与链式流操作不同.