前言

今天在写代码的时候,看到了一篇帖子,讲的是stream流的peek和map的区别,文中是这么个意思,如下,先看代码:
例(1)如下:

 public static void main(String[] args) {
        List<String> stringList = new ArrayList<>();
        stringList.add("a");
        stringList.add("b");
        stringList.add("c");
        List<String> collectMap = stringList.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(collectMap);

        List<String> collectPeek = stringList.stream()
                .peek(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(collectPeek);
    }

说明:定义了一个List集合,集合里面存的都是String类型,collectMap是map方式的集合,collectPeek是peek方式的集合。
输出结果:

[A, B, C]
[a, b, c]

代码层面做的操作是一样的,但是似乎打印出来的结果却不相同呢?于是得出了结论,map可以改变元素值,peek无法改变元素的值,答案真的是这样吗?
:--------------------------------------------------------------------------------------------------------:
我又新写了一个main方法进行测试
例(2)如下:

public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("张三",13));
        userList.add(new User("李四",14));
        userList.add(new User("王五",15));
        List<User> collectMap = userList.stream()
                .map(s -> {s.setAge(10);return s;})
                .collect(Collectors.toList());
        System.out.println(collectMap);

        List<User> collectUser = userList.stream()
                .peek(s -> s.setAge(11))
                .collect(Collectors.toList());
        System.out.println(collectUser);
    }

说明:定义了一个List集合,集合里面存的都是User对象,该对象有两个参数,姓名name、年龄age。第一个流将所有user的age变成10,第二个流将所有user的age变成11
输出结果如下:

[User{name='张三', age=10}, User{name='李四', age=10}, User{name='王五', age=10}]
[User{name='张三', age=11}, User{name='李四', age=11}, User{name='王五', age=11}]

可以看到结果确实变化成这样,和上面的例(1)所描述的结论完全违背啊!!!stream流不管是peek方法也好,map方法也好都是可以改变对象的值呀!
--------------------------------------------懵*********了-------------------------------------------------:
为什么会出现这种情况呢?

值传递和引用传递

哦!厚礼蟹!原来居然是例(1)里面的List存放的String类型,在peek的方法里String::toUpperCase,做的操作是值传递,而不是引用传递,导致传递到方法内部的值做改变之后,并不会写回到原对象里面去,但是在例(2)里面的user是被当作引用传递到方法内部,因此在做了setAge操作之后,原对象的值也就发生了变化

总结

其实peek和map的区别也就只有:
(1)peek传参是消费者类型,返回值是Stream流,map的传参是函数式接口,返回值也是一个Stream。

	<R> Stream<R> map(Function<? super T, ? extends R> var1);
    Stream<T> peek(Consumer<? super T> var1);

思考

最后,我们突然发现,java的类型里面String类型其实也是一个引用类型,并不是基本数据类型,为什么他不是引用传递啊?欢迎大家来讨论!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐