Lambda in Stream.map/filter not called

后端 未结 4 1034
执笔经年
执笔经年 2021-01-18 04:56

I\'m trying to find separate the duplicates and non-duplicates in a List by adding them to a Set and List while using Stream.fil

4条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-18 05:36

    Both Stream#filter and Stream#map are intermediate operations, which means that they are evaluated lazily. According to the documentation:

    Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.

    In any case, you should be using the appropriate methods to avoid errors like this; forEach should be used instead of map here as Stream#map is used to convert the stream to the result of calling the mapping function on each element, while Stream#forEach is used to iterate over it.

    Demo: https://ideone.com/ZQhLJC

    strings
      .stream()
      .filter(x -> !distinct.add(x))
      .forEach(extras::add);
    

    Another possible workaround is to perform a terminal operation like .collect to force the filter and map to be applied.

    strings
      .stream()
      .filter(x -> !distinct.add(x))
      .map(extra -> extras.add(extra)).collect(Collectors.toList());
    

    If you are going to use .collect, you might as well use the collected list as extras to avoid wasting time and space.

    List extras = strings
      .stream()
      .filter(x -> !distinct.add(x)).collect(Collectors.toList());
    

提交回复
热议问题