JDK8中谨慎使用peek去取代map/forEach

peek(窥视)和map(转换)顾名思义:一个是看一眼参数,一个是转化参数。

1. 区别

peek和map的区别:均作为流处理的中间操作,但是两个的内部处理函数不同,一个为“消费元素”,另一个为“映射元素”。

Stream<T> peek(Consumer<? super T> action);

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

peek和foreach的区别:peek作为中间操作,而foreach作为终端操作;

Stream<T> peek(Consumer<? super T> action);

void forEach(Consumer<? super T> action);

2. peek的使用场景

在Java doc中这样描述:“元素存在的目的为了进行debug”

API Note:
This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline:

那么能否使用peek做其他操作呢?

例如:对内部的元素进行修改。

public class TestPeek {

    public static void main(String[] args) {
        List<User> lists = new ArrayList<>();
        lists.add(new User("a"));
        lists.add(new User("b"));
        lists.add(new User("c"));

        List<User> collect = lists.stream().peek(p -> {
            p.setName("1"+p.getName());
        }).collect(Collectors.toList());
    }


    @Data
    public static class User {
        private String name;

        public User(String name) {
            this.name = name;
        }
    }
}
sonarlint中的描述谨慎使用peek().png

根据其 JavaDocs,中间 Stream 操作 java.util.Stream.peek() “存在主要是为了支持调试”目的。
与其他中间 Stream 操作的一个主要区别是 Stream 实现可以自由地跳过对 peek() 的调用以进行优化。 这可能导致 peek() 仅针对 Stream 中的某些元素或没有元素被意外调用。
因此,在没有仔细考虑的情况下依赖 peek() 会导致代码容易出错。
此规则为 peek() 的每次使用提出了一个问题,以确保团队对其进行挑战和验证以用于生产调试/日志记录目的。

3. 完全可以使用map或者forEach进行取代

上面的场景,使用forEach进行取代:

lists.forEach(p->p.setName("1"+p.getName()));

所以,还是谨慎使用peek()函数来进行操作吧!!

推荐阅读

sonar使用——sonarlint

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容