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