Stream转List的新API,真是干净又卫生啊!
前几天分享了 如何优雅的调试Java Stream操作。
然后有小伙伴对其中的一段代码有一些疑问:“为啥你的stream可以直接toList而不必collect?” 下面就给大家解读下这个内容。
疑问的代码片段如下:
public class StreamTest {
@Test
void test() {
List<String> list = List.of("blog.didispace.com", "spring4all.com", "openwrite.cn", "www.didispace.com");
List<String> result = list.stream()
.filter(e -> e.contains("didispace.com"))
.filter(e -> e.length() > 17)
.toList();
System.out.println(result);
}
}
小伙伴疑问的就是第10行:toList()
。实际上这个方法是Java 16才支持的一个方法,它可以直接将Stream
转化成List
。而因为目前很多小伙伴还在用Java 8,所以在介绍如何调试Stream的时候,直接用我这段代码可能会碰到这个问题。
如果您学习过程中如遇困难?可以加入我们超高质量的技术交流群,参与交流与讨论,更好的学习与进步!本文收录在了我正在连载的《Java新特性专栏》,该系列该用电子书的方式编写,如果想要沉浸式阅读学习的话,可以访问Web版本:https://www.didispace.com/java-features/
那么Java 8的用户怎么写呢?我看到也有网友直接给出了Java 8下的方法,就如下面这样:
List<String> result = list.stream()
.filter(e -> e.contains("didispace.com"))
.filter(e -> e.length() > 17)
.collect(Collectors.toList());
Stream.toList() 和 Collectors.toList()
就上面的代码逻辑来说,这样的替换完全是可以的,但是虽然最终都转成List了,他们之间是否还有区别呢?
这里单独拉出来说一下,这两个方法的结果其实是有区别的。
通过查看Stream.toList()
的源码:
default List<T> toList() {
return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())));
}
我们可以发现,它所创建的是一个unmodifiableList
不可变的List。而使用Stream.collect(Collectors.toList())
创建出来的则是一个普通的List,是可以做增删改操作的。
那么如果用Collectors
也要创建不可变的List要怎么写呢?其实也很简单,只需要调用Collectors.toUnmodifiableList()
就可以了。所以与本文开头等价代码替换可以这样写:
List<String> result = list.stream()
.filter(e -> e.contains("didispace.com"))
.filter(e -> e.length() > 17)
.collect(Collectors.toUnmodifiableList());
但要注意的是,这个方法Java 8里也没有,是Java 10才开始支持的。
好了,今天的分享就到这里,你学会了吗?