java stream流之peek和map到底有没有区别?

前言

今天在写代码的时候,看到了一篇帖子,讲的是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类型其实也是一个引用类型,并不是基本数据类型,为什么他不是引用传递啊?欢迎大家来讨论!

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值