Any filter-like lambda operation which does not discard?

前端 未结 2 1388
南方客
南方客 2020-12-10 10:12

I basically would like to do something like:

  assertEquals(Arrays.asList(1,2,3).stream()
                                   .noDiscardingFilter(x -> x!=1         


        
相关标签:
2条回答
  • 2020-12-10 10:37

    Any intermediate step affects the entire stream pipeline. There is no recognizable rule behind your wish that the noDiscardingFilter step affects what the subsequently chained map will do, but not the collect operation. If you want to have a conditional function, it would be much clearer to implement it as such:

    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;
    }
    

    This can be used as

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

    or

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

    or

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

    Note how in these use cases, it is immediately recognizable that the predicate and function passed to conditional belong to the same scope, which is different from the chained stream operations.

    0 讨论(0)
  • 2020-12-10 10:38

    If you want to only change the entries which match the filter but retain the rest.

    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()));
    
    0 讨论(0)
提交回复
热议问题